X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-rest-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frestconf%2Fimpl%2FRestconfImpl.java;h=c8440c0a1692066660b0a6b2025abee6476c28a6;hb=refs%2Fchanges%2F66%2F8866%2F1;hp=5a16c04aedb1fb7ed3d44b77bd1595897215d73f;hpb=b2e6c299fad844633c8b40a2e180780f5774a4ae;p=controller.git diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java index 5a16c04aed..c8440c0a16 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.java @@ -15,7 +15,6 @@ import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; - import java.net.URI; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -26,14 +25,13 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.Future; - import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; - import org.apache.commons.lang3.StringUtils; import org.opendaylight.controller.md.sal.common.api.TransactionStatus; import org.opendaylight.controller.sal.core.api.mount.MountInstance; @@ -78,6 +76,21 @@ import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBu import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; public class RestconfImpl implements RestconfService { + private enum UriParameters { + PRETTY_PRINT( "prettyPrint"), + DEPTH( "depth"); + + private String uriParameterName; + UriParameters(String uriParameterName) { + this.uriParameterName = uriParameterName; + } + + @Override + public String toString() { + return uriParameterName; + } + } + private final static RestconfImpl INSTANCE = new RestconfImpl(); private static final int CHAR_NOT_FOUND = -1; @@ -110,7 +123,7 @@ public class RestconfImpl implements RestconfService { } @Override - public StructuredData getModules() { + public StructuredData getModules(final UriInfo uriInfo) { final Module restconfModule = this.getRestconfModule(); final List> modulesAsData = new ArrayList>(); @@ -127,11 +140,11 @@ public class RestconfImpl implements RestconfService { restconfModule, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE); QName qName = modulesSchemaNode.getQName(); final CompositeNode modulesNode = NodeFactory.createImmutableCompositeNode(qName, null, modulesAsData); - return new StructuredData(modulesNode, modulesSchemaNode, null); + return new StructuredData(modulesNode, modulesSchemaNode, null,parsePrettyPrintParameter( uriInfo )); } @Override - public StructuredData getAvailableStreams() { + public StructuredData getAvailableStreams(final UriInfo uriInfo) { Set availableStreams = Notificator.getStreamNames(); final List> streamsAsData = new ArrayList>(); @@ -146,11 +159,11 @@ public class RestconfImpl implements RestconfService { restconfModule, Draft02.RestConfModule.STREAMS_CONTAINER_SCHEMA_NODE); QName qName = streamsSchemaNode.getQName(); final CompositeNode streamsNode = NodeFactory.createImmutableCompositeNode(qName, null, streamsAsData); - return new StructuredData(streamsNode, streamsSchemaNode, null); + return new StructuredData(streamsNode, streamsSchemaNode, null,parsePrettyPrintParameter( uriInfo )); } @Override - public StructuredData getModules(final String identifier) { + public StructuredData getModules(final String identifier,final UriInfo uriInfo) { Set modules = null; MountInstance mountPoint = null; if (identifier.contains(ControllerContext.MOUNT)) { @@ -178,11 +191,11 @@ public class RestconfImpl implements RestconfService { restconfModule, Draft02.RestConfModule.MODULES_CONTAINER_SCHEMA_NODE); QName qName = modulesSchemaNode.getQName(); final CompositeNode modulesNode = NodeFactory.createImmutableCompositeNode(qName, null, modulesAsData); - return new StructuredData(modulesNode, modulesSchemaNode, mountPoint); + return new StructuredData(modulesNode, modulesSchemaNode, mountPoint,parsePrettyPrintParameter( uriInfo )); } @Override - public StructuredData getModule(final String identifier) { + public StructuredData getModule(final String identifier,final UriInfo uriInfo) { final QName moduleNameAndRevision = this.getModuleNameAndRevision(identifier); Module module = null; MountInstance mountPoint = null; @@ -207,17 +220,17 @@ public class RestconfImpl implements RestconfService { final DataSchemaNode moduleSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode( restconfModule, Draft02.RestConfModule.MODULE_LIST_SCHEMA_NODE); final CompositeNode moduleNode = this.toModuleCompositeNode(module, moduleSchemaNode); - return new StructuredData(moduleNode, moduleSchemaNode, mountPoint); + return new StructuredData(moduleNode, moduleSchemaNode, mountPoint,parsePrettyPrintParameter( uriInfo )); } @Override - public StructuredData getOperations() { + public StructuredData getOperations(final UriInfo uriInfo) { Set allModules = this.controllerContext.getAllModules(); - return this.operationsFromModulesToStructuredData(allModules, null); + return this.operationsFromModulesToStructuredData(allModules, null,parsePrettyPrintParameter(uriInfo)); } @Override - public StructuredData getOperations(final String identifier) { + public StructuredData getOperations(final String identifier,final UriInfo uriInfo) { Set modules = null; MountInstance mountPoint = null; if (identifier.contains(ControllerContext.MOUNT)) { @@ -232,11 +245,11 @@ public class RestconfImpl implements RestconfService { ControllerContext.MOUNT, ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE ); } - return this.operationsFromModulesToStructuredData(modules, mountPoint); + return this.operationsFromModulesToStructuredData(modules, mountPoint,parsePrettyPrintParameter(uriInfo)); } private StructuredData operationsFromModulesToStructuredData(final Set modules, - final MountInstance mountPoint) { + final MountInstance mountPoint,boolean prettyPrint) { final List> operationsAsData = new ArrayList>(); Module restconfModule = this.getRestconfModule(); final DataSchemaNode operationsSchemaNode = controllerContext.getRestconfModuleRestConfSchemaNode( @@ -269,7 +282,7 @@ public class RestconfImpl implements RestconfService { final CompositeNode operationsNode = NodeFactory.createImmutableCompositeNode(qName, null, operationsAsData); ContainerSchemaNode schemaNode = fakeOperationsSchemaNode.build(); - return new StructuredData(operationsNode, schemaNode, mountPoint); + return new StructuredData(operationsNode, schemaNode, mountPoint,prettyPrint); } private Module getRestconfModule() { @@ -389,18 +402,18 @@ public class RestconfImpl implements RestconfService { } @Override - public StructuredData invokeRpc(final String identifier, final CompositeNode payload) { + public StructuredData invokeRpc(final String identifier, final CompositeNode payload,final UriInfo uriInfo) { final RpcExecutor rpc = this.resolveIdentifierInInvokeRpc(identifier); QName rpcName = rpc.getRpcDefinition().getQName(); URI rpcNamespace = rpcName.getNamespace(); if (Objects.equal(rpcNamespace.toString(), SAL_REMOTE_NAMESPACE) && Objects.equal(rpcName.getLocalName(), SAL_REMOTE_RPC_SUBSRCIBE)) { - return invokeSalRemoteRpcSubscribeRPC(payload, rpc.getRpcDefinition()); + return invokeSalRemoteRpcSubscribeRPC(payload, rpc.getRpcDefinition(),parsePrettyPrintParameter(uriInfo)); } validateInput( rpc.getRpcDefinition().getInput(), payload ); - return callRpc(rpc, payload); + return callRpc(rpc, payload,parsePrettyPrintParameter(uriInfo)); } private void validateInput(final DataSchemaNode inputSchema, final CompositeNode payload) { @@ -426,7 +439,7 @@ public class RestconfImpl implements RestconfService { } private StructuredData invokeSalRemoteRpcSubscribeRPC(final CompositeNode payload, - final RpcDefinition rpc) { + final RpcDefinition rpc,final boolean prettyPrint) { final CompositeNode value = this.normalizeNode(payload, rpc.getInput(), null); final SimpleNode pathNode = value == null ? null : value.getFirstSimpleByName( QName.create(rpc.getQName(), "path") ); @@ -463,16 +476,16 @@ public class RestconfImpl implements RestconfService { Notificator.createListener(pathIdentifier, streamName); } - return new StructuredData(responseData, rpc.getOutput(), null); + return new StructuredData(responseData, rpc.getOutput(), null,prettyPrint); } @Override - public StructuredData invokeRpc(final String identifier, final String noPayload) { + public StructuredData invokeRpc(final String identifier, final String noPayload, final UriInfo uriInfo) { if (StringUtils.isNotBlank(noPayload)) { throw new RestconfDocumentedException( "Content must be empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE ); } - return invokeRpc( identifier, (CompositeNode)null ); + return invokeRpc( identifier, (CompositeNode)null,uriInfo); } private RpcExecutor resolveIdentifierInInvokeRpc(final String identifier) { @@ -516,7 +529,7 @@ public class RestconfImpl implements RestconfService { } - private StructuredData callRpc(final RpcExecutor rpcExecutor, final CompositeNode payload) { + private StructuredData callRpc(final RpcExecutor rpcExecutor, final CompositeNode payload,boolean prettyPrint) { if (rpcExecutor == null) { throw new RestconfDocumentedException( "RPC does not exist.", ErrorType.RPC, ErrorTag.UNKNOWN_ELEMENT ); @@ -547,7 +560,7 @@ public class RestconfImpl implements RestconfService { return null; //no output, nothing to send back. } - return new StructuredData(rpcResult.getResult(), rpc.getOutput(), null); + return new StructuredData(rpcResult.getResult(), rpc.getOutput(), null,prettyPrint); } private void checkRpcSuccessAndThrowException(final RpcResult rpcResult) { @@ -570,7 +583,7 @@ public class RestconfImpl implements RestconfService { } @Override - public StructuredData readConfigurationData(final String identifier, final UriInfo info) { + public StructuredData readConfigurationData(final String identifier, final UriInfo uriInfo) { final InstanceIdWithSchemaNode iiWithData = this.controllerContext.toInstanceIdentifier(identifier); CompositeNode data = null; MountInstance mountPoint = iiWithData.getMountPoint(); @@ -581,8 +594,9 @@ public class RestconfImpl implements RestconfService { data = broker.readConfigurationData(iiWithData.getInstanceIdentifier()); } - data = pruneDataAtDepth( data, parseDepthParameter( info ) ); - return new StructuredData(data, iiWithData.getSchemaNode(), iiWithData.getMountPoint()); + data = pruneDataAtDepth( data, parseDepthParameter( uriInfo ) ); + boolean prettyPrintMode = parsePrettyPrintParameter( uriInfo ); + return new StructuredData(data, iiWithData.getSchemaNode(), iiWithData.getMountPoint(),prettyPrintMode); } @SuppressWarnings("unchecked") @@ -607,7 +621,7 @@ public class RestconfImpl implements RestconfService { } private Integer parseDepthParameter( final UriInfo info ) { - String param = info.getQueryParameters( false ).getFirst( "depth" ); + String param = info.getQueryParameters( false ).getFirst( UriParameters.DEPTH.toString() ); if( Strings.isNullOrEmpty( param ) || "unbounded".equals( param ) ) { return null; } @@ -643,7 +657,13 @@ public class RestconfImpl implements RestconfService { } data = pruneDataAtDepth( data, parseDepthParameter( info ) ); - return new StructuredData(data, iiWithData.getSchemaNode(), mountPoint); + boolean prettyPrintMode = parsePrettyPrintParameter( info ); + return new StructuredData(data, iiWithData.getSchemaNode(), mountPoint,prettyPrintMode); + } + + private boolean parsePrettyPrintParameter(UriInfo info) { + String param = info.getQueryParameters(false).getFirst(UriParameters.PRETTY_PRINT.toString()); + return Boolean.parseBoolean(param); } @Override @@ -858,7 +878,7 @@ public class RestconfImpl implements RestconfService { broker.registerToListenDataChanges(listener); final UriBuilder uriBuilder = uriInfo.getAbsolutePathBuilder(); - UriBuilder port = uriBuilder.port(WebSocketServer.PORT); + UriBuilder port = uriBuilder.port(WebSocketServer.getInstance().getPort()); final URI uriToWebsocketServer = port.replacePath(streamName).build(); return Response.status(Status.OK).location(uriToWebsocketServer).build(); @@ -1117,6 +1137,7 @@ public class RestconfImpl implements RestconfService { final DataNodeContainer schema, final MountInstance mountPoint, final QName currentAugment ) { final List> children = compositeNodeBuilder.getValues(); + checkNodeMultiplicityAccordingToSchema(schema,children); for (final NodeWrapper child : children) { final List potentialSchemaNodes = this.controllerContext.findInstanceDataChildrenByName( @@ -1177,6 +1198,29 @@ public class RestconfImpl implements RestconfService { } } + private void checkNodeMultiplicityAccordingToSchema(final DataNodeContainer dataNodeContainer, + final List> nodes) { + Map equalNodeNamesToCounts = new HashMap(); + for (NodeWrapper child : nodes) { + Integer count = equalNodeNamesToCounts.get(child.getLocalName()); + equalNodeNamesToCounts.put(child.getLocalName(), count == null ? 1 : ++count); + } + + for (DataSchemaNode childSchemaNode : dataNodeContainer.getChildNodes()) { + if (childSchemaNode instanceof ContainerSchemaNode || childSchemaNode instanceof LeafSchemaNode) { + String localName = childSchemaNode.getQName().getLocalName(); + Integer count = equalNodeNamesToCounts.get(localName); + if (count != null && count > 1) { + throw new RestconfDocumentedException( + "Multiple input data elements were specified for '" + + childSchemaNode.getQName().getLocalName() + + "'. The data for this element type can only be specified once.", + ErrorType.APPLICATION, ErrorTag.BAD_ELEMENT); + } + } + } + } + private QName normalizeNodeName(final NodeWrapper nodeBuilder, final DataSchemaNode schema, final QName previousAugment, final MountInstance mountPoint) {