import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
-import java.net.URI;
import java.nio.charset.StandardCharsets;
-import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilder;
-import javax.ws.rs.core.UriInfo;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
import org.opendaylight.restconf.common.context.NormalizedNodeContext;
import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
import org.opendaylight.restconf.common.errors.RestconfError;
import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
+import org.opendaylight.restconf.common.patch.PatchContext;
+import org.opendaylight.restconf.common.patch.PatchStatusContext;
+import org.opendaylight.restconf.common.util.MultivaluedHashMap;
+import org.opendaylight.restconf.common.util.SimpleUriInfo;
import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
import org.opendaylight.restconf.nb.rfc8040.jersey.providers.JsonNormalizedNodeBodyReader;
import org.opendaylight.restconf.nb.rfc8040.jersey.providers.NormalizedNodeJsonBodyWriter;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch.JsonToPatchBodyReader;
+import org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch.PatchJsonBodyWriter;
import org.opendaylight.restconf.nb.rfc8040.rests.services.api.JSONRestconfService;
import org.opendaylight.restconf.nb.rfc8040.rests.services.api.TransactionServicesWrapper;
import org.opendaylight.restconf.nb.rfc8040.rests.utils.RestconfDataServiceConstant;
private final TransactionServicesWrapper services;
private final DOMMountPointServiceHandler mountPointServiceHandler;
+ private final SchemaContextHandler schemaContextHandler;
public JSONRestconfServiceRfc8040Impl(final TransactionServicesWrapper services,
- final DOMMountPointServiceHandler mountPointServiceHandler) {
+ final DOMMountPointServiceHandler mountPointServiceHandler,
+ final SchemaContextHandler schemaContextHandler) {
this.services = services;
this.mountPointServiceHandler = mountPointServiceHandler;
+ this.schemaContextHandler = schemaContextHandler;
}
@SuppressWarnings("checkstyle:IllegalCatch")
}
@SuppressWarnings("checkstyle:IllegalCatch")
+ @SuppressFBWarnings(value = "NP_NULL_PARAM_DEREF", justification = "Unrecognised NullableDecl")
@Override
public Optional<String> invokeRpc(final String uriPath, final Optional<String> input)
throws OperationFailedException {
if (outputContext.getData() != null) {
output = toJson(outputContext);
}
- } catch (final Exception e) {
+ } catch (RuntimeException | IOException e) {
propagateExceptionAs(uriPath, e, "RPC");
}
return Optional.fromNullable(output);
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
+ @Override
+ public Optional<String> patch(final String uriPath, final String payload)
+ throws OperationFailedException {
+
+ String output = null;
+ Preconditions.checkNotNull(payload, "payload can't be null");
+
+ LOG.debug("patch: uriPath: {}, payload: {}", uriPath, payload);
+
+ final InputStream entityStream = new ByteArrayInputStream(payload.getBytes(StandardCharsets.UTF_8));
+
+ JsonToPatchBodyReader jsonToPatchBodyReader = new JsonToPatchBodyReader(schemaContextHandler);
+ final PatchContext context = jsonToPatchBodyReader.readFrom(uriPath, entityStream);
+
+ LOG.debug("Parsed YangInstanceIdentifier: {}", context.getInstanceIdentifierContext().getInstanceIdentifier());
+ LOG.debug("Parsed NormalizedNode: {}", context.getData());
+
+ try {
+ PatchStatusContext patchStatusContext = services.patchData(context, new SimpleUriInfo(uriPath));
+ output = toJson(patchStatusContext);
+ } catch (final Exception e) {
+ propagateExceptionAs(uriPath, e, "PATCH");
+ }
+ return Optional.fromNullable(output);
+ }
+
@Override
public void close() {
}
private NormalizedNodeContext toNormalizedNodeContext(final String uriPath, @Nullable final String payload,
final boolean isPost) throws OperationFailedException {
final InstanceIdentifierContext<?> instanceIdentifierContext = ParserIdentifier.toInstanceIdentifier(
- uriPath, SchemaContextHandler.getActualSchemaContext(),
- Optional.of(mountPointServiceHandler.get()));
+ uriPath, schemaContextHandler.get(), Optional.of(mountPointServiceHandler.get()));
if (payload == null) {
return new NormalizedNodeContext(instanceIdentifierContext, null);
}
}
+ private String toJson(final PatchStatusContext patchStatusContext) throws IOException {
+ final PatchJsonBodyWriter writer = new PatchJsonBodyWriter();
+ final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ writer.writeTo(patchStatusContext, PatchStatusContext.class, null, EMPTY_ANNOTATIONS,
+ MediaType.APPLICATION_JSON_TYPE, null, outputStream);
+ return outputStream.toString(StandardCharsets.UTF_8.name());
+ }
+
private static String toJson(final NormalizedNodeContext readData) throws IOException {
final NormalizedNodeJsonBodyWriter writer = new NormalizedNodeJsonBodyWriter();
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
return ErrorType.APPLICATION;
}
}
-
- private static class SimpleUriInfo implements UriInfo {
- private final String path;
- private final MultivaluedMap<String, String> queryParams;
-
- SimpleUriInfo(final String path) {
- this(path, new MultivaluedHashMap<>());
- }
-
- SimpleUriInfo(final String path, final MultivaluedMap<String, String> queryParams) {
- this.path = path;
- this.queryParams = queryParams;
- }
-
- @Override
- public String getPath() {
- return path;
- }
-
- @Override
- public String getPath(final boolean decode) {
- return path;
- }
-
- @Override
- public List<PathSegment> getPathSegments() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public List<PathSegment> getPathSegments(final boolean decode) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public URI getRequestUri() {
- return URI.create(path);
- }
-
- @Override
- public UriBuilder getRequestUriBuilder() {
- return UriBuilder.fromUri(getRequestUri());
- }
-
- @Override
- public URI getAbsolutePath() {
- return getRequestUri();
- }
-
- @Override
- public UriBuilder getAbsolutePathBuilder() {
- return UriBuilder.fromUri(getAbsolutePath());
- }
-
- @Override
- public URI getBaseUri() {
- return URI.create("");
- }
-
- @Override
- public UriBuilder getBaseUriBuilder() {
- return UriBuilder.fromUri(getBaseUri());
- }
-
- @Override
- public MultivaluedMap<String, String> getPathParameters() {
- return new MultivaluedHashMap<>();
- }
-
- @Override
- public MultivaluedMap<String, String> getPathParameters(final boolean decode) {
- return getPathParameters();
- }
-
- @Override
- public MultivaluedMap<String, String> getQueryParameters() {
- return queryParams;
- }
-
- @Override
- public MultivaluedMap<String, String> getQueryParameters(final boolean decode) {
- return getQueryParameters();
- }
-
- @Override
- public List<String> getMatchedURIs() {
- return Collections.emptyList();
- }
-
- @Override
- public List<String> getMatchedURIs(final boolean decode) {
- return getMatchedURIs();
- }
-
- @Override
- public List<Object> getMatchedResources() {
- return Collections.emptyList();
- }
-
- @Override
- public URI resolve(final URI uri) {
- return uri;
- }
-
- @Override
- public URI relativize(final URI uri) {
- return uri;
- }
- }
}