Merge "- netconf SSH bridge bundle - Implement bridge using socket - standard netconf...
[controller.git] / opendaylight / md-sal / sal-rest-connector / src / main / java / org / opendaylight / controller / sal / restconf / impl / RestconfImpl.xtend
1 package org.opendaylight.controller.sal.restconf.impl
2
3 import java.util.List
4 import javax.ws.rs.core.Response
5 import org.opendaylight.controller.md.sal.common.api.TransactionStatus
6 import org.opendaylight.controller.sal.rest.api.RestconfService
7 import org.opendaylight.yangtools.yang.data.api.CompositeNode
8 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
9 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
10
11 class RestconfImpl implements RestconfService {
12     
13     val static RestconfImpl INSTANCE = new RestconfImpl
14
15     @Property
16     BrokerFacade broker
17
18     @Property
19     extension ControllerContext controllerContext
20     
21     private new() {
22         if (INSTANCE !== null) {
23             throw new IllegalStateException("Already instantiated");
24         }
25     }
26     
27     static def getInstance() {
28         return INSTANCE
29     }
30
31     override readAllData() {
32 //        return broker.readOperationalData("".toInstanceIdentifier.getInstanceIdentifier);
33         throw new UnsupportedOperationException("Reading all data is currently not supported.")
34     }
35
36     override getModules() {
37         throw new UnsupportedOperationException("TODO: auto-generated method stub")
38     }
39
40     override getRoot() {
41         return null;
42     }
43
44     override readData(String identifier) {
45         val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
46         val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
47         return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
48     }
49
50     override createConfigurationData(String identifier, CompositeNode payload) {
51         val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
52         val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
53         val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
54         switch status.result {
55             case TransactionStatus.COMMITED: Response.status(Response.Status.OK).build
56             default: Response.status(Response.Status.INTERNAL_SERVER_ERROR).build
57         }
58     }
59
60     override updateConfigurationData(String identifier, CompositeNode payload) {
61         val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
62         val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
63         val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
64         switch status.result {
65             case TransactionStatus.COMMITED: Response.status(Response.Status.NO_CONTENT).build
66             default: Response.status(Response.Status.INTERNAL_SERVER_ERROR).build
67         }
68     }
69
70     override invokeRpc(String identifier, CompositeNode payload) {
71         val rpc = identifier.toQName;
72         val value = resolveNodeNamespaceBySchema(payload, controllerContext.getRpcInputSchema(rpc))
73         val rpcResult = broker.invokeRpc(rpc, value);
74         val schema = controllerContext.getRpcOutputSchema(rpc);
75         return new StructuredData(rpcResult.result, schema);
76     }
77     
78     override readConfigurationData(String identifier) {
79         val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
80         val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
81         return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
82     }
83     
84     override readOperationalData(String identifier) {
85         val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
86         val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
87         return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
88     }
89     
90     override updateConfigurationDataLegacy(String identifier, CompositeNode payload) {
91         updateConfigurationData(identifier,payload);
92     }
93     
94     override createConfigurationDataLegacy(String identifier, CompositeNode payload) {
95         createConfigurationData(identifier,payload);
96     }
97     
98     private def InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) {
99         val identifierWithSchemaNode = identifier.toInstanceIdentifier
100         if (identifierWithSchemaNode === null) {
101             throw new ResponseException(Response.Status.BAD_REQUEST, "URI has bad format");
102         }
103         return identifierWithSchemaNode
104     }
105     
106     private def CompositeNode resolveNodeNamespaceBySchema(CompositeNode node, DataSchemaNode schema) {
107         if (node instanceof CompositeNodeWrapper) {
108             addNamespaceToNodeFromSchemaRecursively(node as CompositeNodeWrapper, schema)
109             return (node as CompositeNodeWrapper).unwrap(null)
110         }
111         return node
112     }
113
114     private def void addNamespaceToNodeFromSchemaRecursively(NodeWrapper<?> nodeBuilder, DataSchemaNode schema) {
115         if (nodeBuilder.namespace === null) {
116             nodeBuilder.namespace = schema.QName.namespace
117         }
118         if (nodeBuilder instanceof CompositeNodeWrapper) {
119             val List<NodeWrapper<?>> children = (nodeBuilder as CompositeNodeWrapper).getValues
120             for (child : children) {
121                 addNamespaceToNodeFromSchemaRecursively(child,
122                     (schema as DataNodeContainer).childNodes.findFirst[n|n.QName.localName.equals(child.localName)])
123             }
124         }
125     }
126
127 }