import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Optional;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
-import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.mdsal.dom.api.DOMActionException;
import org.opendaylight.mdsal.dom.api.DOMActionResult;
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.common.patch.PatchContext;
import org.opendaylight.restconf.common.patch.PatchStatusContext;
-import org.opendaylight.restconf.nb.rfc8040.InsertParameter;
-import org.opendaylight.restconf.nb.rfc8040.PointParameter;
+import org.opendaylight.restconf.nb.rfc8040.ReadDataParams;
import org.opendaylight.restconf.nb.rfc8040.Rfc8040;
+import org.opendaylight.restconf.nb.rfc8040.WriteDataParams;
+import org.opendaylight.restconf.nb.rfc8040.databind.jaxrs.QueryParams;
import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
import org.opendaylight.restconf.nb.rfc8040.legacy.QueryParameters;
import org.opendaylight.restconf.nb.rfc8040.utils.mapping.RestconfMappingNodeUtil;
import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
-import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.common.ErrorTag;
import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.QName;
*/
@Path("/")
public class RestconfDataServiceImpl implements RestconfDataService {
- // FIXME: we should be able to interpret 'point' and refactor this class into a behavior
- private static final class QueryParams implements Immutable {
- final @Nullable PointParameter point;
- final @Nullable InsertParameter insert;
-
- QueryParams(final @Nullable InsertParameter insert, final @Nullable PointParameter point) {
- this.insert = insert;
- this.point = point;
- }
- }
-
private static final Logger LOG = LoggerFactory.getLogger(RestconfDataServiceImpl.class);
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss");
private static final QName NETCONF_BASE_QNAME = SchemaContext.NAME;
@Override
public Response readData(final String identifier, final UriInfo uriInfo) {
+ final ReadDataParams readParams = QueryParams.newReadDataParams(uriInfo);
+
final EffectiveModelContext schemaContextRef = schemaContextHandler.get();
- final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
+ final InstanceIdentifierContext instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
identifier, schemaContextRef, Optional.of(mountPointService));
- final QueryParameters parameters = ReadDataTransactionUtil.parseUriParameters(instanceIdentifier, uriInfo);
-
final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
// FIXME: this looks quite crazy, why do we even have it?
createAllYangNotificationStreams(schemaContextRef, uriInfo);
}
- final List<YangInstanceIdentifier> fieldPaths = parameters.getFieldPaths();
+ final QueryParameters queryParams = QueryParams.newQueryParameters(readParams, instanceIdentifier);
+ final List<YangInstanceIdentifier> fieldPaths = queryParams.fieldPaths();
final RestconfStrategy strategy = getRestconfStrategy(mountPoint);
final NormalizedNode node;
if (fieldPaths != null && !fieldPaths.isEmpty()) {
- node = ReadDataTransactionUtil.readData(parameters.getContent(), instanceIdentifier.getInstanceIdentifier(),
- strategy, parameters.getWithDefault(), schemaContextRef, fieldPaths);
+ node = ReadDataTransactionUtil.readData(readParams.content(), instanceIdentifier.getInstanceIdentifier(),
+ strategy, readParams.withDefaults(), schemaContextRef, fieldPaths);
} else {
- node = ReadDataTransactionUtil.readData(parameters.getContent(), instanceIdentifier.getInstanceIdentifier(),
- strategy, parameters.getWithDefault(), schemaContextRef);
+ node = ReadDataTransactionUtil.readData(readParams.content(), instanceIdentifier.getInstanceIdentifier(),
+ strategy, readParams.withDefaults(), schemaContextRef);
}
// FIXME: this is utter craziness, refactor it properly!
ErrorType.PROTOCOL, ErrorTag.DATA_MISSING);
}
- switch (parameters.getContent()) {
+ switch (readParams.content()) {
case ALL:
case CONFIG:
final QName type = node.getIdentifier().getNodeType();
return Response.status(Status.OK)
- .entity(NormalizedNodePayload.ofReadData(instanceIdentifier, node, parameters))
+ .entity(NormalizedNodePayload.ofReadData(instanceIdentifier, node, queryParams))
.header("ETag", '"' + type.getModule().getRevision().map(Revision::toString).orElse(null)
+ "-" + type.getLocalName() + '"')
.header("Last-Modified", FORMATTER.format(LocalDateTime.now(Clock.systemUTC())))
.build();
default:
return Response.status(Status.OK)
- .entity(NormalizedNodePayload.ofReadData(instanceIdentifier, node, parameters))
+ .entity(NormalizedNodePayload.ofReadData(instanceIdentifier, node, queryParams))
.build();
}
}
public Response putData(final String identifier, final NormalizedNodePayload payload, final UriInfo uriInfo) {
requireNonNull(payload);
- final QueryParams checkedParms = checkQueryParameters(uriInfo);
+ final WriteDataParams params = QueryParams.newWriteDataParams(uriInfo);
- final InstanceIdentifierContext<? extends SchemaNode> iid = payload.getInstanceIdentifierContext();
+ final InstanceIdentifierContext iid = payload.getInstanceIdentifierContext();
validInputData(iid.getSchemaNode(), payload);
validTopLevelNodeName(iid.getInstanceIdentifier(), payload);
? schemaContextHandler.get() : modelContext(mountPoint);
final RestconfStrategy strategy = getRestconfStrategy(mountPoint);
- return PutDataTransactionUtil.putData(payload, ref, strategy, checkedParms.insert, checkedParms.point);
- }
-
- private static QueryParams checkQueryParameters(final UriInfo uriInfo) {
- boolean insertUsed = false;
- boolean pointUsed = false;
- InsertParameter insert = null;
- PointParameter point = null;
-
- for (final Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) {
- final String uriName = entry.getKey();
- if (InsertParameter.uriName().equals(uriName)) {
- if (insertUsed) {
- throw new RestconfDocumentedException("Insert parameter can be used only once.",
- ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
- }
-
- insertUsed = true;
- final String str = entry.getValue().get(0);
- insert = InsertParameter.forUriValue(str);
- if (insert == null) {
- throw new RestconfDocumentedException("Unrecognized insert parameter value '" + str + "'",
- ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
- }
- } else if (PointParameter.uriName().equals(uriName)) {
- if (pointUsed) {
- throw new RestconfDocumentedException("Point parameter can be used only once.",
- ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
- }
-
- pointUsed = true;
- point = PointParameter.forUriValue(entry.getValue().get(0));
- } else {
- throw new RestconfDocumentedException("Bad parameter for post: " + uriName,
- ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
- }
- }
-
- checkQueryParams(insertUsed, pointUsed, insert);
- return new QueryParams(insert, point);
- }
-
- private static void checkQueryParams(final boolean insertUsed, final boolean pointUsed,
- final InsertParameter insert) {
- if (pointUsed) {
- if (!insertUsed) {
- throw new RestconfDocumentedException("Point parameter can't be used without Insert parameter.",
- ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
- }
- if (insert != InsertParameter.BEFORE && insert != InsertParameter.AFTER) {
- throw new RestconfDocumentedException(
- "Point parameter can be used only with 'after' or 'before' values of Insert parameter.",
- ErrorType.PROTOCOL, ErrorTag.BAD_ELEMENT);
- }
- }
+ return PutDataTransactionUtil.putData(payload, ref, strategy, params);
}
@Override
return invokeAction(payload);
}
- final QueryParams checkedParms = checkQueryParameters(uriInfo);
+ final WriteDataParams params = QueryParams.newWriteDataParams(uriInfo);
final DOMMountPoint mountPoint = payload.getInstanceIdentifierContext().getMountPoint();
final RestconfStrategy strategy = getRestconfStrategy(mountPoint);
- return PostDataTransactionUtil.postData(uriInfo, payload, strategy,
- getSchemaContext(mountPoint), checkedParms.insert, checkedParms.point);
+ return PostDataTransactionUtil.postData(uriInfo, payload, strategy, getSchemaContext(mountPoint), params);
}
@Override
public Response deleteData(final String identifier) {
- final InstanceIdentifierContext<?> instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
+ final InstanceIdentifierContext instanceIdentifier = ParserIdentifier.toInstanceIdentifier(
identifier, schemaContextHandler.get(), Optional.of(mountPointService));
final DOMMountPoint mountPoint = instanceIdentifier.getMountPoint();
public Response patchData(final String identifier, final NormalizedNodePayload payload, final UriInfo uriInfo) {
requireNonNull(payload);
- final InstanceIdentifierContext<? extends SchemaNode> iid = payload.getInstanceIdentifierContext();
+ final InstanceIdentifierContext iid = payload.getInstanceIdentifierContext();
validInputData(iid.getSchemaNode(), payload);
validTopLevelNodeName(iid.getInstanceIdentifier(), payload);
validateListKeysEqualityInPayloadAndUri(payload);
* @return {@link NormalizedNodePayload} wrapped in {@link Response}
*/
public Response invokeAction(final NormalizedNodePayload payload) {
- final InstanceIdentifierContext<?> context = payload.getInstanceIdentifierContext();
- final DOMMountPoint mountPoint = context.getMountPoint();
- final Absolute schemaPath = Absolute.of(ImmutableList.copyOf(context.getSchemaNode().getPath()
- .getPathFromRoot()));
+ final InstanceIdentifierContext context = payload.getInstanceIdentifierContext();
final YangInstanceIdentifier yangIIdContext = context.getInstanceIdentifier();
final NormalizedNode data = payload.getData();
ErrorType.PROTOCOL, ErrorTag.MALFORMED_MESSAGE);
}
+ final DOMMountPoint mountPoint = context.getMountPoint();
+ final Absolute schemaPath = Absolute.of(ImmutableList.copyOf(context.getSchemaNode().getPath()
+ .getPathFromRoot()));
final DOMActionResult response;
final EffectiveModelContext schemaContextRef;
if (mountPoint != null) {
return Response.status(Status.OK)
.entity(NormalizedNodePayload.ofNullable(
- new InstanceIdentifierContext<>(yangIIdContext, resultNodeSchema, mountPoint, schemaContextRef),
+ new InstanceIdentifierContext(yangIIdContext, resultNodeSchema, mountPoint, schemaContextRef),
resultData))
.build();
}
-
/**
* Invoking Action via mount point.
*
*/
@VisibleForTesting
public static void validateListKeysEqualityInPayloadAndUri(final NormalizedNodePayload payload) {
- final InstanceIdentifierContext<?> iiWithData = payload.getInstanceIdentifierContext();
+ final InstanceIdentifierContext iiWithData = payload.getInstanceIdentifierContext();
final PathArgument lastPathArgument = iiWithData.getInstanceIdentifier().getLastPathArgument();
final SchemaNode schemaNode = iiWithData.getSchemaNode();
final NormalizedNode data = payload.getData();