1 package org.opendaylight.controller.sal.restconf.impl
4 import javax.ws.rs.core.Response
5 import org.opendaylight.controller.sal.rest.api.RestconfService
6 import org.opendaylight.yangtools.yang.data.api.CompositeNode
7 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
8 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
9 import org.opendaylight.controller.md.sal.common.api.TransactionStatus
10 import javax.ws.rs.WebApplicationException
12 class RestconfImpl implements RestconfService {
14 val static RestconfImpl INSTANCE = new RestconfImpl
20 extension ControllerContext controllerContext
23 if (INSTANCE !== null) {
24 throw new IllegalStateException("Already instantiated");
28 static def getInstance() {
32 override readAllData() {
33 // return broker.readOperationalData("".toInstanceIdentifier.getInstanceIdentifier);
34 throw new UnsupportedOperationException("Reading all data is currently not supported.")
37 override getModules() {
38 throw new UnsupportedOperationException("TODO: auto-generated method stub")
45 override readData(String identifier) {
46 val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
47 val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
48 return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
51 override createConfigurationData(String identifier, CompositeNode payload) {
52 val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
53 val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
54 val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
55 switch status.result {
56 case TransactionStatus.COMMITED: Response.status(Response.Status.OK).build
57 default: Response.status(Response.Status.INTERNAL_SERVER_ERROR).build
61 override updateConfigurationData(String identifier, CompositeNode payload) {
62 val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
63 val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
64 val status = broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
65 switch status.result {
66 case TransactionStatus.COMMITED: Response.status(Response.Status.NO_CONTENT).build
67 default: Response.status(Response.Status.INTERNAL_SERVER_ERROR).build
71 override invokeRpc(String identifier, CompositeNode payload) {
72 val rpc = identifier.toQName;
73 val value = resolveNodeNamespaceBySchema(payload, controllerContext.getRpcInputSchema(rpc))
74 val rpcResult = broker.invokeRpc(rpc, value);
75 val schema = controllerContext.getRpcOutputSchema(rpc);
76 return new StructuredData(rpcResult.result, schema);
79 override readConfigurationData(String identifier) {
80 val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
81 val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
82 return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
85 override readOperationalData(String identifier) {
86 val instanceIdentifierWithSchemaNode = identifier.resolveInstanceIdentifier
87 val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
88 return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
91 override updateConfigurationDataLegacy(String identifier, CompositeNode payload) {
92 updateConfigurationData(identifier,payload);
95 override createConfigurationDataLegacy(String identifier, CompositeNode payload) {
96 createConfigurationData(identifier,payload);
99 override createOperationalData(String identifier, CompositeNode payload) {
100 val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
101 val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
102 val status = broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
103 switch status.result {
104 case TransactionStatus.COMMITED: Response.status(Response.Status.OK).build
105 default: Response.status(Response.Status.INTERNAL_SERVER_ERROR).build
109 override updateOperationalData(String identifier, CompositeNode payload) {
110 val identifierWithSchemaNode = identifier.resolveInstanceIdentifier
111 val value = resolveNodeNamespaceBySchema(payload, identifierWithSchemaNode.schemaNode)
112 val status = broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,value).get();
113 switch status.result {
114 case TransactionStatus.COMMITED: Response.status(Response.Status.NO_CONTENT).build
115 default: Response.status(Response.Status.INTERNAL_SERVER_ERROR).build
119 private def InstanceIdWithSchemaNode resolveInstanceIdentifier(String identifier) {
120 val identifierWithSchemaNode = identifier.toInstanceIdentifier
121 if (identifierWithSchemaNode === null) {
122 throw new ResponseException(Response.Status.BAD_REQUEST, "URI has bad format");
124 return identifierWithSchemaNode
127 private def CompositeNode resolveNodeNamespaceBySchema(CompositeNode node, DataSchemaNode schema) {
128 if (node instanceof CompositeNodeWrapper) {
129 addNamespaceToNodeFromSchemaRecursively(node as CompositeNodeWrapper, schema)
130 return (node as CompositeNodeWrapper).unwrap(null)
135 private def void addNamespaceToNodeFromSchemaRecursively(NodeWrapper<?> nodeBuilder, DataSchemaNode schema) {
136 if (nodeBuilder.namespace === null) {
137 nodeBuilder.namespace = schema.QName.namespace
139 if (nodeBuilder instanceof CompositeNodeWrapper) {
140 val List<NodeWrapper<?>> children = (nodeBuilder as CompositeNodeWrapper).getValues
141 for (child : children) {
142 addNamespaceToNodeFromSchemaRecursively(child,
143 (schema as DataNodeContainer).childNodes.findFirst[n|n.QName.localName.equals(child.localName)])