From: Jakub Morvay Date: Wed, 21 Jun 2017 07:52:43 +0000 (+0000) Subject: Merge "Switch from config-parent in pom files" X-Git-Tag: release/nitrogen~56 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=4469e472b3208c5d472ce3970f4a875f9fae830e;hp=9251b02f242ff6abe00fee9086a2fcd5fea3b207;p=netconf.git Merge "Switch from config-parent in pom files" --- diff --git a/features/restconf/features-restconf/pom.xml b/features/restconf/features-restconf/pom.xml index d45fe415f1..ae922a5d95 100644 --- a/features/restconf/features-restconf/pom.xml +++ b/features/restconf/features-restconf/pom.xml @@ -135,8 +135,9 @@ jackson-databind - com.fasterxml.jackson.datatype - jackson-datatype-json-org + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + 2.3.2 com.fasterxml.jackson.module @@ -150,10 +151,6 @@ com.fasterxml.jackson.jaxrs jackson-jaxrs-json-provider - - org.json - json - org.opendaylight.yangtools diff --git a/features/restconf/features-restconf/src/main/features/features.xml b/features/restconf/features-restconf/src/main/features/features.xml index 77c9687fba..cc371cde3a 100644 --- a/features/restconf/features-restconf/src/main/features/features.xml +++ b/features/restconf/features-restconf/src/main/features/features.xml @@ -37,6 +37,9 @@ mvn:com.google.code.gson/gson/{{VERSION}} mvn:org.opendaylight.yangtools/yang-data-codec-gson/{{VERSION}} mvn:org.opendaylight.yangtools/yang-model-export/{{VERSION}} + mvn:com.fasterxml.jackson.dataformat/jackson-dataformat-xml/{{VERSION}} + mvn:org.codehaus.woodstox/stax2-api/{{VERSION}} + wrap:mvn:javax.xml.stream/stax-api/{{VERSION}} mvn:org.opendaylight.netconf/sal-rest-connector-config/{{VERSION}}/xml/config mvn:org.opendaylight.netconf/sal-rest-connector-config/{{VERSION}}/xml/configrestconfservice @@ -46,14 +49,12 @@ mvn:com.fasterxml.jackson.core/jackson-annotations/{{VERSION}} mvn:com.fasterxml.jackson.core/jackson-core/{{VERSION}} mvn:com.fasterxml.jackson.core/jackson-databind/{{VERSION}} - mvn:com.fasterxml.jackson.datatype/jackson-datatype-json-org/{{VERSION}} mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/{{VERSION}} mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/{{VERSION}} mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/{{VERSION}} mvn:com.sun.jersey/jersey-core/{{VERSION}} mvn:com.sun.jersey/jersey-server/{{VERSION}} mvn:com.sun.jersey/jersey-servlet/{{VERSION}} - wrap:mvn:org.json/json/{{VERSION}} diff --git a/features/restconf/odl-mdsal-apidocs/pom.xml b/features/restconf/odl-mdsal-apidocs/pom.xml index 6944837c75..3aa0f2d136 100644 --- a/features/restconf/odl-mdsal-apidocs/pom.xml +++ b/features/restconf/odl-mdsal-apidocs/pom.xml @@ -38,49 +38,5 @@ sal-rest-docgen ${project.version} - - com.fasterxml.jackson.core - jackson-annotations - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.datatype - jackson-datatype-json-org - - - com.fasterxml.jackson.module - jackson-module-jaxb-annotations - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-base - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider - - - com.sun.jersey - jersey-core - - - com.sun.jersey - jersey-server - - - com.sun.jersey - jersey-servlet - - - org.json - json - \ No newline at end of file diff --git a/features/restconf/odl-restconf-noauth/pom.xml b/features/restconf/odl-restconf-noauth/pom.xml index 9d8fe92084..9b6da60170 100644 --- a/features/restconf/odl-restconf-noauth/pom.xml +++ b/features/restconf/odl-restconf-noauth/pom.xml @@ -115,18 +115,6 @@ org.opendaylight.netconf sal-rest-connector - - com.google.code.gson - gson - - - org.opendaylight.yangtools - yang-data-codec-gson - - - org.opendaylight.yangtools - yang-model-export - org.opendaylight.netconf diff --git a/karaf/pom.xml b/karaf/pom.xml index 3ab1d1478e..e76fabaa12 100644 --- a/karaf/pom.xml +++ b/karaf/pom.xml @@ -18,9 +18,6 @@ netconf-karaf 1.6.0-SNAPSHOT pom - - 3.1.1 - 1.3.0-SNAPSHOT 1.6.0-SNAPSHOT diff --git a/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/RuntimeRpc.java b/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/RuntimeRpc.java index 3321b269fb..2b18e2c2c5 100644 --- a/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/RuntimeRpc.java +++ b/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/RuntimeRpc.java @@ -40,7 +40,7 @@ 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.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; -import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.schema.SchemaOrderedNormalizedNodeWriter; import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils; import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory; diff --git a/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/get/AbstractGet.java b/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/get/AbstractGet.java index 5acceb359b..e04766a1d7 100644 --- a/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/get/AbstractGet.java +++ b/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/get/AbstractGet.java @@ -33,7 +33,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter; -import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaPath; diff --git a/netconf/sal-netconf-connector/pom.xml b/netconf/sal-netconf-connector/pom.xml index bccd4a782f..fb52fbb0c2 100644 --- a/netconf/sal-netconf-connector/pom.xml +++ b/netconf/sal-netconf-connector/pom.xml @@ -119,6 +119,10 @@ org.opendaylight.yangtools yang-data-codec-gson + + org.opendaylight.yangtools + yang-data-codec-xml + org.opendaylight.mdsal.model ietf-inet-types-2013-07-15 diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java index 07fa3467f5..4cc4110653 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java @@ -51,7 +51,7 @@ 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.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; -import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.data.impl.schema.SchemaOrderedNormalizedNodeWriter; diff --git a/restconf/sal-rest-connector/pom.xml b/restconf/sal-rest-connector/pom.xml index a332a5f69d..81b4042c47 100644 --- a/restconf/sal-rest-connector/pom.xml +++ b/restconf/sal-rest-connector/pom.xml @@ -123,6 +123,10 @@ org.opendaylight.yangtools yang-data-codec-gson + + org.opendaylight.yangtools + yang-data-codec-xml + org.opendaylight.yangtools yang-model-export @@ -146,17 +150,19 @@ net.java.dev.stax-utils stax-utils + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + + + 2.3.2 + ch.qos.logback logback-classic test - - org.json - json - - org.glassfish.jersey.test-framework.providers diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/NormalizedNodeXmlBodyWriter.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/NormalizedNodeXmlBodyWriter.java index 40123d0e98..434b476457 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/NormalizedNodeXmlBodyWriter.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/NormalizedNodeXmlBodyWriter.java @@ -37,7 +37,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; -import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/RestconfDocumentedExceptionMapper.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/RestconfDocumentedExceptionMapper.java index f24650856c..4590782621 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/RestconfDocumentedExceptionMapper.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/rest/impl/RestconfDocumentedExceptionMapper.java @@ -51,7 +51,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWrit import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory; import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory; -import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder; @@ -165,14 +165,14 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper lsChildDataSchemaNode = ControllerContext.findInstanceDataChildrenByName( - (listStreamSchemaNode), "error-type"); + listStreamSchemaNode, "error-type"); final DataSchemaNode errTypSchemaNode = Iterables.getFirst(lsChildDataSchemaNode, null); Preconditions.checkState(errTypSchemaNode instanceof LeafSchemaNode); errNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) errTypSchemaNode) .withValue(error.getErrorType().getErrorTypeTag()).build()); lsChildDataSchemaNode = ControllerContext.findInstanceDataChildrenByName( - (listStreamSchemaNode), "error-tag"); + listStreamSchemaNode, "error-tag"); final DataSchemaNode errTagSchemaNode = Iterables.getFirst(lsChildDataSchemaNode, null); Preconditions.checkState(errTagSchemaNode instanceof LeafSchemaNode); errNodeValues.withChild(Builders.leafBuilder((LeafSchemaNode) errTagSchemaNode) @@ -180,7 +180,7 @@ public class RestconfDocumentedExceptionMapper implements ExceptionMapper get(String uriPath, LogicalDatastoreType datastoreType, UriInfo uriInfo) + Optional get(String uriPath, LogicalDatastoreType datastoreType) throws OperationFailedException; /** diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/JSONRestconfServiceImpl.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/JSONRestconfServiceImpl.java index 77c6dc99c6..f6359a68b8 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/JSONRestconfServiceImpl.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/JSONRestconfServiceImpl.java @@ -14,9 +14,15 @@ 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.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.UriBuilder; import javax.ws.rs.core.UriInfo; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.netconf.sal.rest.impl.JsonNormalizedNodeBodyReader; @@ -42,7 +48,7 @@ public class JSONRestconfServiceImpl implements JSONRestconfService, AutoCloseab @SuppressWarnings("checkstyle:IllegalCatch") @Override - public void put(final String uriPath, final String payload, final UriInfo uriInfo) throws OperationFailedException { + public void put(final String uriPath, final String payload) throws OperationFailedException { Preconditions.checkNotNull(payload, "payload can't be null"); LOG.debug("put: uriPath: {}, payload: {}", uriPath, payload); @@ -54,7 +60,7 @@ public class JSONRestconfServiceImpl implements JSONRestconfService, AutoCloseab LOG.debug("Parsed NormalizedNode: {}", context.getData()); try { - RestconfImpl.getInstance().updateConfigurationData(uriPath, context, uriInfo); + RestconfImpl.getInstance().updateConfigurationData(uriPath, context, new SimpleUriInfo(uriPath)); } catch (final Exception e) { propagateExceptionAs(uriPath, e, "PUT"); } @@ -62,7 +68,7 @@ public class JSONRestconfServiceImpl implements JSONRestconfService, AutoCloseab @SuppressWarnings("checkstyle:IllegalCatch") @Override - public void post(final String uriPath, final String payload, final UriInfo uriInfo) + public void post(final String uriPath, final String payload) throws OperationFailedException { Preconditions.checkNotNull(payload, "payload can't be null"); @@ -75,7 +81,7 @@ public class JSONRestconfServiceImpl implements JSONRestconfService, AutoCloseab LOG.debug("Parsed NormalizedNode: {}", context.getData()); try { - RestconfImpl.getInstance().createConfigurationData(uriPath, context, uriInfo); + RestconfImpl.getInstance().createConfigurationData(uriPath, context, new SimpleUriInfo(uriPath)); } catch (final Exception e) { propagateExceptionAs(uriPath, e, "POST"); } @@ -95,12 +101,13 @@ public class JSONRestconfServiceImpl implements JSONRestconfService, AutoCloseab @SuppressWarnings("checkstyle:IllegalCatch") @Override - public Optional get(final String uriPath, final LogicalDatastoreType datastoreType, final UriInfo uriInfo) + public Optional get(final String uriPath, final LogicalDatastoreType datastoreType) throws OperationFailedException { LOG.debug("get: uriPath: {}", uriPath); try { NormalizedNodeContext readData; + final SimpleUriInfo uriInfo = new SimpleUriInfo(uriPath); if (datastoreType == LogicalDatastoreType.CONFIGURATION) { readData = RestconfImpl.getInstance().readConfigurationData(uriPath, uriInfo); } else { @@ -225,4 +232,113 @@ public class JSONRestconfServiceImpl implements JSONRestconfService, AutoCloseab } } } + + private static class SimpleUriInfo implements UriInfo { + private final String path; + private final MultivaluedMap queryParams; + + SimpleUriInfo(String path) { + this(path, new MultivaluedHashMap<>()); + } + + SimpleUriInfo(String path, MultivaluedMap queryParams) { + this.path = path; + this.queryParams = queryParams; + } + + @Override + public String getPath() { + return path; + } + + @Override + public String getPath(boolean decode) { + return path; + } + + @Override + public List getPathSegments() { + throw new UnsupportedOperationException(); + } + + @Override + public List getPathSegments(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 getPathParameters() { + return new MultivaluedHashMap<>(); + } + + @Override + public MultivaluedMap getPathParameters(boolean decode) { + return getPathParameters(); + } + + @Override + public MultivaluedMap getQueryParameters() { + return queryParams; + } + + @Override + public MultivaluedMap getQueryParameters(boolean decode) { + return getQueryParameters(); + } + + @Override + public List getMatchedURIs() { + return Collections.emptyList(); + } + + @Override + public List getMatchedURIs(boolean decode) { + return getMatchedURIs(); + } + + @Override + public List getMatchedResources() { + return Collections.emptyList(); + } + + @Override + public URI resolve(URI uri) { + return uri; + } + + @Override + public URI relativize(URI uri) { + return uri; + } + } } diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/RestconfImpl.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/RestconfImpl.java index 7c4a7d5084..4abc492dff 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/RestconfImpl.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/RestconfImpl.java @@ -106,7 +106,7 @@ import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; -import org.opendaylight.yangtools.yang.parser.stmt.reactor.EffectiveSchemaContext; +import org.opendaylight.yangtools.yang.model.util.SimpleSchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -383,9 +383,7 @@ public class RestconfImpl implements RestconfService { neededModules.forEach(imp -> fakeModules.add(new FakeImportedModule(imp))); fakeModules.add(new FakeRestconfModule(neededModules, fakeCont)); - // FIXME: use a separate sublcass of AbstractSchemaContext - final SchemaContext fakeSchemaCtx = - EffectiveSchemaContext.resolveSchemaContext(ImmutableSet.copyOf(fakeModules)); + final SchemaContext fakeSchemaCtx = SimpleSchemaContext.forModules(ImmutableSet.copyOf(fakeModules)); final InstanceIdentifierContext instanceIdentifierContext = new InstanceIdentifierContext<>(null, fakeCont, mountPoint, fakeSchemaCtx); return new NormalizedNodeContext(instanceIdentifierContext, containerBuilder.build()); @@ -1264,7 +1262,7 @@ public class RestconfImpl implements RestconfService { * @return {@link URI} of location */ private URI dataSubs(final String identifier, final UriInfo uriInfo, final Instant start, final Instant stop, - final String filter, boolean leafNodesOnly) { + final String filter, final boolean leafNodesOnly) { final String streamName = Notificator.createStreamNameFromUri(identifier); if (Strings.isNullOrEmpty(streamName)) { throw new RestconfDocumentedException("Stream name is empty.", ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE); diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/AbstractNotificationsData.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/AbstractNotificationsData.java index 05e7785b14..f531a62a8d 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/AbstractNotificationsData.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/AbstractNotificationsData.java @@ -35,7 +35,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter; -import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaPath; diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/ListenerAdapter.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/ListenerAdapter.java index 8a2ab0511e..832aaf2481 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/ListenerAdapter.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/ListenerAdapter.java @@ -7,15 +7,16 @@ */ package org.opendaylight.netconf.sal.streams.listeners; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.google.common.base.Preconditions; +import com.google.common.base.Throwables; import java.io.IOException; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.xml.stream.XMLStreamException; import javax.xml.transform.dom.DOMResult; -import org.json.JSONObject; -import org.json.XML; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener; import org.opendaylight.netconf.sal.restconf.impl.ControllerContext; @@ -117,8 +118,13 @@ public class ListenerAdapter extends AbstractCommonSubscriber implements DOMData private void prepareAndPostData(final String xml) { final Event event = new Event(EventType.NOTIFY); if (this.outputType.equals(NotificationOutputType.JSON)) { - final JSONObject jsonObject = XML.toJSONObject(xml); - event.setData(jsonObject.toString()); + try { + JsonNode node = new XmlMapper().readTree(xml.getBytes()); + event.setData(node.toString()); + } catch (IOException e) { + LOG.error("Error parsing XML {}", xml, e); + Throwables.propagate(e); + } } else { event.setData(xml); } diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/NotificationListenerAdapter.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/NotificationListenerAdapter.java index cdf1ff2645..a5999ddfac 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/NotificationListenerAdapter.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/NotificationListenerAdapter.java @@ -9,6 +9,8 @@ package org.opendaylight.netconf.sal.streams.listeners; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; @@ -16,7 +18,6 @@ import java.time.Instant; import java.util.Collection; import javax.xml.stream.XMLStreamException; import javax.xml.transform.dom.DOMResult; -import org.json.JSONObject; import org.opendaylight.controller.md.sal.dom.api.DOMNotification; import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener; import org.opendaylight.netconf.sal.restconf.impl.ControllerContext; @@ -137,9 +138,10 @@ public class NotificationListenerAdapter extends AbstractCommonSubscriber implem */ @VisibleForTesting String prepareJson() { - final JSONObject json = new JSONObject(); - json.put("ietf-restconf:notification", - new JSONObject(writeBodyToString()).put("event-time", ListenerAdapter.toRFC3339(Instant.now()))); + JsonParser jsonParser = new JsonParser(); + JsonObject json = new JsonObject(); + json.add("ietf-restconf:notification", jsonParser.parse(writeBodyToString())); + json.addProperty("event-time", ListenerAdapter.toRFC3339(Instant.now())); return json.toString(); } diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/base/services/impl/RestconfOperationsServiceImpl.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/base/services/impl/RestconfOperationsServiceImpl.java index 62fc11e92b..5053db01ad 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/base/services/impl/RestconfOperationsServiceImpl.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/base/services/impl/RestconfOperationsServiceImpl.java @@ -35,7 +35,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.parser.stmt.reactor.EffectiveSchemaContext; +import org.opendaylight.yangtools.yang.model.util.SimpleSchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -129,9 +129,7 @@ public class RestconfOperationsServiceImpl implements RestconfOperationsService neededModules.forEach(imp -> fakeModules.add(new FakeImportedModule(imp))); fakeModules.add(new FakeRestconfModule(neededModules, fakeCont)); - // FIXME: use a separate sublcass of AbstractSchemaContext - final SchemaContext fakeSchemaCtx = - EffectiveSchemaContext.resolveSchemaContext(ImmutableSet.copyOf(fakeModules)); + final SchemaContext fakeSchemaCtx = SimpleSchemaContext.forModules(ImmutableSet.copyOf(fakeModules)); final InstanceIdentifierContext instanceIdentifierContext = new InstanceIdentifierContext<>(null, fakeCont, mountPoint, fakeSchemaCtx); return new NormalizedNodeContext(instanceIdentifierContext, containerBuilder.build()); diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/JsonToPatchBodyReader.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/JsonToPatchBodyReader.java index 45fd009600..11388dd7b1 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/JsonToPatchBodyReader.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/JsonToPatchBodyReader.java @@ -8,6 +8,7 @@ package org.opendaylight.restconf.jersey.providers; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; @@ -156,7 +157,7 @@ public class JsonToPatchBodyReader extends AbstractToPatchBodyReader { @Nonnull final StringModuleInstanceIdentifierCodec codec, @Nonnull final List resultCollection) throws IOException { switch (name) { - case "edit" : + case "edit": if (in.peek() == JsonToken.BEGIN_ARRAY) { in.beginArray(); @@ -174,7 +175,7 @@ public class JsonToPatchBodyReader extends AbstractToPatchBodyReader { } break; - case "patch-id" : + case "patch-id": this.patchId = in.nextString(); break; default: @@ -194,19 +195,19 @@ public class JsonToPatchBodyReader extends AbstractToPatchBodyReader { private void readEditDefinition(@Nonnull final PatchEdit edit, @Nonnull final JsonReader in, @Nonnull final InstanceIdentifierContext path, @Nonnull final StringModuleInstanceIdentifierCodec codec) throws IOException { - final StringBuilder sb = new StringBuilder(); + String deferredValue = null; in.beginObject(); while (in.hasNext()) { final String editDefinition = in.nextName(); switch (editDefinition) { - case "edit-id" : + case "edit-id": edit.setId(in.nextString()); break; - case "operation" : + case "operation": edit.setOperation(PatchEditOperation.valueOf(in.nextString().toUpperCase())); break; - case "target" : + case "target": // target can be specified completely in request URI final String target = in.nextString(); if (target.equals("/")) { @@ -220,21 +221,35 @@ public class JsonToPatchBodyReader extends AbstractToPatchBodyReader { } break; - case "value" : - // save data defined in value node for next (later) processing, because target needs to be read - // always first and there is no ordering in Json input - readValueNode(sb, in); + case "value": + Preconditions.checkArgument(edit.getData() == null && deferredValue == null, + "Multiple value entries found"); + + if (edit.getTargetSchemaNode() == null) { + final StringBuilder sb = new StringBuilder(); + + // save data defined in value node for next (later) processing, because target needs to be read + // always first and there is no ordering in Json input + readValueNode(sb, in); + deferredValue = sb.toString(); + } else { + // We have a target schema node, reuse this reader without buffering the value. + edit.setData(readEditData(in, edit.getTargetSchemaNode(), path)); + } break; default: + // FIXME: this does not look right, as it can wreck our logic break; } } in.endObject(); - // read saved data to normalized node when target schema is already known - edit.setData( - readEditData(new JsonReader(new StringReader(sb.toString())), edit.getTargetSchemaNode(), path)); + if (deferredValue != null) { + // read saved data to normalized node when target schema is already known + edit.setData(readEditData(new JsonReader(new StringReader(deferredValue)), edit.getTargetSchemaNode(), + path)); + } } /** @@ -392,47 +407,47 @@ public class JsonToPatchBodyReader extends AbstractToPatchBodyReader { private SchemaNode targetSchemaNode; private NormalizedNode data; - public String getId() { + String getId() { return id; } - public void setId(final String id) { - this.id = id; + void setId(final String id) { + this.id = Preconditions.checkNotNull(id); } - public PatchEditOperation getOperation() { + PatchEditOperation getOperation() { return operation; } - public void setOperation(final PatchEditOperation operation) { - this.operation = operation; + void setOperation(final PatchEditOperation operation) { + this.operation = Preconditions.checkNotNull(operation); } - public YangInstanceIdentifier getTarget() { + YangInstanceIdentifier getTarget() { return target; } - public void setTarget(final YangInstanceIdentifier target) { - this.target = target; + void setTarget(final YangInstanceIdentifier target) { + this.target = Preconditions.checkNotNull(target); } - public SchemaNode getTargetSchemaNode() { + SchemaNode getTargetSchemaNode() { return targetSchemaNode; } - public void setTargetSchemaNode(final SchemaNode targetSchemaNode) { - this.targetSchemaNode = targetSchemaNode; + void setTargetSchemaNode(final SchemaNode targetSchemaNode) { + this.targetSchemaNode = Preconditions.checkNotNull(targetSchemaNode); } - public NormalizedNode getData() { + NormalizedNode getData() { return data; } - public void setData(final NormalizedNode data) { - this.data = data; + void setData(final NormalizedNode data) { + this.data = Preconditions.checkNotNull(data); } - public void clear() { + void clear() { id = null; operation = null; target = null; diff --git a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/NormalizedNodeXmlBodyWriter.java b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/NormalizedNodeXmlBodyWriter.java index 9d66d80a15..e62de06547 100644 --- a/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/NormalizedNodeXmlBodyWriter.java +++ b/restconf/sal-rest-connector/src/main/java/org/opendaylight/restconf/jersey/providers/NormalizedNodeXmlBodyWriter.java @@ -38,7 +38,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; -import org.opendaylight.yangtools.yang.data.impl.codec.xml.XMLStreamNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; diff --git a/restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JSONRestconfServiceImplTest.java b/restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JSONRestconfServiceImplTest.java index f0b797c025..89d5412ef5 100644 --- a/restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JSONRestconfServiceImplTest.java +++ b/restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/JSONRestconfServiceImplTest.java @@ -29,13 +29,9 @@ import com.google.common.util.concurrent.Futures; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.HashSet; import java.util.List; import java.util.Map; -import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response.Status; -import javax.ws.rs.core.UriBuilder; -import javax.ws.rs.core.UriInfo; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -140,11 +136,7 @@ public class JSONRestconfServiceImplTest { when(result.getStatus()).thenReturn(Status.OK); final String uriPath = "ietf-interfaces:interfaces/interface/eth0"; final String payload = loadData("/parts/ietf-interfaces_interfaces.json"); - final UriInfo uriInfo = Mockito.mock(UriInfo.class); - final MultivaluedMap value = Mockito.mock(MultivaluedMap.class); - Mockito.when(value.entrySet()).thenReturn(new HashSet<>()); - Mockito.when(uriInfo.getQueryParameters()).thenReturn(value); - this.service.put(uriPath, payload, uriInfo); + this.service.put(uriPath, payload); final ArgumentCaptor capturedPath = ArgumentCaptor.forClass(YangInstanceIdentifier.class); @@ -178,11 +170,7 @@ public class JSONRestconfServiceImplTest { final String uriPath = "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont/cont1"; final String payload = loadData("/full-versions/testCont1Data.json"); - final UriInfo uriInfo = Mockito.mock(UriInfo.class); - final MultivaluedMap value = Mockito.mock(MultivaluedMap.class); - Mockito.when(value.entrySet()).thenReturn(new HashSet<>()); - Mockito.when(uriInfo.getQueryParameters()).thenReturn(value); - this.service.put(uriPath, payload, uriInfo); + this.service.put(uriPath, payload); final ArgumentCaptor capturedPath = ArgumentCaptor.forClass(YangInstanceIdentifier.class); @@ -214,11 +202,7 @@ public class JSONRestconfServiceImplTest { final String uriPath = "ietf-interfaces:interfaces/interface/eth0"; final String payload = loadData("/parts/ietf-interfaces_interfaces.json"); - final UriInfo uriInfo = Mockito.mock(UriInfo.class); - final MultivaluedMap value = Mockito.mock(MultivaluedMap.class); - Mockito.when(value.entrySet()).thenReturn(new HashSet<>()); - Mockito.when(uriInfo.getQueryParameters()).thenReturn(value); - this.service.put(uriPath, payload, uriInfo); + this.service.put(uriPath, payload); } @SuppressWarnings("rawtypes") @@ -231,13 +215,7 @@ public class JSONRestconfServiceImplTest { final String uriPath = null; final String payload = loadData("/parts/ietf-interfaces_interfaces_absolute_path.json"); - final UriInfo uriInfo = Mockito.mock(UriInfo.class); - final MultivaluedMap value = Mockito.mock(MultivaluedMap.class); - Mockito.when(value.entrySet()).thenReturn(new HashSet<>()); - Mockito.when(uriInfo.getQueryParameters()).thenReturn(value); - final UriBuilder uriBuilder = UriBuilder.fromPath(""); - Mockito.when(uriInfo.getBaseUriBuilder()).thenReturn(uriBuilder); - this.service.post(uriPath, payload, uriInfo); + this.service.post(uriPath, payload); final ArgumentCaptor capturedPath = ArgumentCaptor.forClass(YangInstanceIdentifier.class); @@ -278,13 +256,7 @@ public class JSONRestconfServiceImplTest { final String uriPath = "ietf-interfaces:interfaces/yang-ext:mount/test-module:cont"; final String payload = loadData("/full-versions/testCont1Data.json"); - final UriInfo uriInfo = Mockito.mock(UriInfo.class); - final MultivaluedMap value = Mockito.mock(MultivaluedMap.class); - Mockito.when(value.entrySet()).thenReturn(new HashSet<>()); - Mockito.when(uriInfo.getQueryParameters()).thenReturn(value); - final UriBuilder uriBuilder = UriBuilder.fromPath(""); - Mockito.when(uriInfo.getBaseUriBuilder()).thenReturn(uriBuilder); - this.service.post(uriPath, payload, uriInfo); + this.service.post(uriPath, payload); final ArgumentCaptor capturedPath = ArgumentCaptor.forClass(YangInstanceIdentifier.class); @@ -311,15 +283,8 @@ public class JSONRestconfServiceImplTest { final String uriPath = null; final String payload = loadData("/parts/ietf-interfaces_interfaces_absolute_path.json"); - final UriInfo uriInfo = Mockito.mock(UriInfo.class); - final MultivaluedMap value = Mockito.mock(MultivaluedMap.class); - Mockito.when(value.entrySet()).thenReturn(new HashSet<>()); - Mockito.when(uriInfo.getQueryParameters()).thenReturn(value); - final UriBuilder uriBuilder = UriBuilder.fromPath(""); - Mockito.when(uriInfo.getBaseUriBuilder()).thenReturn(uriBuilder); - try { - this.service.post(uriPath, payload, uriInfo); + this.service.post(uriPath, payload); } catch (final OperationFailedException e) { assertNotNull(e.getCause()); throw e.getCause(); @@ -365,21 +330,13 @@ public class JSONRestconfServiceImplTest { doReturn(null).when(brokerFacade).readConfigurationData(notNull(YangInstanceIdentifier.class), Mockito.anyString()); final String uriPath = "ietf-interfaces:interfaces"; - final UriInfo uriInfo = Mockito.mock(UriInfo.class); - final MultivaluedMap value = Mockito.mock(MultivaluedMap.class); - Mockito.when(value.entrySet()).thenReturn(new HashSet<>()); - Mockito.when(uriInfo.getQueryParameters()).thenReturn(value); - this.service.get(uriPath, LogicalDatastoreType.CONFIGURATION, uriInfo); + this.service.get(uriPath, LogicalDatastoreType.CONFIGURATION); } @Test(expected = OperationFailedException.class) public void testGetFailure() throws Exception { final String invalidUriPath = "/ietf-interfaces:interfaces/invalid"; - final UriInfo uriInfo = Mockito.mock(UriInfo.class); - final MultivaluedMap value = Mockito.mock(MultivaluedMap.class); - Mockito.when(value.entrySet()).thenReturn(new HashSet<>()); - Mockito.when(uriInfo.getQueryParameters()).thenReturn(value); - this.service.get(invalidUriPath, LogicalDatastoreType.CONFIGURATION, uriInfo); + this.service.get(invalidUriPath, LogicalDatastoreType.CONFIGURATION); } @SuppressWarnings("rawtypes") @@ -474,14 +431,8 @@ public class JSONRestconfServiceImplTest { } final String uriPath = "/ietf-interfaces:interfaces/interface/eth0"; - final UriInfo uriInfo = Mockito.mock(UriInfo.class); - final MultivaluedMap value = Mockito.mock(MultivaluedMap.class); - Mockito.when(value.entrySet()).thenReturn(new HashSet<>()); - Mockito.when(uriInfo.getQueryParameters()).thenReturn(value); - Mockito.when(uriInfo.getQueryParameters(false)).thenReturn(value); - Mockito.when(value.getFirst("depth")).thenReturn(""); - - final Optional optionalResp = this.service.get(uriPath, datastoreType, uriInfo); + + final Optional optionalResp = this.service.get(uriPath, datastoreType); assertEquals("Response present", true, optionalResp.isPresent()); final String jsonResp = optionalResp.get(); diff --git a/restconf/sal-rest-docgen/pom.xml b/restconf/sal-rest-docgen/pom.xml index 8a21e7e244..155351e36b 100644 --- a/restconf/sal-rest-docgen/pom.xml +++ b/restconf/sal-rest-docgen/pom.xml @@ -46,10 +46,6 @@ com.fasterxml.jackson.core jackson-databind - - com.fasterxml.jackson.datatype - jackson-datatype-json-org - com.google.guava @@ -62,11 +58,6 @@ jaxrs-api - - org.json - json - - org.opendaylight.controller sal-core-api @@ -133,9 +124,8 @@ MD SAL Rest Api Doc Generator generex, automaton - !org.apache.maven.plugin.logging, - !org.apache.maven.project, - !org.opendaylight.yangtools.yang2sources.spi, + + *, com.sun.jersey.spi.container.servlet, org.eclipse.jetty.servlets, @@ -145,8 +135,7 @@ org.apache.shiro.web.env - com.fasterxml.jackson.datatype.*, - org.json + com.fasterxml.jackson.datatype.* org.opendaylight.netconf.sal.rest.doc.DocProvider /apidoc @@ -163,4 +152,4 @@ - \ No newline at end of file + diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java index 2f22fa9a42..f5002e0371 100644 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java @@ -7,13 +7,14 @@ */ package org.opendaylight.netconf.sal.rest.doc.impl; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; import java.io.ByteArrayOutputStream; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.Map.Entry; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; -import org.json.JSONWriter; import org.opendaylight.netconf.sal.rest.doc.api.ApiDocService; import org.opendaylight.netconf.sal.rest.doc.mountpoints.MountPointSwagger; import org.opendaylight.netconf.sal.rest.doc.swagger.ApiDeclaration; @@ -86,16 +87,16 @@ public class ApiDocServiceImpl implements ApiDocService { public synchronized Response getListOfMounts(final UriInfo uriInfo) { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (OutputStreamWriter streamWriter = new OutputStreamWriter(baos, StandardCharsets.UTF_8)) { - final JSONWriter writer = new JSONWriter(streamWriter); - writer.array(); + JsonGenerator writer = new JsonFactory().createGenerator(streamWriter); + writer.writeStartArray(); for (final Entry entry : MountPointSwagger.getInstance().getInstanceIdentifiers() .entrySet()) { - writer.object(); - writer.key("instance").value(entry.getKey()); - writer.key("id").value(entry.getValue()); - writer.endObject(); + writer.writeStartObject(); + writer.writeObjectField("instance", entry.getKey()); + writer.writeObjectField("id", entry.getValue()); + writer.writeEndObject(); } - writer.endArray(); + writer.writeEndArray(); } catch (final Exception e) { return Response.status(500).entity(e.getMessage()).build(); } diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java index 7ffc4c5816..91612c1eac 100644 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java @@ -11,7 +11,7 @@ import static org.opendaylight.netconf.sal.rest.doc.util.RestDocgenUtil.resolveP import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.base.Preconditions; import java.io.IOException; import java.net.URI; @@ -28,8 +28,6 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.ws.rs.core.UriInfo; -import org.json.JSONException; -import org.json.JSONObject; import org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder; import org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.Delete; import org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.Get; @@ -72,7 +70,6 @@ public class BaseYangSwaggerGenerator { private static boolean newDraft; protected BaseYangSwaggerGenerator() { - this.mapper.registerModule(new JsonOrgModule()); this.mapper.configure(SerializationFeature.INDENT_OUTPUT, true); } @@ -231,7 +228,7 @@ public class BaseYangSwaggerGenerator { if (!apis.isEmpty()) { doc.setApis(apis); - JSONObject models = null; + ObjectNode models = null; try { models = this.jsonConverter.convertToJsonSchema(module, schemaContext); @@ -239,7 +236,7 @@ public class BaseYangSwaggerGenerator { if (LOG.isDebugEnabled()) { LOG.debug(this.mapper.writeValueAsString(doc)); } - } catch (IOException | JSONException e) { + } catch (IOException e) { LOG.error("Exception occured in ModelGenerator", e); } diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ModelGenerator.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ModelGenerator.java index f4ba8d4189..5149200a09 100644 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ModelGenerator.java +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ModelGenerator.java @@ -9,17 +9,18 @@ package org.opendaylight.netconf.sal.rest.doc.impl; import static org.opendaylight.netconf.sal.rest.doc.util.RestDocgenUtil.resolveNodesName; -import com.google.common.base.Optional; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.JsonNodeFactory; +import com.fasterxml.jackson.databind.node.NullNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.databind.node.TextNode; import com.mifmif.common.regex.Generex; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.regex.Pattern; import javax.annotation.concurrent.NotThreadSafe; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; import org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder; import org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.Post; import org.opendaylight.yangtools.yang.common.QName; @@ -103,14 +104,13 @@ public class ModelGenerator { * * @param module - Yang module to be converted * @param schemaContext - SchemaContext of all Yang files used by Api Doc - * @return JSONObject containing data used for creating examples and models in Api Doc + * @return ObjectNode containing data used for creating examples and models in Api Doc * @throws IOException if I/O operation fails - * @throws JSONException when things are amiss */ - public JSONObject convertToJsonSchema(final Module module, - final SchemaContext schemaContext) throws IOException, JSONException { - final JSONObject models = new JSONObject(); - models.put(UNIQUE_EMPTY_IDENTIFIER, new JSONObject()); + public ObjectNode convertToJsonSchema(final Module module, + final SchemaContext schemaContext) throws IOException { + final ObjectNode models = JsonNodeFactory.instance.objectNode(); + models.put(UNIQUE_EMPTY_IDENTIFIER, NullNode.getInstance()); topLevelModule = module; processModules(module, models, schemaContext); processContainersAndLists(module, models, schemaContext); @@ -119,14 +119,14 @@ public class ModelGenerator { return models; } - private void processModules(final Module module, final JSONObject models, - final SchemaContext schemaContext) throws JSONException { + private void processModules(final Module module, final ObjectNode models, + final SchemaContext schemaContext) { createConcreteModelForPost(models, module.getName() + BaseYangSwaggerGenerator.MODULE_NAME_SUFFIX, createPropertiesForPost(module, schemaContext, module.getName())); } - private void processContainersAndLists(final Module module, final JSONObject models, - final SchemaContext schemaContext) throws IOException, JSONException { + private void processContainersAndLists(final Module module, final ObjectNode models, + final SchemaContext schemaContext) throws IOException { final String moduleName = module.getName(); for (final DataSchemaNode childNode : module.getChildNodes()) { @@ -144,22 +144,20 @@ public class ModelGenerator { * for each RPC that contains input & output elements. * * @param module module - * @throws JSONException when things are amiss * @throws IOException if I/O operation fails */ - private void processRPCs(final Module module, final JSONObject models, - final SchemaContext schemaContext) throws JSONException, - IOException { + private void processRPCs(final Module module, final ObjectNode models, + final SchemaContext schemaContext) throws IOException { final Set rpcs = module.getRpcs(); final String moduleName = module.getName(); for (final RpcDefinition rpc : rpcs) { final ContainerSchemaNode input = rpc.getInput(); if (!input.getChildNodes().isEmpty()) { - final JSONObject properties = + final ObjectNode properties = processChildren(input.getChildNodes(), moduleName, models, true, schemaContext); final String filename = "(" + rpc.getQName().getLocalName() + ")input"; - final JSONObject childSchema = getSchemaTemplate(); + final ObjectNode childSchema = getSchemaTemplate(); childSchema.put(TYPE_KEY, OBJECT_TYPE); childSchema.put(PROPERTIES_KEY, properties); childSchema.put(ID_KEY, filename); @@ -170,10 +168,10 @@ public class ModelGenerator { final ContainerSchemaNode output = rpc.getOutput(); if (!output.getChildNodes().isEmpty()) { - final JSONObject properties = + final ObjectNode properties = processChildren(output.getChildNodes(), moduleName, models, true, schemaContext); final String filename = "(" + rpc.getQName().getLocalName() + ")output"; - final JSONObject childSchema = getSchemaTemplate(); + final ObjectNode childSchema = getSchemaTemplate(); childSchema.put(TYPE_KEY, OBJECT_TYPE); childSchema.put(PROPERTIES_KEY, properties); childSchema.put(ID_KEY, filename); @@ -184,18 +182,18 @@ public class ModelGenerator { } } - private JSONObject processTopData(final String filename, final JSONObject models, final SchemaNode schemaNode) { - final JSONObject items = new JSONObject(); + private ObjectNode processTopData(final String filename, final ObjectNode models, final SchemaNode schemaNode) { + final ObjectNode items = JsonNodeFactory.instance.objectNode(); items.put(REF_KEY, filename); - final JSONObject dataNodeProperties = new JSONObject(); + final ObjectNode dataNodeProperties = JsonNodeFactory.instance.objectNode(); dataNodeProperties.put(TYPE_KEY, schemaNode instanceof ListSchemaNode ? ARRAY_TYPE : OBJECT_TYPE); dataNodeProperties.put(ITEMS_KEY, items); - dataNodeProperties.putOpt(DESCRIPTION_KEY, schemaNode.getDescription()); - final JSONObject properties = new JSONObject(); + putIfNonNull(dataNodeProperties, DESCRIPTION_KEY, schemaNode.getDescription()); + final ObjectNode properties = JsonNodeFactory.instance.objectNode(); properties.put(topLevelModule.getName() + ":" + schemaNode.getQName().getLocalName(), dataNodeProperties); - final JSONObject finalChildSchema = getSchemaTemplate(); + final ObjectNode finalChildSchema = getSchemaTemplate(); finalChildSchema.put(TYPE_KEY, OBJECT_TYPE); finalChildSchema.put(PROPERTIES_KEY, properties); finalChildSchema.put(ID_KEY, filename + OperationBuilder.TOP); @@ -208,42 +206,42 @@ public class ModelGenerator { * Processes the 'identity' statement in a yang model and maps it to a 'model' in the Swagger JSON spec. * * @param module The module from which the identity stmt will be processed - * @param models The JSONObject in which the parsed identity will be put as a 'model' obj + * @param models The ObjectNode in which the parsed identity will be put as a 'model' obj */ - private static void processIdentities(final Module module, final JSONObject models) throws JSONException { + private static void processIdentities(final Module module, final ObjectNode models) { final String moduleName = module.getName(); final Set idNodes = module.getIdentities(); LOG.debug("Processing Identities for module {} . Found {} identity statements", moduleName, idNodes.size()); for (final IdentitySchemaNode idNode : idNodes) { - final JSONObject identityObj = new JSONObject(); + final ObjectNode identityObj = JsonNodeFactory.instance.objectNode(); final String identityName = idNode.getQName().getLocalName(); LOG.debug("Processing Identity: {}", identityName); identityObj.put(ID_KEY, identityName); - identityObj.put(DESCRIPTION_KEY, idNode.getDescription()); + putIfNonNull(identityObj, DESCRIPTION_KEY, idNode.getDescription()); - final JSONObject props = new JSONObject(); + final ObjectNode props = JsonNodeFactory.instance.objectNode(); final IdentitySchemaNode baseId = idNode.getBaseIdentity(); if (baseId == null) { - /** + /* * This is a base identity. So lets see if it has sub types. If it does, then add them to the model * definition. */ final Set derivedIds = idNode.getDerivedIdentities(); if (derivedIds != null) { - final JSONArray subTypes = new JSONArray(); + final ArrayNode subTypes = new ArrayNode(JsonNodeFactory.instance); for (final IdentitySchemaNode derivedId : derivedIds) { - subTypes.put(derivedId.getQName().getLocalName()); + subTypes.add(derivedId.getQName().getLocalName()); } identityObj.put(SUB_TYPES_KEY, subTypes); } } else { - /** + /* * This is a derived entity. Add it's base type & move on. */ props.put(TYPE_KEY, baseId.getQName().getLocalName()); @@ -255,18 +253,18 @@ public class ModelGenerator { } } - private JSONObject processDataNodeContainer( - final DataNodeContainer dataNode, final String parentName, final JSONObject models, final boolean isConfig, - final SchemaContext schemaContext) throws JSONException, IOException { + private ObjectNode processDataNodeContainer( + final DataNodeContainer dataNode, final String parentName, final ObjectNode models, final boolean isConfig, + final SchemaContext schemaContext) throws IOException { if (dataNode instanceof ListSchemaNode || dataNode instanceof ContainerSchemaNode) { final Iterable containerChildren = dataNode.getChildNodes(); final String localName = ((SchemaNode) dataNode).getQName().getLocalName(); - final JSONObject properties = + final ObjectNode properties = processChildren(containerChildren, parentName + "/" + localName, models, isConfig, schemaContext); final String nodeName = parentName + (isConfig ? OperationBuilder.CONFIG : OperationBuilder.OPERATIONAL) + localName; - final JSONObject childSchema = getSchemaTemplate(); + final ObjectNode childSchema = getSchemaTemplate(); childSchema.put(TYPE_KEY, OBJECT_TYPE); childSchema.put(PROPERTIES_KEY, properties); @@ -283,30 +281,29 @@ public class ModelGenerator { return null; } - private static void createConcreteModelForPost(final JSONObject models, final String localName, - final JSONObject properties) throws JSONException { + private static void createConcreteModelForPost(final ObjectNode models, final String localName, + final JsonNode properties) { final String nodePostName = OperationBuilder.CONFIG + localName + Post.METHOD_NAME; - final JSONObject postSchema = getSchemaTemplate(); + final ObjectNode postSchema = getSchemaTemplate(); postSchema.put(TYPE_KEY, OBJECT_TYPE); postSchema.put(ID_KEY, nodePostName); postSchema.put(PROPERTIES_KEY, properties); models.put(nodePostName, postSchema); } - private JSONObject createPropertiesForPost(final DataNodeContainer dataNodeContainer, - final SchemaContext schemaContext, final String parentName) - throws JSONException { - final JSONObject properties = new JSONObject(); + private JsonNode createPropertiesForPost(final DataNodeContainer dataNodeContainer, + final SchemaContext schemaContext, final String parentName) { + final ObjectNode properties = JsonNodeFactory.instance.objectNode(); for (final DataSchemaNode childNode : dataNodeContainer.getChildNodes()) { if (childNode instanceof ListSchemaNode || childNode instanceof ContainerSchemaNode) { - final JSONObject items = new JSONObject(); + final ObjectNode items = JsonNodeFactory.instance.objectNode(); items.put(REF_KEY, parentName + "(config)" + childNode.getQName().getLocalName()); - final JSONObject property = new JSONObject(); + final ObjectNode property = JsonNodeFactory.instance.objectNode(); property.put(TYPE_KEY, childNode instanceof ListSchemaNode ? ARRAY_TYPE : OBJECT_TYPE); property.put(ITEMS_KEY, items); properties.put(childNode.getQName().getLocalName(), property); } else if (childNode instanceof LeafSchemaNode) { - final JSONObject property = processLeafNode((LeafSchemaNode) childNode, schemaContext); + final ObjectNode property = processLeafNode((LeafSchemaNode) childNode, schemaContext); properties.put(childNode.getQName().getLocalName(), property); } } @@ -316,15 +313,14 @@ public class ModelGenerator { /** * Processes the nodes. */ - private JSONObject processChildren( - final Iterable nodes, final String parentName, final JSONObject models, - final boolean isConfig, final SchemaContext schemaContext) - throws JSONException, IOException { - final JSONObject properties = new JSONObject(); + private ObjectNode processChildren( + final Iterable nodes, final String parentName, final ObjectNode models, + final boolean isConfig, final SchemaContext schemaContext) throws IOException { + final ObjectNode properties = JsonNodeFactory.instance.objectNode(); for (final DataSchemaNode node : nodes) { if (node.isConfiguration() == isConfig) { final String name = resolveNodesName(node, topLevelModule, schemaContext); - final JSONObject property; + final ObjectNode property; if (node instanceof LeafSchemaNode) { property = processLeafNode((LeafSchemaNode) node, schemaContext); @@ -352,22 +348,22 @@ public class ModelGenerator { } else { throw new IllegalArgumentException("Unknown DataSchemaNode type: " + node.getClass()); } - property.putOpt(DESCRIPTION_KEY, node.getDescription()); + putIfNonNull(property, DESCRIPTION_KEY, node.getDescription()); properties.put(topLevelModule.getName() + ":" + name, property); } } return properties; } - private JSONObject processLeafListNode(final LeafListSchemaNode listNode, - final SchemaContext schemaContext) throws JSONException { - final JSONObject props = new JSONObject(); + private ObjectNode processLeafListNode(final LeafListSchemaNode listNode, + final SchemaContext schemaContext) { + final ObjectNode props = JsonNodeFactory.instance.objectNode(); props.put(TYPE_KEY, ARRAY_TYPE); - final JSONObject itemsVal = new JSONObject(); + final ObjectNode itemsVal = JsonNodeFactory.instance.objectNode(); final ConstraintDefinition constraints = listNode.getConstraints(); - final Optional maxOptional = Optional.fromNullable(constraints.getMaxElements()); - if (maxOptional.or(2) >= 2) { + int max = constraints.getMaxElements() == null ? 2 : constraints.getMaxElements(); + if (max >= 2) { processTypeDef(listNode.getType(), listNode, itemsVal, schemaContext); processTypeDef(listNode.getType(), listNode, itemsVal, schemaContext); } else { @@ -382,12 +378,12 @@ public class ModelGenerator { } private void processChoiceNode( - final Iterable nodes, final String moduleName, final JSONObject models, - final SchemaContext schemaContext, final boolean isConfig, final JSONObject properties) - throws JSONException, IOException { + final Iterable nodes, final String moduleName, final ObjectNode models, + final SchemaContext schemaContext, final boolean isConfig, final ObjectNode properties) + throws IOException { for (final DataSchemaNode node : nodes) { final String name = resolveNodesName(node, topLevelModule, schemaContext); - final JSONObject property; + final ObjectNode property; if (node instanceof LeafSchemaNode) { property = processLeafNode((LeafSchemaNode) node, schemaContext); @@ -417,13 +413,13 @@ public class ModelGenerator { throw new IllegalArgumentException("Unknown DataSchemaNode type: " + node.getClass()); } - property.putOpt(DESCRIPTION_KEY, node.getDescription()); + putIfNonNull(property, DESCRIPTION_KEY, node.getDescription()); properties.put(name, property); } } private static void processConstraints(final ConstraintDefinition constraints, - final JSONObject props) throws JSONException { + final ObjectNode props) { final boolean isMandatory = constraints.isMandatory(); props.put(REQUIRED_KEY, isMandatory); @@ -437,23 +433,23 @@ public class ModelGenerator { } } - private JSONObject processLeafNode(final LeafSchemaNode leafNode, - final SchemaContext schemaContext) throws JSONException { - final JSONObject property = new JSONObject(); + private ObjectNode processLeafNode(final LeafSchemaNode leafNode, + final SchemaContext schemaContext) { + final ObjectNode property = JsonNodeFactory.instance.objectNode(); final String leafDescription = leafNode.getDescription(); - property.put(DESCRIPTION_KEY, leafDescription); + putIfNonNull(property, DESCRIPTION_KEY, leafDescription); processConstraints(leafNode.getConstraints(), property); processTypeDef(leafNode.getType(), leafNode, property, schemaContext); return property; } - private static JSONObject processAnyXMLNode(final AnyXmlSchemaNode leafNode) throws JSONException { - final JSONObject property = new JSONObject(); + private static ObjectNode processAnyXMLNode(final AnyXmlSchemaNode leafNode) { + final ObjectNode property = JsonNodeFactory.instance.objectNode(); final String leafDescription = leafNode.getDescription(); - property.put(DESCRIPTION_KEY, leafDescription); + putIfNonNull(property, DESCRIPTION_KEY, leafDescription); processConstraints(leafNode.getConstraints(), property); final String localName = leafNode.getQName().getLocalName(); @@ -463,7 +459,7 @@ public class ModelGenerator { } private String processTypeDef(final TypeDefinition leafTypeDef, final DataSchemaNode node, - final JSONObject property, final SchemaContext schemaContext) throws JSONException { + final ObjectNode property, final SchemaContext schemaContext) { final String jsonType; if (leafTypeDef.getDefaultValue() == null) { if (leafTypeDef instanceof BinaryTypeDefinition) { @@ -514,11 +510,11 @@ public class ModelGenerator { } else { jsonType = String.valueOf(leafTypeDef.getDefaultValue()); } - property.putOpt(TYPE_KEY, jsonType); + putIfNonNull(property, TYPE_KEY, jsonType); return jsonType; } - private String processLeafRef(final DataSchemaNode node, final JSONObject property, + private String processLeafRef(final DataSchemaNode node, final ObjectNode property, final SchemaContext schemaContext, final TypeDefinition leafTypeDef) { RevisionAwareXPath xpath = ((LeafrefTypeDefinition) leafTypeDef).getPathStatement(); final SchemaNode schemaNode; @@ -544,42 +540,41 @@ public class ModelGenerator { .findModuleByNamespaceAndRevision(qualifiedName.getNamespace(), qualifiedName.getRevision()); } - private static String processBinaryType(final JSONObject property) throws JSONException { - final JSONObject media = new JSONObject(); + private static String processBinaryType(final ObjectNode property) { + final ObjectNode media = JsonNodeFactory.instance.objectNode(); media.put(BINARY_ENCODING_KEY, BASE_64); property.put(MEDIA_KEY, media); return "bin1 bin2"; } private static String processEnumType(final EnumTypeDefinition enumLeafType, - final JSONObject property) throws JSONException { + final ObjectNode property) { final List enumPairs = enumLeafType.getValues(); - final List enumNames = new ArrayList<>(); + ArrayNode enumNames = new ArrayNode(JsonNodeFactory.instance); for (final EnumPair enumPair : enumPairs) { - enumNames.add(enumPair.getName()); + enumNames.add(new TextNode(enumPair.getName())); } - property.putOpt(ENUM, new JSONArray(enumNames)); + property.put(ENUM, enumNames); return enumLeafType.getValues().iterator().next().getName(); } private static String processBitsType(final BitsTypeDefinition bitsType, - final JSONObject property) throws JSONException { + final ObjectNode property) { property.put(MIN_ITEMS, 0); property.put(UNIQUE_ITEMS_KEY, true); - final List enumNames = new ArrayList<>(); + ArrayNode enumNames = new ArrayNode(JsonNodeFactory.instance); final List bits = bitsType.getBits(); for (final Bit bit : bits) { - enumNames.add(bit.getName()); + enumNames.add(new TextNode(bit.getName())); } - property.put(ENUM, new JSONArray(enumNames)); + property.put(ENUM, enumNames); return enumNames.iterator().next() + " " + enumNames.get(enumNames.size() - 1); } private static String processStringType(final TypeDefinition stringType, - final JSONObject property, final String nodeName) - throws JSONException { + final ObjectNode property, final String nodeName) { StringTypeDefinition type = (StringTypeDefinition) stringType; List lengthConstraints = ((StringTypeDefinition) stringType).getLengthConstraints(); while (lengthConstraints.isEmpty() && type.getBaseType() != null) { @@ -592,8 +587,8 @@ public class ModelGenerator { for (final LengthConstraint lengthConstraint : lengthConstraints) { final Number min = lengthConstraint.getMin(); final Number max = lengthConstraint.getMax(); - property.putOpt(MIN_LENGTH_KEY, min); - property.putOpt(MAX_LENGTH_KEY, max); + putIfNonNull(property, MIN_LENGTH_KEY, min); + putIfNonNull(property, MAX_LENGTH_KEY, max); } if (type.getPatternConstraints().iterator().hasNext()) { final PatternConstraint pattern = type.getPatternConstraints().iterator().next(); @@ -606,25 +601,46 @@ public class ModelGenerator { } } - private String processUnionType(final UnionTypeDefinition unionType, final JSONObject property, - final SchemaContext schemaContext, final DataSchemaNode node) - throws JSONException { - final List unionNames = new ArrayList<>(); + private String processUnionType(final UnionTypeDefinition unionType, final ObjectNode property, + final SchemaContext schemaContext, final DataSchemaNode node) { + final ArrayNode unionNames = new ArrayNode(JsonNodeFactory.instance); for (final TypeDefinition typeDef : unionType.getTypes()) { unionNames.add(processTypeDef(typeDef, node, property, schemaContext)); } - property.put(ENUM, new JSONArray(unionNames)); - return unionNames.iterator().next(); + property.put(ENUM, unionNames); + return unionNames.iterator().next().asText(); } /** * Helper method to generate a pre-filled JSON schema object. */ - private static JSONObject getSchemaTemplate() throws JSONException { - final JSONObject schemaJSON = new JSONObject(); + private static ObjectNode getSchemaTemplate() { + final ObjectNode schemaJSON = JsonNodeFactory.instance.objectNode(); schemaJSON.put(SCHEMA_KEY, SCHEMA_URL); return schemaJSON; } + private static void putIfNonNull(ObjectNode property, String key, Number number) { + if (key != null && number != null) { + if (number instanceof Double) { + property.put(key, (Double) number); + } else if (number instanceof Float) { + property.put(key, (Float) number); + } else if (number instanceof Integer) { + property.put(key, (Integer) number); + } else if (number instanceof Short) { + property.put(key, (Short) number); + } else if (number instanceof Long) { + property.put(key, (Long) number); + } + } + } + + private static void putIfNonNull(ObjectNode property, String key, String value) { + if (key != null && value != null) { + property.put(key, value); + } + } + } \ No newline at end of file diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/JaxbContextResolver.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/JaxbContextResolver.java index de8c5bc501..a8baa7774c 100644 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/JaxbContextResolver.java +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/JaxbContextResolver.java @@ -9,7 +9,6 @@ package org.opendaylight.netconf.sal.rest.doc.jaxrs; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @@ -26,7 +25,6 @@ public class JaxbContextResolver implements ContextResolver { public JaxbContextResolver() { ctx = new ObjectMapper(); - ctx.registerModule(new JsonOrgModule()); ctx.getSerializationConfig().withSerializationInclusion(JsonInclude.Include.ALWAYS); } diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/swagger/ApiDeclaration.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/swagger/ApiDeclaration.java index 3d735ac2f6..00c6de8fe3 100644 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/swagger/ApiDeclaration.java +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/swagger/ApiDeclaration.java @@ -7,8 +7,8 @@ */ package org.opendaylight.netconf.sal.rest.doc.swagger; +import com.fasterxml.jackson.databind.node.ObjectNode; import java.util.List; -import org.json.JSONObject; /** * Implementation of swagger spec (see produces; private List apis; - private JSONObject models; + private ObjectNode models; - public JSONObject getModels() { + public ObjectNode getModels() { return models; } - public void setModels(JSONObject models) { + public void setModels(ObjectNode models) { this.models = models; } @@ -86,6 +86,6 @@ public class ApiDeclaration { } public boolean hasModel() { - return (models != null && models.length() > 0); + return (models != null && models.size() > 0); } } diff --git a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java index 91cbcec2c7..50fe6b6225 100644 --- a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java +++ b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java @@ -13,6 +13,8 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.base.Preconditions; import java.sql.Date; import java.util.Arrays; @@ -21,8 +23,6 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; import javax.ws.rs.core.UriInfo; -import org.json.JSONException; -import org.json.JSONObject; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -164,72 +164,67 @@ public class ApiDocGeneratorTest { * Validates whether doc {@code doc} contains concrete specified models. */ private void validateSwaggerModules(final ApiDeclaration doc) { - final JSONObject models = doc.getModels(); + final ObjectNode models = doc.getModels(); assertNotNull(models); - try { - final JSONObject configLstTop = models.getJSONObject("toaster2(config)lst-TOP"); - assertNotNull(configLstTop); - containsReferences(configLstTop, "toaster2:lst", "toaster2(config)"); + final JsonNode configLstTop = models.get("toaster2(config)lst-TOP"); + assertNotNull(configLstTop); - final JSONObject configLst = models.getJSONObject("toaster2(config)lst"); - assertNotNull(configLst); + containsReferences(configLstTop, "toaster2:lst", "toaster2(config)"); - containsReferences(configLst, "toaster2:lst1", "toaster2/lst(config)"); - containsReferences(configLst, "toaster2:cont1", "toaster2/lst(config)"); + final JsonNode configLst = models.get("toaster2(config)lst"); + assertNotNull(configLst); - final JSONObject configLst1Top = models.getJSONObject("toaster2/lst(config)lst1-TOP"); - assertNotNull(configLst1Top); + containsReferences(configLst, "toaster2:lst1", "toaster2/lst(config)"); + containsReferences(configLst, "toaster2:cont1", "toaster2/lst(config)"); - containsReferences(configLst1Top, "toaster2:lst1", "toaster2/lst(config)"); + final JsonNode configLst1Top = models.get("toaster2/lst(config)lst1-TOP"); + assertNotNull(configLst1Top); - final JSONObject configLst1 = models.getJSONObject("toaster2/lst(config)lst1"); - assertNotNull(configLst1); + containsReferences(configLst1Top, "toaster2:lst1", "toaster2/lst(config)"); - final JSONObject configCont1Top = models.getJSONObject("toaster2/lst(config)cont1-TOP"); - assertNotNull(configCont1Top); + final JsonNode configLst1 = models.get("toaster2/lst(config)lst1"); + assertNotNull(configLst1); - containsReferences(configCont1Top, "toaster2:cont1", "toaster2/lst(config)"); - final JSONObject configCont1 = models.getJSONObject("toaster2/lst(config)cont1"); - assertNotNull(configCont1); + final JsonNode configCont1Top = models.get("toaster2/lst(config)cont1-TOP"); + assertNotNull(configCont1Top); - containsReferences(configCont1, "toaster2:cont11", "toaster2/lst/cont1(config)"); - containsReferences(configCont1, "toaster2:lst11", "toaster2/lst/cont1(config)"); + containsReferences(configCont1Top, "toaster2:cont1", "toaster2/lst(config)"); + final JsonNode configCont1 = models.get("toaster2/lst(config)cont1"); + assertNotNull(configCont1); - final JSONObject configCont11Top = models.getJSONObject("toaster2/lst/cont1(config)cont11-TOP"); - assertNotNull(configCont11Top); + containsReferences(configCont1, "toaster2:cont11", "toaster2/lst/cont1(config)"); + containsReferences(configCont1, "toaster2:lst11", "toaster2/lst/cont1(config)"); - containsReferences(configCont11Top, "toaster2:cont11", "toaster2/lst/cont1(config)"); - final JSONObject configCont11 = models.getJSONObject("toaster2/lst/cont1(config)cont11"); - assertNotNull(configCont11); + final JsonNode configCont11Top = models.get("toaster2/lst/cont1(config)cont11-TOP"); + assertNotNull(configCont11Top); - final JSONObject configlst11Top = models.getJSONObject("toaster2/lst/cont1(config)lst11-TOP"); - assertNotNull(configlst11Top); + containsReferences(configCont11Top, "toaster2:cont11", "toaster2/lst/cont1(config)"); + final JsonNode configCont11 = models.get("toaster2/lst/cont1(config)cont11"); + assertNotNull(configCont11); - containsReferences(configlst11Top, "toaster2:lst11", "toaster2/lst/cont1(config)"); - final JSONObject configLst11 = models.getJSONObject("toaster2/lst/cont1(config)lst11"); - assertNotNull(configLst11); - } catch (final JSONException e) { - fail("JSONException wasn't expected"); - } + final JsonNode configlst11Top = models.get("toaster2/lst/cont1(config)lst11-TOP"); + assertNotNull(configlst11Top); + containsReferences(configlst11Top, "toaster2:lst11", "toaster2/lst/cont1(config)"); + final JsonNode configLst11 = models.get("toaster2/lst/cont1(config)lst11"); + assertNotNull(configLst11); } /** * Checks whether object {@code mainObject} contains in properties/items key $ref with concrete value. */ - private void containsReferences(final JSONObject mainObject, final String childObject, final String prefix) - throws JSONException { - final JSONObject properties = mainObject.getJSONObject("properties"); + private void containsReferences(final JsonNode mainObject, final String childObject, final String prefix) { + final JsonNode properties = mainObject.get("properties"); assertNotNull(properties); - final JSONObject nodeInProperties = properties.getJSONObject(childObject); + final JsonNode nodeInProperties = properties.get(childObject); assertNotNull(nodeInProperties); - final JSONObject itemsInNodeInProperties = nodeInProperties.getJSONObject("items"); + final JsonNode itemsInNodeInProperties = nodeInProperties.get("items"); assertNotNull(itemsInNodeInProperties); - final String itemRef = itemsInNodeInProperties.getString("$ref"); + final String itemRef = itemsInNodeInProperties.get("$ref").asText(); assertEquals(prefix + childObject.split(":")[1], itemRef); } @@ -246,7 +241,7 @@ public class ApiDocGeneratorTest { // testing bugs.opendaylight.org bug 1290. UnionType model type. final String jsonString = doc.getModels().toString(); - assertTrue(jsonString.contains("testUnion\":{\"type\":\"-2147483648\",\"required\":false," + assertTrue(jsonString.contains("testUnion\":{\"required\":false,\"type\":\"-2147483648\"," + "\"enum\":[\"-2147483648\",\"Some testUnion\"]}")); } } @@ -263,13 +258,13 @@ public class ApiDocGeneratorTest { this.schemaContext); assertNotNull(doc); - final JSONObject models = doc.getModels(); - final JSONObject inputTop = models.getJSONObject("(make-toast)input-TOP"); + final ObjectNode models = doc.getModels(); + final JsonNode inputTop = models.get("(make-toast)input-TOP"); final String testString = "{\"toaster:input\":{\"type\":\"object\",\"items\":{\"$ref\":\"(make-toast)input\"}}}"; - assertEquals(testString, inputTop.getJSONObject("properties").toString()); - final JSONObject input = models.getJSONObject("(make-toast)input"); - final JSONObject properties = input.getJSONObject("properties"); + assertEquals(testString, inputTop.get("properties").toString()); + final JsonNode input = models.get("(make-toast)input"); + final JsonNode properties = input.get("properties"); assertTrue(properties.has("toaster:toasterDoneness")); assertTrue(properties.has("toaster:toasterToastType")); } @@ -322,7 +317,7 @@ public class ApiDocGeneratorTest { // TODO: we should really do some more validation of the // documentation... - /** + /* * Missing validation: Explicit validation of URLs, and their methods Input / output models. */ } @@ -355,28 +350,24 @@ public class ApiDocGeneratorTest { } private void validateTosterDocContainsModulePrefixes(final ApiDeclaration doc) { - final JSONObject topLevelJson = doc.getModels(); - try { - final JSONObject configToaster = topLevelJson.getJSONObject("toaster2(config)toaster"); - assertNotNull("(config)toaster JSON object missing", configToaster); - // without module prefix - containsProperties(configToaster, "toaster2:toasterSlot"); - - final JSONObject toasterSlot = topLevelJson.getJSONObject("toaster2/toaster(config)toasterSlot"); - assertNotNull("(config)toasterSlot JSON object missing", toasterSlot); - // with module prefix - containsProperties(toasterSlot, "toaster2:toaster-augmented:slotInfo"); - - } catch (final JSONException e) { - fail("Json exception while reading JSON object. Original message " + e.getMessage()); - } + final ObjectNode topLevelJson = doc.getModels(); + + final JsonNode configToaster = topLevelJson.get("toaster2(config)toaster"); + assertNotNull("(config)toaster JSON object missing", configToaster); + // without module prefix + containsProperties(configToaster, "toaster2:toasterSlot"); + + final JsonNode toasterSlot = topLevelJson.get("toaster2/toaster(config)toasterSlot"); + assertNotNull("(config)toasterSlot JSON object missing", toasterSlot); + // with module prefix + containsProperties(toasterSlot, "toaster2:toaster-augmented:slotInfo"); } - private void containsProperties(final JSONObject jsonObject, final String... properties) throws JSONException { + private void containsProperties(final JsonNode jsonObject, final String... properties) { for (final String property : properties) { - final JSONObject propertiesObject = jsonObject.getJSONObject("properties"); + final JsonNode propertiesObject = jsonObject.get("properties"); assertNotNull("Properties object missing in ", propertiesObject); - final JSONObject concretePropertyObject = propertiesObject.getJSONObject(property); + final JsonNode concretePropertyObject = propertiesObject.get(property); assertNotNull(property + " is missing", concretePropertyObject); } } diff --git a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/DocGenTestHelper.java b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/DocGenTestHelper.java index 3adc856983..a8196dac47 100644 --- a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/DocGenTestHelper.java +++ b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/DocGenTestHelper.java @@ -12,7 +12,6 @@ import static org.mockito.Mockito.when; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule; import java.io.File; import java.io.FileNotFoundException; import java.net.URI; @@ -65,7 +64,6 @@ public class DocGenTestHelper { public void setUp() throws Exception { this.modules = loadModules("/yang"); this.mapper = new ObjectMapper(); - this.mapper.registerModule(new JsonOrgModule()); this.mapper.configure(SerializationFeature.INDENT_OUTPUT, true); } diff --git a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ModelGeneratorTest.java b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ModelGeneratorTest.java index b4ab8f4f56..58478425b9 100644 --- a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ModelGeneratorTest.java +++ b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ModelGeneratorTest.java @@ -8,9 +8,9 @@ package org.opendaylight.controller.sal.rest.doc.impl; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.base.Preconditions; import java.sql.Date; -import org.json.JSONObject; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -45,7 +45,7 @@ public class ModelGeneratorTest { if (m.getQNameModule().getNamespace().toString().equals(NAMESPACE) && m.getQNameModule().getRevision().equals(REVISION)) { - final JSONObject jsonObject = generator.convertToJsonSchema(m, this.schemaContext); + final ObjectNode jsonObject = generator.convertToJsonSchema(m, this.schemaContext); Assert.assertNotNull(jsonObject); } }