X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=inline;f=opendaylight%2Fmd-sal%2Fsal-rest-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frestconf%2Fimpl%2FRestconfImpl.java;h=814273ebc0dc6ba1205fa3a7c93dd97152e38034;hb=576efc4bd225c62269108466aaaa2c4a2dfd4d65;hp=82ac862843b78db99d1707dce5ac701b139185e8;hpb=f55f03931ef55344b0fb71b75fb0cb577fa89d54;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 82ac862843..814273ebc0 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 @@ -18,6 +18,7 @@ import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.Futures; import java.math.BigInteger; @@ -74,6 +75,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.InstanceI import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; @@ -168,8 +170,6 @@ public class RestconfImpl implements RestconfService { private static final URI NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT = URI.create("urn:sal:restconf:event:subscription"); - private static final Date EVENT_SUBSCRIPTION_AUGMENT_REVISION; - private static final String DATASTORE_PARAM_NAME = "datastore"; private static final String SCOPE_PARAM_NAME = "scope"; @@ -180,10 +180,18 @@ public class RestconfImpl implements RestconfService { private static final QName NETCONF_BASE_QNAME; + private static final QNameModule SAL_REMOTE_AUGMENT; + + private static final YangInstanceIdentifier.AugmentationIdentifier SAL_REMOTE_AUG_IDENTIFIER; + static { try { - EVENT_SUBSCRIPTION_AUGMENT_REVISION = new SimpleDateFormat("yyyy-MM-dd").parse("2014-07-08"); + final Date eventSubscriptionAugRevision = new SimpleDateFormat("yyyy-MM-dd").parse("2014-07-08"); NETCONF_BASE_QNAME = QName.create(QNameModule.create(new URI(NETCONF_BASE), null), NETCONF_BASE_PAYLOAD_NAME ); + SAL_REMOTE_AUGMENT = QNameModule.create(NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT, + eventSubscriptionAugRevision); + SAL_REMOTE_AUG_IDENTIFIER = new YangInstanceIdentifier.AugmentationIdentifier(Sets.newHashSet(QName.create(SAL_REMOTE_AUGMENT, "scope"), + QName.create(SAL_REMOTE_AUGMENT, "datastore"))); } catch (final ParseException e) { throw new RestconfDocumentedException( "It wasn't possible to convert revision date of sal-remote-augment to date", ErrorType.APPLICATION, @@ -549,16 +557,14 @@ public class RestconfImpl implements RestconfService { final DOMRpcResult result = checkRpcResponse(response); - DataSchemaNode resultNodeSchema = null; - NormalizedNode resultData = null; + RpcDefinition resultNodeSchema = null; + final NormalizedNode resultData = result.getResult(); if (result != null && result.getResult() != null) { - resultData = result.getResult(); - final ContainerSchemaNode rpcDataSchemaNode = SchemaContextUtil.getRpcDataSchema(schemaContext, type); - resultNodeSchema = rpcDataSchemaNode.getDataChildByName(result.getResult().getNodeType()); + resultNodeSchema = (RpcDefinition) payload.getInstanceIdentifierContext().getSchemaNode(); } - return new NormalizedNodeContext(new InstanceIdentifierContext(null, resultNodeSchema, mountPoint, - schemaContext), resultData); + return new NormalizedNodeContext(new InstanceIdentifierContext(null, + resultNodeSchema, mountPoint, schemaContext), resultData); } private DOMRpcResult checkRpcResponse(final CheckedFuture response) { @@ -601,7 +607,7 @@ public class RestconfImpl implements RestconfService { } } - private void validateInput(final DataSchemaNode inputSchema, final NormalizedNodeContext payload) { + private void validateInput(final SchemaNode inputSchema, final NormalizedNodeContext payload) { if (inputSchema != null && payload.getData() == null) { // expected a non null payload throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE); @@ -643,7 +649,7 @@ public class RestconfImpl implements RestconfService { private CheckedFuture invokeSalRemoteRpcSubscribeRPC(final NormalizedNodeContext payload) { final ContainerNode value = (ContainerNode) payload.getData(); final QName rpcQName = payload.getInstanceIdentifierContext().getSchemaNode().getQName(); - Optional> path = value.getChild(new NodeIdentifier( + final Optional> path = value.getChild(new NodeIdentifier( QName.create(payload.getInstanceIdentifierContext().getSchemaNode().getQName(), "path"))); final Object pathValue = path.isPresent() ? path.get().getValue() : null; @@ -674,18 +680,18 @@ public class RestconfImpl implements RestconfService { ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE); } - QName outputQname = QName.create(rpcQName, "output"); - QName streamNameQname = QName.create(rpcQName, "stream-name"); + final QName outputQname = QName.create(rpcQName, "output"); + final QName streamNameQname = QName.create(rpcQName, "stream-name"); - ContainerNode output = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(outputQname)) + final ContainerNode output = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(outputQname)) .withChild(ImmutableNodes.leafNode(streamNameQname, streamName)).build(); if (!Notificator.existListenerFor(streamName)) { - YangInstanceIdentifier normalizedPathIdentifier = controllerContext.toNormalized(pathIdentifier); + final YangInstanceIdentifier normalizedPathIdentifier = controllerContext.toNormalized(pathIdentifier); Notificator.createListener(normalizedPathIdentifier, streamName); } - DOMRpcResult defaultDOMRpcResult = new DefaultDOMRpcResult(output); + final DOMRpcResult defaultDOMRpcResult = new DefaultDOMRpcResult(output); return Futures.immediateCheckedFuture(defaultDOMRpcResult); } @@ -733,7 +739,7 @@ public class RestconfImpl implements RestconfService { if (rpc.getInput() != null) { // FIXME : find a correct Error from specification - throw new IllegalStateException("RPC " + rpc + " needs input value!"); + throw new IllegalStateException("RPC " + rpc + " does'n need input value!"); } final CheckedFuture response; @@ -872,15 +878,17 @@ public class RestconfImpl implements RestconfService { final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier); final DOMMountPoint mountPoint = iiWithData.getMountPoint(); NormalizedNode data = null; - YangInstanceIdentifier normalizedII; + final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier(); if (mountPoint != null) { - normalizedII = new DataNormalizer(mountPoint.getSchemaContext()).toNormalized(iiWithData - .getInstanceIdentifier()); data = broker.readConfigurationData(mountPoint, normalizedII); } else { - normalizedII = controllerContext.toNormalized(iiWithData.getInstanceIdentifier()); data = broker.readConfigurationData(normalizedII); } + if(data == null) { + throw new RestconfDocumentedException( + "Request could not be completed because the relevant data model content does not exist.", + ErrorType.APPLICATION, ErrorTag.DATA_MISSING); + } return new NormalizedNodeContext(iiWithData, data); } @@ -931,16 +939,17 @@ public class RestconfImpl implements RestconfService { final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier); final DOMMountPoint mountPoint = iiWithData.getMountPoint(); NormalizedNode data = null; - YangInstanceIdentifier normalizedII; + final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier(); if (mountPoint != null) { - normalizedII = new DataNormalizer(mountPoint.getSchemaContext()).toNormalized(iiWithData - .getInstanceIdentifier()); data = broker.readOperationalData(mountPoint, normalizedII); } else { - normalizedII = controllerContext.toNormalized(iiWithData.getInstanceIdentifier()); data = broker.readOperationalData(normalizedII); } - + if(data == null) { + throw new RestconfDocumentedException( + "Request could not be completed because the relevant data model content does not exist.", + ErrorType.APPLICATION, ErrorTag.DATA_MISSING); + } return new NormalizedNodeContext(iiWithData, data); } @@ -952,7 +961,8 @@ public class RestconfImpl implements RestconfService { @Override public Response updateConfigurationData(final String identifier, final NormalizedNodeContext payload) { Preconditions.checkNotNull(identifier); - final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier); + final InstanceIdentifierContext iiWithData = + (InstanceIdentifierContext) payload.getInstanceIdentifierContext(); validateInput(iiWithData.getSchemaNode(), payload); validateTopLevelNodeName(payload, iiWithData.getInstanceIdentifier()); @@ -1062,7 +1072,7 @@ public class RestconfImpl implements RestconfService { * if key values or key count in payload and URI isn't equal * */ - private void validateListKeysEqualityInPayloadAndUri(final InstanceIdentifierContext iiWithData, + private void validateListKeysEqualityInPayloadAndUri(final InstanceIdentifierContext iiWithData, final NormalizedNode payload) { if (iiWithData.getSchemaNode() instanceof ListSchemaNode) { final List keyDefinitions = ((ListSchemaNode) iiWithData.getSchemaNode()).getKeyDefinition(); @@ -1158,43 +1168,7 @@ public class RestconfImpl implements RestconfService { @Override public Response createConfigurationData(final String identifier, final NormalizedNodeContext payload, final UriInfo uriInfo) { - if (payload == null) { - throw new RestconfDocumentedException("Input is required.", ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE); - } - - final URI payloadNS = payload.getData().getNodeType().getNamespace(); - if (payloadNS == null) { - throw new RestconfDocumentedException( - "Data has bad format. Root element node must have namespace (XML format) or module name(JSON format)", - ErrorType.PROTOCOL, ErrorTag.UNKNOWN_NAMESPACE); - } - - final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint(); - - final InstanceIdentifierContext iiWithData = mountPoint != null - ? controllerContext.toMountPointIdentifier(identifier) - : controllerContext.toInstanceIdentifier(identifier); - final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier(); - - try { - if (mountPoint != null) { - broker.commitConfigurationDataPost(mountPoint, normalizedII, payload.getData()); - } else { - broker.commitConfigurationDataPost(normalizedII, payload.getData()); - } - } catch(final RestconfDocumentedException e) { - throw e; - } catch (final Exception e) { - throw new RestconfDocumentedException("Error creating data", e); - } - - - final ResponseBuilder responseBuilder = Response.status(Status.NO_CONTENT); - final URI location = resolveLocation(uriInfo, "config", mountPoint, normalizedII); - if (location != null) { - responseBuilder.location(location); - } - return responseBuilder.build(); + return createConfigurationData(payload, uriInfo); } // FIXME create RestconfIdetifierHelper and move this method there @@ -1241,15 +1215,14 @@ public class RestconfImpl implements RestconfService { } final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint(); - final InstanceIdentifierContext iiWithData = payload.getInstanceIdentifierContext(); + final InstanceIdentifierContext iiWithData = (InstanceIdentifierContext) payload.getInstanceIdentifierContext(); final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier(); - + final YangInstanceIdentifier resultII; try { if (mountPoint != null) { - broker.commitConfigurationDataPost(mountPoint, normalizedII, payload.getData()); - + broker.commitConfigurationDataPost(mountPoint, normalizedII, payload.getData()).checkedGet(); } else { - broker.commitConfigurationDataPost(normalizedII, payload.getData()); + broker.commitConfigurationDataPost(normalizedII, payload.getData()).checkedGet(); } } catch(final RestconfDocumentedException e) { throw e; @@ -1258,6 +1231,7 @@ public class RestconfImpl implements RestconfService { } final ResponseBuilder responseBuilder = Response.status(Status.NO_CONTENT); + // FIXME: Provide path to result. final URI location = resolveLocation(uriInfo, "", mountPoint, normalizedII); if (location != null) { responseBuilder.location(location); @@ -1279,17 +1253,14 @@ public class RestconfImpl implements RestconfService { @Override public Response deleteConfigurationData(final String identifier) { - final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier); + final InstanceIdentifierContext iiWithData = controllerContext.toInstanceIdentifier(identifier); final DOMMountPoint mountPoint = iiWithData.getMountPoint(); - YangInstanceIdentifier normalizedII; + final YangInstanceIdentifier normalizedII = iiWithData.getInstanceIdentifier(); try { if (mountPoint != null) { - normalizedII = new DataNormalizer(mountPoint.getSchemaContext()).toNormalized(iiWithData - .getInstanceIdentifier()); broker.commitConfigurationDataDelete(mountPoint, normalizedII); } else { - normalizedII = controllerContext.toNormalized(iiWithData.getInstanceIdentifier()); broker.commitConfigurationDataDelete(normalizedII).get(); } } catch (final Exception e) { @@ -1362,10 +1333,12 @@ public class RestconfImpl implements RestconfService { */ private T parseEnumTypeParameter(final ContainerNode value, final Class classDescriptor, final String paramName) { - final QNameModule salRemoteAugment = QNameModule.create(NAMESPACE_EVENT_SUBSCRIPTION_AUGMENT, - EVENT_SUBSCRIPTION_AUGMENT_REVISION); - Optional> enumNode = value.getChild(new NodeIdentifier( - QName.create(salRemoteAugment, paramName))); + final Optional> augNode = value.getChild(SAL_REMOTE_AUG_IDENTIFIER); + if (!augNode.isPresent() && !(augNode instanceof AugmentationNode)) { + return null; + } + final Optional> enumNode = + ((AugmentationNode) augNode.get()).getChild(new NodeIdentifier(QName.create(SAL_REMOTE_AUGMENT, paramName))); if (!enumNode.isPresent()) { return null; }