Merge "Remove deprecated registerDataChangeListener method"
authorJakubToth <jakub.toth@pantheon.tech>
Mon, 5 Mar 2018 20:54:25 +0000 (20:54 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 5 Mar 2018 20:54:25 +0000 (20:54 +0000)
37 files changed:
restconf/restconf-binding-parent/pom.xml
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/RestConnectorProvider.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/codecs/RestCodec.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/handlers/DOMMountPointServiceHandler.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/handlers/SchemaContextHandler.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/JsonNormalizedNodeBodyReader.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonToPatchBodyReader.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlToPatchBodyReader.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/spi/AbstractIdentifierAwareJaxRsProvider.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040Impl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfInvokeOperationsServiceImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/RestconfStreamsSubscriptionServiceImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/CreateStreamUtil.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/RestconfDataServiceConstant.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/SubscribeToStreamUtil.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/services/simple/impl/RestconfImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/services/simple/impl/RestconfOperationsServiceImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/services/simple/impl/RestconfSchemaServiceImpl.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/listeners/ListenerAdapter.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/streams/websockets/WebSocketServerHandler.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/YangInstanceIdentifierDeserializer.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/parser/YangInstanceIdentifierSerializer.java
restconf/restconf-nb-rfc8040/src/main/java/org/opendaylight/restconf/nb/rfc8040/utils/validations/RestconfValidation.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/XmlBodyReaderMountPointTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonPatchBodyReaderMountPointTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/JsonPatchBodyReaderTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlPatchBodyReaderMountPointTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/patch/XmlPatchBodyReaderTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/test/JsonBodyReaderTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/jersey/providers/test/XmlBodyReaderTest.java
restconf/restconf-nb-rfc8040/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/services/impl/JSONRestconfServiceRfc8040ImplTest.java
restconf/sal-rest-docgen-maven/src/main/java/org/opendaylight/netconf/sal/rest/doc/maven/StaticDocGenerator.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGenerator.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/model/builder/OperationBuilder.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/mountpoints/MountPointSwagger.java

index 6aac2185ffe7f45c883eff0f9752f6eadf7a9173..8b7279ae087affb36a7e10cfa11c6c4ee7afd22d 100644 (file)
           <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <configuration>
+          <failOnError>true</failOnError>
+        </configuration>
+      </plugin>
     </plugins>
   </build>
 </project>
index e2650032ff50fe7166a29b1722ad38285ae83015..7e251ef4e57d1cd54675d26362b292c176353bf0 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.restconf.nb.rfc8040;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSet.Builder;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.Set;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
@@ -56,9 +57,12 @@ public class RestConnectorProvider<T extends ServiceWrapper> implements Restconf
         }
     };
 
-    private static TransactionChainHandler transactionChainHandler;
-    private static DOMDataBroker dataBroker;
-    private static DOMMountPointServiceHandler mountPointServiceHandler;
+    @SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
+    private static volatile TransactionChainHandler transactionChainHandler;
+    @SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
+    private static volatile DOMDataBroker dataBroker;
+    @SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
+    private static volatile DOMMountPointServiceHandler mountPointServiceHandler;
 
     private final DOMRpcService rpcService;
     private final DOMNotificationService notificationService;
index 947002c9f014af93fdc631c6958480d6ced6fbff..4d9ee346e26740674d53e37a25c6397fd1623dae 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
 import org.opendaylight.restconf.common.util.IdentityValuesDTO;
 import org.opendaylight.restconf.common.util.IdentityValuesDTO.IdentityValue;
@@ -325,8 +326,9 @@ public final class RestCodec {
 
         private static List<Predicate> keyValuesToPredicateList(final Map<QName, Object> keyValues) {
             final List<Predicate> result = new ArrayList<>();
-            for (final QName qualifiedName : keyValues.keySet()) {
-                final Object value = keyValues.get(qualifiedName);
+            for (final Entry<QName, Object> entry : keyValues.entrySet()) {
+                final QName qualifiedName = entry.getKey();
+                final Object value = entry.getValue();
                 result.add(new Predicate(qNameToIdentityValue(qualifiedName), String.valueOf(value)));
             }
             return result;
@@ -360,7 +362,7 @@ public final class RestCodec {
             final SchemaContext schemaContext) {
         URI validNamespace;
         if (mountPoint != null) {
-            validNamespace = findFirstModuleByName(schemaContext, namespace);
+            validNamespace = findFirstModuleByName(mountPoint.getSchemaContext(), namespace);
         } else {
             validNamespace = findFirstModuleByName(schemaContext, namespace);
         }
index ecb67cc09187fec4c04ad216e0ccfb33bf419320..c95ee3f64cf7aa54383336a4996e453647432862 100644 (file)
@@ -7,8 +7,7 @@
  */
 package org.opendaylight.restconf.nb.rfc8040.handlers;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
+import java.util.Objects;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 
 /**
@@ -16,9 +15,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
  *
  */
 public class DOMMountPointServiceHandler implements Handler<DOMMountPointService> {
-
     private final DOMMountPointService domMountPointService;
-    private static DOMMountPointService actualDomMountPointService;
 
     /**
      * Prepare mount point service for Restconf services.
@@ -27,18 +24,11 @@ public class DOMMountPointServiceHandler implements Handler<DOMMountPointService
      *             mount point service
      */
     public DOMMountPointServiceHandler(final DOMMountPointService domMountPointService) {
-        Preconditions.checkNotNull(domMountPointService);
-        this.domMountPointService = domMountPointService;
-        actualDomMountPointService = domMountPointService;
+        this.domMountPointService = Objects.requireNonNull(domMountPointService);
     }
 
     @Override
     public DOMMountPointService get() {
         return this.domMountPointService;
     }
-
-    public static Optional<DOMMountPointService> getActualMountPointService() {
-        return Optional.fromNullable(actualDomMountPointService);
-    }
-
 }
index e50b0152a51ba59cfb3ad7c53fe68d4ee89cabb4..51b7790fd34913a586e8a4a4adfa54e2466ee927 100644 (file)
@@ -8,7 +8,9 @@
 package org.opendaylight.restconf.nb.rfc8040.handlers;
 
 import com.google.common.base.Preconditions;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.Collection;
+import java.util.concurrent.atomic.AtomicInteger;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
@@ -36,57 +38,53 @@ public class SchemaContextHandler implements SchemaContextListenerHandler {
 
     private static final Logger LOG = LoggerFactory.getLogger(SchemaContextHandler.class);
 
+    @SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
+    private static volatile SchemaContext schemaContext;
+
     private final TransactionChainHandler transactionChainHandler;
-    private SchemaContext context;
-    private static SchemaContext actualSchemaContext;
 
-    private int moduleSetId;
+    private final AtomicInteger moduleSetId = new AtomicInteger(0);
 
     /**
-     * Set module-set-id on initial value - 0.
+     * Constructor.
      *
      * @param transactionChainHandler Transaction chain handler
      */
     public SchemaContextHandler(final TransactionChainHandler transactionChainHandler) {
         this.transactionChainHandler = transactionChainHandler;
-        this.moduleSetId = 0;
-        actualSchemaContext = null;
+        schemaContext = null;
     }
 
     @Override
     @SuppressWarnings("checkstyle:hiddenField")
     public void onGlobalContextUpdated(final SchemaContext context) {
         Preconditions.checkNotNull(context);
-        this.context = null;
-        this.context = context;
-
-        actualSchemaContext = context;
+        schemaContext = context;
 
-        this.moduleSetId++;
         final Module ietfYangLibraryModule =
                 context.findModule(IetfYangLibrary.MODULE_QNAME).orElse(null);
         NormalizedNode<NodeIdentifier, Collection<DataContainerChild<? extends PathArgument, ?>>> normNode =
                 RestconfMappingNodeUtil.mapModulesByIetfYangLibraryYang(context.getModules(), ietfYangLibraryModule,
-                        context, String.valueOf(this.moduleSetId));
+                        context, String.valueOf(this.moduleSetId.incrementAndGet()));
         putData(normNode);
 
         final Module monitoringModule =
-                this.context.findModule(MonitoringModule.MODULE_QNAME).orElse(null);
+                schemaContext.findModule(MonitoringModule.MODULE_QNAME).orElse(null);
         normNode = RestconfMappingNodeUtil.mapCapabilites(monitoringModule);
         putData(normNode);
     }
 
     @Override
     public SchemaContext get() {
-        return this.context;
+        return schemaContext;
     }
 
-    public static SchemaContext getActualSchemaContext() {
-        return actualSchemaContext;
+    public static SchemaContext getSchemaContext() {
+        return schemaContext;
     }
 
-    public static void setActualSchemaContext(final SchemaContext schemaContext) {
-        actualSchemaContext = schemaContext;
+    public static void setSchemaContext(final SchemaContext context) {
+        schemaContext = context;
     }
 
     private void putData(
index 1d61b4cc06e2f80e8a5daa4a700731686bc0a4f3..83b927a7bbadcb498222c4be93c45ebc9f5cbb81 100644 (file)
@@ -12,6 +12,7 @@ import com.google.gson.stream.JsonReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 import javax.ws.rs.Consumes;
@@ -87,7 +88,7 @@ public class JsonNormalizedNodeBodyReader extends AbstractNormalizedNodeBodyRead
         final JsonParserStream jsonParser = JsonParserStream.create(writer,
             JSONCodecFactorySupplier.RFC7951.getShared(path.getSchemaContext()), parentSchema);
 
-        final JsonReader reader = new JsonReader(new InputStreamReader(entityStream));
+        final JsonReader reader = new JsonReader(new InputStreamReader(entityStream, StandardCharsets.UTF_8));
         jsonParser.parse(reader);
 
         NormalizedNode<?, ?> result = resultHolder.getResult();
index 648aa11090e4838a001a4365eed452e5f0588944..9985f7686124ab7d7ef81050ee47ef6846632d17 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.restconf.nb.rfc8040.jersey.providers.patch;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.gson.stream.JsonReader;
@@ -16,8 +17,10 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.StringReader;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 import javax.annotation.Nonnull;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.WebApplicationException;
@@ -29,9 +32,9 @@ import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
 import org.opendaylight.restconf.common.patch.PatchContext;
 import org.opendaylight.restconf.common.patch.PatchEditOperation;
 import org.opendaylight.restconf.common.patch.PatchEntity;
+import org.opendaylight.restconf.nb.rfc8040.RestConnectorProvider;
 import org.opendaylight.restconf.nb.rfc8040.Rfc8040;
 import org.opendaylight.restconf.nb.rfc8040.codecs.StringModuleInstanceIdentifierCodec;
-import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
 import org.opendaylight.restconf.nb.rfc8040.utils.RestconfConstants;
 import org.opendaylight.restconf.nb.rfc8040.utils.parser.ParserIdentifier;
@@ -69,7 +72,7 @@ public class JsonToPatchBodyReader extends AbstractToPatchBodyReader {
 
     private PatchContext readFrom(final InstanceIdentifierContext<?> path, final InputStream entityStream)
             throws IOException {
-        final JsonReader jsonReader = new JsonReader(new InputStreamReader(entityStream));
+        final JsonReader jsonReader = new JsonReader(new InputStreamReader(entityStream, StandardCharsets.UTF_8));
         final List<PatchEntity> resultList = read(jsonReader, path);
         jsonReader.close();
 
@@ -81,8 +84,8 @@ public class JsonToPatchBodyReader extends AbstractToPatchBodyReader {
             RestconfDocumentedException {
         try {
             return readFrom(
-                    ParserIdentifier.toInstanceIdentifier(uriPath, SchemaContextHandler.getActualSchemaContext(),
-                            DOMMountPointServiceHandler.getActualMountPointService()), entityStream);
+                    ParserIdentifier.toInstanceIdentifier(uriPath, SchemaContextHandler.getSchemaContext(),
+                            Optional.of(RestConnectorProvider.getMountPointService())), entityStream);
         } catch (final Exception e) {
             propagateExceptionAs(e);
             return null; // no-op
@@ -211,7 +214,7 @@ public class JsonToPatchBodyReader extends AbstractToPatchBodyReader {
                     edit.setId(in.nextString());
                     break;
                 case "operation":
-                    edit.setOperation(PatchEditOperation.valueOf(in.nextString().toUpperCase()));
+                    edit.setOperation(PatchEditOperation.valueOf(in.nextString().toUpperCase(Locale.ROOT)));
                     break;
                 case "target":
                     // target can be specified completely in request URI
index 2db6167dc0e7d92ec1d6691dffc00906baff15d1..7af6e56b32c14e2b35de0c58eebf5aeea42f02cd 100644 (file)
@@ -17,6 +17,7 @@ import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import javax.annotation.Nonnull;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.WebApplicationException;
@@ -92,7 +93,7 @@ public class XmlToPatchBodyReader extends AbstractToPatchBodyReader {
             DataSchemaNode schemaNode = (DataSchemaNode) pathContext.getSchemaNode();
             final Element element = (Element) editNodes.item(i);
             final String operation = element.getElementsByTagName("operation").item(0).getFirstChild().getNodeValue();
-            final PatchEditOperation oper = PatchEditOperation.valueOf(operation.toUpperCase());
+            final PatchEditOperation oper = PatchEditOperation.valueOf(operation.toUpperCase(Locale.ROOT));
             final String editId = element.getElementsByTagName("edit-id").item(0).getFirstChild().getNodeValue();
             final String target = element.getElementsByTagName("target").item(0).getFirstChild().getNodeValue();
             final List<Element> values = readValueNodes(element, oper);
index ab40b3274a7197b7dd7bc4261f8d4d0a8fe9db71..8028ee94d8cd5c1bd2ccc386f74feda47d654662 100644 (file)
@@ -80,7 +80,7 @@ public abstract class AbstractIdentifierAwareJaxRsProvider<T> implements Message
     private InstanceIdentifierContext<?> getInstanceIdentifierContext() {
         return ParserIdentifier.toInstanceIdentifier(
                 getIdentifier(),
-                SchemaContextHandler.getActualSchemaContext(),
+                SchemaContextHandler.getSchemaContext(),
                 Optional.of(RestConnectorProvider.getMountPointService()));
     }
 
index 8f80fb3bbafc1bd7e7f3a70e147abdd57e9071d9..3fd9e00734d84c3b22c4e5331b51f38da66cd6bc 100644 (file)
@@ -171,7 +171,7 @@ public class JSONRestconfServiceRfc8040Impl implements JSONRestconfService, Auto
             if (outputContext.getData() != null) {
                 output = toJson(outputContext);
             }
-        } catch (final Exception e) {
+        } catch (RuntimeException | IOException e) {
             propagateExceptionAs(uriPath, e, "RPC");
         }
 
@@ -212,7 +212,7 @@ public class JSONRestconfServiceRfc8040Impl implements JSONRestconfService, Auto
     private NormalizedNodeContext toNormalizedNodeContext(final String uriPath, @Nullable final String payload,
             final boolean isPost) throws OperationFailedException {
         final InstanceIdentifierContext<?> instanceIdentifierContext = ParserIdentifier.toInstanceIdentifier(
-                uriPath, SchemaContextHandler.getActualSchemaContext(),
+                uriPath, SchemaContextHandler.getSchemaContext(),
                 Optional.of(mountPointServiceHandler.get()));
 
         if (payload == null) {
index e56767ab75eb3b0ac4f9f643bb87a31b5483bb84..e3cc96a46163c07b53ac01d1450e19428b59f1a3 100644 (file)
@@ -35,8 +35,8 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 @Path("/")
 public class RestconfInvokeOperationsServiceImpl implements RestconfInvokeOperationsService {
 
-    private RpcServiceHandler rpcServiceHandler;
-    private SchemaContextHandler schemaContextHandler;
+    private volatile RpcServiceHandler rpcServiceHandler;
+    private volatile SchemaContextHandler schemaContextHandler;
 
     public RestconfInvokeOperationsServiceImpl(final RpcServiceHandler rpcServiceHandler,
             final SchemaContextHandler schemaContextHandler) {
@@ -87,11 +87,12 @@ public class RestconfInvokeOperationsServiceImpl implements RestconfInvokeOperat
         final DOMRpcResult result = RestconfInvokeOperationsUtil.checkResponse(response);
 
         RpcDefinition resultNodeSchema = null;
-        final NormalizedNode<?, ?> resultData = result.getResult();
-        if ((result != null) && (result.getResult() != null)) {
+        NormalizedNode<?, ?> resultData = null;
+        if (result != null && result.getResult() != null) {
+            resultData = result.getResult();
             resultNodeSchema = (RpcDefinition) payload.getInstanceIdentifierContext().getSchemaNode();
         }
-        return new NormalizedNodeContext(new InstanceIdentifierContext<RpcDefinition>(null, resultNodeSchema,
+        return new NormalizedNodeContext(new InstanceIdentifierContext<>(null, resultNodeSchema,
                 mountPoint, schemaContextRef.get()), resultData);
     }
 }
index f320c115e7b2b97d51f5f4894c4f6f9bab28bf5e..ac60ed560311827322bafac6fd3c874093bb0b46 100644 (file)
@@ -115,7 +115,7 @@ public class RestconfStreamsSubscriptionServiceImpl implements RestconfStreamsSu
     /**
      * Holder of all handlers for notifications.
      */
-    public final class HandlersHolder {
+    public static final class HandlersHolder {
 
         private final DOMDataBrokerHandler domDataBrokerHandler;
         private final NotificationServiceHandler notificationServiceHandler;
index dff93ea258a56879d7d4c9566aa8cfff915a03bf..674d189ed53551f88f923b4e2a9c750103645cff 100644 (file)
@@ -128,7 +128,7 @@ public final class CreateStreamUtil {
      */
     private static NotificationOutputType prepareOutputType(final ContainerNode data) {
         NotificationOutputType outputType = parseEnum(data, NotificationOutputType.class, OUTPUT_TYPE_PARAM_NAME);
-        return outputType = outputType == null ? NotificationOutputType.XML : outputType;
+        return outputType == null ? NotificationOutputType.XML : outputType;
     }
 
     private static String prepareDataChangeNotifiStreamName(final YangInstanceIdentifier path,
index 8077b5cc002e8cfb44ce53ce29ce9bce4ecfad56..a39ec65bc08ece3f8654cbb72db0be183579b08f 100644 (file)
@@ -28,7 +28,7 @@ public final class RestconfDataServiceConstant {
      * Constants for read data.
      *
      */
-    public final class ReadData {
+    public static final class ReadData {
         // URI parameters
         public static final String CONTENT = "content";
         public static final String DEPTH = "depth";
@@ -56,7 +56,7 @@ public final class RestconfDataServiceConstant {
      * Constants for data to put.
      *
      */
-    public final class PutData {
+    public static final class PutData {
         public static final String NETCONF_BASE = "urn:ietf:params:xml:ns:netconf:base:1.0";
         public static final String NETCONF_BASE_PAYLOAD_NAME = "data";
         public static final String PUT_TX_TYPE = "PUT";
@@ -70,7 +70,7 @@ public final class RestconfDataServiceConstant {
      * Constants for data to post.
      *
      */
-    public final class PostData {
+    public static final class PostData {
         public static final String POST_TX_TYPE = "POST";
 
         private PostData() {
@@ -82,7 +82,7 @@ public final class RestconfDataServiceConstant {
      * Constants for data to delete.
      *
      */
-    public final class DeleteData {
+    public static final class DeleteData {
         public static final String DELETE_TX_TYPE = "DELETE";
 
         private DeleteData() {
@@ -94,7 +94,7 @@ public final class RestconfDataServiceConstant {
      * Constants for data to yang patch.
      *
      */
-    public final class PatchData {
+    public static final class PatchData {
         public static final String PATCH_TX_TYPE = "Patch";
 
         private PatchData() {
index f6b685ac0689bf86f2031d548c9c47826ab67d80..eb4b64f4aa4a286b66ec694dc65ab5bb48d424a1 100644 (file)
@@ -113,7 +113,7 @@ public final class SubscribeToStreamUtil {
         } else {
             listeners = pickSpecificListenerByOutput(listeners, NotificationOutputType.XML.getName());
         }
-        if (listeners == null || listeners.isEmpty()) {
+        if (listeners.isEmpty()) {
             throw new RestconfDocumentedException("Stream was not found.", ErrorType.PROTOCOL,
                     ErrorTag.UNKNOWN_ELEMENT);
         }
index 629590ab3a879a419ef50b1adbc9059c398f82a5..da89d99bcfd227666b1387888963513b9707e810 100644 (file)
@@ -27,7 +27,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 @Path("/")
 public class RestconfImpl implements RestconfService {
 
-    private SchemaContextHandler schemaContextHandler;
+    private volatile SchemaContextHandler schemaContextHandler;
 
     public RestconfImpl(final SchemaContextHandler schemaContextHandler) {
         this.schemaContextHandler = schemaContextHandler;
index 19f39fc9f9492b89f8eb09d0ee8f05de5d5d5fdd..51f1f3eccc3b5f64af14694de9373801ac9a131e 100644 (file)
@@ -49,8 +49,8 @@ public class RestconfOperationsServiceImpl implements RestconfOperationsService
 
     private static final Logger LOG = LoggerFactory.getLogger(RestconfOperationsServiceImpl.class);
 
-    private SchemaContextHandler schemaContextHandler;
-    private DOMMountPointServiceHandler domMountPointServiceHandler;
+    private volatile SchemaContextHandler schemaContextHandler;
+    private volatile DOMMountPointServiceHandler domMountPointServiceHandler;
 
     /**
      * Set {@link SchemaContextHandler} for getting actual {@link SchemaContext}.
index 709ed23cf0d479aaac41c9301b0b8b91d041f424..63c05686c01aa765ef41b5ed1e534c4dd08bfbe7 100644 (file)
@@ -24,9 +24,9 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 @Path("/")
 public class RestconfSchemaServiceImpl implements RestconfSchemaService {
 
-    private SchemaContextHandler schemaContextHandler;
-    private DOMMountPointServiceHandler domMountPointServiceHandler;
-    private DOMYangTextSourceProvider sourceProvider;
+    private volatile SchemaContextHandler schemaContextHandler;
+    private volatile DOMMountPointServiceHandler domMountPointServiceHandler;
+    private volatile DOMYangTextSourceProvider sourceProvider;
 
     /**
      * Set {@link SchemaContextHandler} for getting actual {@link SchemaContext}
index 815f4b413e46ceac7b92fdaaff6ecfdd53f4f003..874ba1eaa8953431530e435316e6efbf164a4f00 100644 (file)
@@ -12,6 +12,7 @@ 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.nio.charset.StandardCharsets;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -118,7 +119,7 @@ public class ListenerAdapter extends AbstractCommonSubscriber implements DOMData
         final Event event = new Event(EventType.NOTIFY);
         if (this.outputType.equals(NotificationOutputType.JSON)) {
             try {
-                final JsonNode node = new XmlMapper().readTree(xml.getBytes());
+                final JsonNode node = new XmlMapper().readTree(xml.getBytes(StandardCharsets.UTF_8));
                 event.setData(node.toString());
             } catch (final IOException e) {
                 LOG.error("Error parsing XML {}", xml, e);
@@ -312,8 +313,9 @@ public class ListenerAdapter extends AbstractCommonSubscriber implements DOMData
             writeIdentifierWithNamespacePrefix(element, textContent, pathArgument.getNodeType(), schemaContext);
             if (pathArgument instanceof NodeIdentifierWithPredicates) {
                 final Map<QName, Object> predicates = ((NodeIdentifierWithPredicates) pathArgument).getKeyValues();
-                for (final QName keyValue : predicates.keySet()) {
-                    final String predicateValue = String.valueOf(predicates.get(keyValue));
+                for (final Entry<QName, Object> entry : predicates.entrySet()) {
+                    final QName keyValue = entry.getKey();
+                    final String predicateValue = String.valueOf(entry.getValue());
                     textContent.append("[");
                     writeIdentifierWithNamespacePrefix(element, textContent, keyValue, schemaContext);
                     textContent.append("='");
index fc7573a16464a03e7cc4bae9509e9b599f3d08d5..fce83008d5aded16545e797a0f114a845a7d2f2d 100755 (executable)
@@ -8,7 +8,6 @@
 
 package org.opendaylight.restconf.nb.rfc8040.streams.websockets;
 
-import static io.netty.handler.codec.http.HttpHeaders.Names.HOST;
 import static io.netty.handler.codec.http.HttpHeaders.isKeepAlive;
 import static io.netty.handler.codec.http.HttpHeaders.setContentLength;
 import static io.netty.handler.codec.http.HttpMethod.GET;
@@ -26,6 +25,7 @@ import io.netty.channel.SimpleChannelInboundHandler;
 import io.netty.handler.codec.http.DefaultFullHttpResponse;
 import io.netty.handler.codec.http.FullHttpRequest;
 import io.netty.handler.codec.http.FullHttpResponse;
+import io.netty.handler.codec.http.HttpHeaders.Names;
 import io.netty.handler.codec.http.HttpRequest;
 import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
 import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
@@ -95,7 +95,7 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
             }
         } else if (streamName.contains(RestconfConstants.NOTIFICATION_STREAM)) {
             final List<NotificationListenerAdapter> listeners = Notificator.getNotificationListenerFor(streamName);
-            if (!listeners.isEmpty() && (listeners != null)) {
+            if (listeners != null && !listeners.isEmpty()) {
                 for (final NotificationListenerAdapter listener : listeners) {
                     listener.addSubscriber(ctx.channel());
                     LOG.debug("Subscriber successfully registered.");
@@ -141,7 +141,7 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
 
         // Send the response and close the connection if necessary.
         final ChannelFuture f = ctx.channel().writeAndFlush(res);
-        if (!isKeepAlive(req) || (res.getStatus().code() != 200)) {
+        if (!isKeepAlive(req) || res.getStatus().code() != 200) {
             f.addListener(ChannelFutureListener.CLOSE);
         }
     }
@@ -163,11 +163,11 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
                 if (listener != null) {
                     listener.removeSubscriber(ctx.channel());
                     LOG.debug("Subscriber successfully registered.");
+                    Notificator.removeListenerIfNoSubscriberExists(listener);
                 }
-                Notificator.removeListenerIfNoSubscriberExists(listener);
             } else if (streamName.contains(RestconfConstants.NOTIFICATION_STREAM)) {
                 final List<NotificationListenerAdapter> listeners = Notificator.getNotificationListenerFor(streamName);
-                if (!listeners.isEmpty() && (listeners != null)) {
+                if (listeners != null && !listeners.isEmpty()) {
                     for (final NotificationListenerAdapter listener : listeners) {
                         listener.removeSubscriber(ctx.channel());
                     }
@@ -182,9 +182,6 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
 
     @Override
     public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception {
-        if (!(cause instanceof java.nio.channels.ClosedChannelException)) {
-            // LOG.info("Not expected error cause: ", cause.toString());
-        }
         ctx.close();
     }
 
@@ -196,7 +193,7 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
      * @return String representation of web socket location.
      */
     private static String getWebSocketLocation(final HttpRequest req) {
-        return "ws://" + req.headers().get(HOST) + req.getUri();
+        return "ws://" + req.headers().get(Names.HOST) + req.getUri();
     }
 
 }
index 7136efbe1785ba151276891c6fd1b86face3e16a..2009a072c6a48290678a73f3db088805fe4e52c6 100644 (file)
@@ -11,9 +11,12 @@ import com.google.common.base.CharMatcher;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Optional;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError;
 import org.opendaylight.restconf.common.util.RestUtil;
 import org.opendaylight.restconf.common.util.RestconfSchemaUtil;
@@ -85,7 +88,8 @@ public final class YangInstanceIdentifierDeserializer {
             } else if (currentChar(variables.getOffset(),
                     variables.getData()) == ParserBuilderConstants.Deserializer.EQUAL) {
                 if (nextContextNode(qname, path, variables).getDataSchemaNode() instanceof ListSchemaNode) {
-                    prepareNodeWithPredicates(qname, path, variables);
+                    prepareNodeWithPredicates(qname, path, variables,
+                            (ListSchemaNode) variables.getCurrent().getDataSchemaNode());
                 } else {
                     prepareNodeWithValue(qname, path, variables);
                 }
@@ -100,12 +104,10 @@ public final class YangInstanceIdentifierDeserializer {
     }
 
     private static void prepareNodeWithPredicates(final QName qname, final List<PathArgument> path,
-                                                  final MainVarsWrapper variables) {
+            final MainVarsWrapper variables, final ListSchemaNode listSchemaNode) {
+        checkValid(listSchemaNode != null, "Data schema node is null", variables.getData(), variables.getOffset());
 
-        final DataSchemaNode dataSchemaNode = variables.getCurrent().getDataSchemaNode();
-        checkValid(dataSchemaNode != null, "Data schema node is null", variables.getData(), variables.getOffset());
-
-        final Iterator<QName> keys = ((ListSchemaNode) dataSchemaNode).getKeyDefinition().iterator();
+        final Iterator<QName> keys = listSchemaNode.getKeyDefinition().iterator();
         final ImmutableMap.Builder<QName, Object> values = ImmutableMap.builder();
 
         // skip already expected equal sign
@@ -133,15 +135,15 @@ public final class YangInstanceIdentifierDeserializer {
 
             // parse value
             final QName key = keys.next();
-            DataSchemaNode leafSchemaNode = null;
-            if (dataSchemaNode instanceof ListSchemaNode) {
-                leafSchemaNode = ((ListSchemaNode) dataSchemaNode).getDataChildByName(key);
-            } else if (dataSchemaNode instanceof LeafListSchemaNode) {
-                leafSchemaNode = dataSchemaNode;
+            Optional<DataSchemaNode> leafSchemaNode = listSchemaNode.findDataChildByName(key);
+            if (!leafSchemaNode.isPresent()) {
+                throw new RestconfDocumentedException("Schema not found for " + key,
+                        RestconfError.ErrorType.PROTOCOL, RestconfError.ErrorTag.BAD_ELEMENT);
             }
+
             final String value = findAndParsePercentEncoded(nextIdentifierFromNextSequence(
                     ParserBuilderConstants.Deserializer.IDENTIFIER_PREDICATE, variables));
-            final Object valueByType = prepareValueByType(leafSchemaNode, value, variables);
+            final Object valueByType = prepareValueByType(leafSchemaNode.get(), value, variables);
             values.put(key, valueByType);
 
 
@@ -252,6 +254,7 @@ public final class YangInstanceIdentifierDeserializer {
 
         switch (currentChar(variables.getOffset(), variables.getData())) {
             case RestconfConstants.SLASH:
+            case ParserBuilderConstants.Deserializer.EQUAL:
                 prefix = preparedPrefix;
                 return getQNameOfDataSchemaNode(prefix, variables);
             case ParserBuilderConstants.Deserializer.COLON:
@@ -272,9 +275,6 @@ public final class YangInstanceIdentifierDeserializer {
                     Preconditions.checkArgument(module != null, "Failed to lookup prefix %s", prefix);
                     return QName.create(module.getQNameModule(), localName);
                 }
-            case ParserBuilderConstants.Deserializer.EQUAL:
-                prefix = preparedPrefix;
-                return getQNameOfDataSchemaNode(prefix, variables);
             default:
                 throw new IllegalArgumentException("Failed build path.");
         }
@@ -321,15 +321,18 @@ public final class YangInstanceIdentifierDeserializer {
                 variables.getData(), variables.getOffset());
     }
 
+    @SuppressFBWarnings("NP_NULL_ON_SOME_PATH") // code does check for null 'current' but FB doesn't recognize it
     private static DataSchemaContextNode<?> nextContextNode(final QName qname, final List<PathArgument> path,
             final MainVarsWrapper variables) {
         variables.setCurrent(variables.getCurrent().getChild(qname));
         DataSchemaContextNode<?> current = variables.getCurrent();
         if (current == null) {
-            for (final RpcDefinition rpcDefinition : variables.getSchemaContext()
-                    .findModule(qname.getModule()).orElse(null).getRpcs()) {
-                if (rpcDefinition.getQName().getLocalName().equals(qname.getLocalName())) {
-                    return null;
+            final Optional<Module> module = variables.getSchemaContext().findModule(qname.getModule());
+            if (module.isPresent()) {
+                for (final RpcDefinition rpcDefinition : module.get().getRpcs()) {
+                    if (rpcDefinition.getQName().getLocalName().equals(qname.getLocalName())) {
+                        return null;
+                    }
                 }
             }
         }
index b20c5c15bd5606c9f5d617313820ea9b1a42d1ae..849a8c561543f2261257f23d8cf801ee256e12c4 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.restconf.nb.rfc8040.utils.parser;
 
 import com.google.common.base.Preconditions;
 import java.util.Iterator;
+import java.util.Locale;
 import java.util.Map.Entry;
 import org.opendaylight.restconf.nb.rfc8040.utils.RestconfConstants;
 import org.opendaylight.restconf.nb.rfc8040.utils.parser.builder.ParserBuilderConstants;
@@ -137,7 +138,7 @@ public final class YangInstanceIdentifierSerializer {
         while (start < valueOf.length()) {
             if (Serializer.PERCENT_ENCODE_CHARS.matches(valueOf.charAt(start))) {
                 final String format = String.format("%x", (int) valueOf.charAt(start));
-                final String upperCase = format.toUpperCase();
+                final String upperCase = format.toUpperCase(Locale.ROOT);
                 sb.append(ParserBuilderConstants.Deserializer.PERCENT_ENCODING + upperCase);
             } else {
                 sb.append(valueOf.charAt(start));
index 84db15e8f1634da1571ff2b533e5ab998215768a..1db58e4473c0e088088143f800d1b7083d27acb8 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.restconf.nb.rfc8040.utils.validations;
 import java.time.format.DateTimeParseException;
 import java.util.Date;
 import java.util.Iterator;
+import java.util.Locale;
 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
@@ -67,7 +68,7 @@ public final class RestconfValidation {
         );
 
         RestconfValidationUtils.checkDocumentedError(
-                !name.toUpperCase().startsWith("XML"),
+                !name.toUpperCase(Locale.ROOT).startsWith("XML"),
                 ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE,
                 "Identifier must NOT start with XML ignore case."
         );
index b5365e0c1c992ecd91d168be8a318c84fa349afa..6290961e1ddf73b792c4c7cd054bf8760ca50553 100644 (file)
@@ -74,7 +74,7 @@ public class XmlBodyReaderMountPointTest extends AbstractBodyReaderTest {
         when(MOUNT_POINT_SERVICE_HANDLER.get()).thenReturn(mountPointService);
         when(mountPointService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountPoint));
         when(mountPoint.getSchemaContext()).thenReturn(schemaContext);
-        SchemaContextHandler.setActualSchemaContext(schemaContext);
+        SchemaContextHandler.setSchemaContext(schemaContext);
     }
 
     @Test
index b92a6cedcffe5d12622e897cf0d349d89b5cd8dd..fa0d482fde4f6bfae5036127bb42198c5da12a6c 100644 (file)
@@ -55,7 +55,7 @@ public class JsonPatchBodyReaderMountPointTest extends AbstractBodyReaderTest {
         when(MOUNT_POINT_SERVICE_HANDLER.get()).thenReturn(mountPointService);
         when(mountPointService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountPoint));
         when(mountPoint.getSchemaContext()).thenReturn(schemaContext);
-        SchemaContextHandler.setActualSchemaContext(schemaContext);
+        SchemaContextHandler.setSchemaContext(schemaContext);
     }
 
     @Test
index d47534b5339e63361438354c421525798090d305..e5824c9217cffdf98267b068a4a25a1bbdb03079 100644 (file)
@@ -44,7 +44,7 @@ public class JsonPatchBodyReaderTest extends AbstractBodyReaderTest {
     public static void initialization() {
         schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
         when(MOUNT_POINT_SERVICE_HANDLER.get()).thenReturn(mock(DOMMountPointService.class));
-        SchemaContextHandler.setActualSchemaContext(schemaContext);
+        SchemaContextHandler.setSchemaContext(schemaContext);
     }
 
     @Test
index 656dbcae494fd41568b41d5babffc91d576f1aa5..00c200ea273a93ab8cfea3bcbfb207396ee743dd 100644 (file)
@@ -54,7 +54,7 @@ public class XmlPatchBodyReaderMountPointTest extends AbstractBodyReaderTest {
         when(MOUNT_POINT_SERVICE_HANDLER.get()).thenReturn(mountPointService);
         when(mountPointService.getMountPoint(any(YangInstanceIdentifier.class))).thenReturn(Optional.of(mountPoint));
         when(mountPoint.getSchemaContext()).thenReturn(schemaContext);
-        SchemaContextHandler.setActualSchemaContext(schemaContext);
+        SchemaContextHandler.setSchemaContext(schemaContext);
     }
 
     @Test
index 87d9ef18a1c74c2de7463c635172c8a4ae244014..aee4a976639234f7cc10aa3a08554330bb069291 100644 (file)
@@ -43,7 +43,7 @@ public class XmlPatchBodyReaderTest extends AbstractBodyReaderTest {
     public static void initialization() {
         schemaContext = schemaContextLoader("/instanceidentifier/yang", schemaContext);
         when(MOUNT_POINT_SERVICE_HANDLER.get()).thenReturn(mock(DOMMountPointService.class));
-        SchemaContextHandler.setActualSchemaContext(schemaContext);
+        SchemaContextHandler.setSchemaContext(schemaContext);
     }
 
     @Test
index 635c568902d21c8d2789c24b94cff5540701cf76..41283b63f89677cfe21d784e4977dccd45962fb6 100644 (file)
@@ -64,7 +64,7 @@ public class JsonBodyReaderTest extends AbstractBodyReaderTest {
         testFiles.addAll(TestRestconfUtils.loadFiles("/modules"));
         schemaContext = YangParserTestUtils.parseYangFiles(testFiles);
         when(MOUNT_POINT_SERVICE_HANDLER.get()).thenReturn(mock(DOMMountPointService.class));
-        SchemaContextHandler.setActualSchemaContext(schemaContext);
+        SchemaContextHandler.setSchemaContext(schemaContext);
     }
 
     @Test
index 291a383554643dadf19bf14ea4c49b256011f3e3..d3529d0ab07f6bf233e5a47718eb61ed553fd3a1 100644 (file)
@@ -68,7 +68,7 @@ public class XmlBodyReaderTest extends AbstractBodyReaderTest {
         testFiles.addAll(TestRestconfUtils.loadFiles("/foo-xml-test/yang"));
         schemaContext = YangParserTestUtils.parseYangFiles(testFiles);
         when(MOUNT_POINT_SERVICE_HANDLER.get()).thenReturn(mock(DOMMountPointService.class));
-        SchemaContextHandler.setActualSchemaContext(schemaContext);
+        SchemaContextHandler.setSchemaContext(schemaContext);
     }
 
     @Test
index 624828cbb0972dfceba6280f0bd5db59d902308d..016abcee7f7b1ed648393c3c05455394ee924bcf 100644 (file)
@@ -51,6 +51,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.controller.md.sal.dom.spi.DefaultDOMRpcResult;
 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.restconf.nb.rfc8040.RestConnectorProvider;
 import org.opendaylight.restconf.nb.rfc8040.TestUtils;
 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMDataBrokerHandler;
 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
@@ -144,9 +145,10 @@ public class JSONRestconfServiceRfc8040ImplTest {
     @BeforeClass
     public static void init() throws IOException, ReactorException {
         schemaContext = TestUtils.loadSchemaContext("/full-versions/yangs");
-        SchemaContextHandler.setActualSchemaContext(schemaContext);
+        SchemaContextHandler.setSchemaContext(schemaContext);
     }
 
+    @SuppressWarnings("resource")
     @Before
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -182,12 +184,18 @@ public class JSONRestconfServiceRfc8040ImplTest {
         final DOMMountPointServiceHandler mountPointServiceHandler =
                 new DOMMountPointServiceHandler(mockMountPointService);
 
+        final DOMNotificationService mockNotificationService = mock(DOMNotificationService.class);
         ServicesWrapperImpl.getInstance().setHandlers(mockSchemaContextHandler, mountPointServiceHandler,
                 txChainHandler, new DOMDataBrokerHandler(mockDOMDataBroker),
                 new RpcServiceHandler(mockRpcService),
-                new NotificationServiceHandler(mock(DOMNotificationService.class)), domSchemaService);
+                new NotificationServiceHandler(mockNotificationService), domSchemaService);
 
         service = new JSONRestconfServiceRfc8040Impl(ServicesWrapperImpl.getInstance(), mountPointServiceHandler);
+
+        new RestConnectorProvider<>(mockDOMDataBroker, domSchemaService, mockRpcService, mockNotificationService,
+                mockMountPointService).start();
+
+        SchemaContextHandler.setSchemaContext(schemaContext);
     }
 
     private static String loadData(final String path) throws IOException {
index dbb1c1e1ee7a4c44b3352aecf4ecb533a9068bf7..e09c73ed4d8eea896218d625f948285ffe80daf2 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.netconf.sal.rest.doc.maven;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
@@ -30,20 +31,20 @@ import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
 import org.opendaylight.yangtools.yang2sources.spi.MavenProjectAware;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * This class gathers all yang defined {@link Module}s and generates Swagger compliant documentation.
  */
 public class StaticDocGenerator extends ApiDocGenerator implements BasicCodeGenerator, MavenProjectAware {
+    private static final Logger LOG = LoggerFactory.getLogger(StaticDocGenerator.class);
+
     private static final String DEFAULT_OUTPUT_BASE_DIR_PATH = "target" + File.separator + "generated-resources"
         + File.separator + "swagger-api-documentation";
 
-    private MavenProject mavenProject;
-    private File projectBaseDir;
-    private Map<String, String> additionalConfig;
-    private File resourceBaseDir;
-
     @Override
+    @SuppressFBWarnings("DM_DEFAULT_ENCODING")
     public Collection<File> generateSources(final SchemaContext context, final File outputBaseDir,
             final Set<Module> currentModules, final Function<Module, Optional<String>> moduleResourcePathResolver)
                     throws IOException {
@@ -56,48 +57,58 @@ public class StaticDocGenerator extends ApiDocGenerator implements BasicCodeGene
         } else {
             outputDir = outputBaseDir;
         }
-        outputDir.mkdirs();
+
+        if (!outputDir.mkdirs()) {
+            throw new IOException("Could not create directory " + outputDir);
+        }
 
         // Create Resources directory
         File resourcesDir = new File(outputDir, "resources");
-        resourcesDir.mkdirs();
+        if (!resourcesDir.mkdirs()) {
+            throw new IOException("Could not create directory " + resourcesDir);
+        }
 
         // Create JS file
         File resourcesJsFile = new File(outputDir, "resources.js");
-        resourcesJsFile.createNewFile();
-        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(resourcesJsFile));
-        ObjectMapper mapper = new ObjectMapper();
-        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
-
-        // Write resource listing to JS file
-        ResourceList resourceList = super.getResourceListing(null, context, "");
-        String resourceListJson = mapper.writeValueAsString(resourceList);
-        resourceListJson = resourceListJson.replace("\'", "\\\'").replace("\\n", "\\\\n");
-        bufferedWriter.write("function getSpec() {\n\treturn \'" + resourceListJson + "\';\n}\n\n");
-
-        // Write resources/APIs to JS file and to disk
-        bufferedWriter.write("function jsonFor(resource) {\n\tswitch(resource) {\n");
-        for (Resource resource : resourceList.getApis()) {
-            int revisionIndex = resource.getPath().indexOf('(');
-            String name = resource.getPath().substring(0, revisionIndex);
-            String revision = resource.getPath().substring(revisionIndex + 1, resource.getPath().length() - 1);
-            ApiDeclaration apiDeclaration = super.getApiDeclaration(name, revision, null, context, "");
-            String json = mapper.writeValueAsString(apiDeclaration);
-            // Manually insert models because org.json.JSONObject cannot be serialized by ObjectMapper
-            json = json.replace(
-                "\"models\":{}", "\"models\":" + apiDeclaration.getModels().toString().replace("\\\"", "\""));
-            // Escape single quotes and new lines
-            json = json.replace("\'", "\\\'").replace("\\n", "\\\\n");
-            bufferedWriter.write("\t\tcase \"" + name + "(" + revision + ")\": return \'" + json + "\';\n");
-
-            File resourceFile = new File(resourcesDir, name + "(" + revision + ").json");
-            BufferedWriter resourceFileWriter = new BufferedWriter(new FileWriter(resourceFile));
-            resourceFileWriter.write(json);
-            resourceFileWriter.close();
-            result.add(resourceFile);
+        if (!resourcesJsFile.createNewFile()) {
+            LOG.info("File " + resourcesJsFile + " already exists.");
+        }
+
+        try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(resourcesJsFile))) {
+            ObjectMapper mapper = new ObjectMapper();
+            mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+
+            // Write resource listing to JS file
+            ResourceList resourceList = super.getResourceListing(null, context, "");
+            String resourceListJson = mapper.writeValueAsString(resourceList);
+            resourceListJson = resourceListJson.replace("\'", "\\\'").replace("\\n", "\\\\n");
+            bufferedWriter.write("function getSpec() {\n\treturn \'" + resourceListJson + "\';\n}\n\n");
+
+            // Write resources/APIs to JS file and to disk
+            bufferedWriter.write("function jsonFor(resource) {\n\tswitch(resource) {\n");
+            for (Resource resource : resourceList.getApis()) {
+                int revisionIndex = resource.getPath().indexOf('(');
+                String name = resource.getPath().substring(0, revisionIndex);
+                String revision = resource.getPath().substring(revisionIndex + 1, resource.getPath().length() - 1);
+                ApiDeclaration apiDeclaration = super.getApiDeclaration(name, revision, null, context, "");
+                String json = mapper.writeValueAsString(apiDeclaration);
+                // Manually insert models because org.json.JSONObject cannot be serialized by ObjectMapper
+                json = json.replace(
+                        "\"models\":{}", "\"models\":" + apiDeclaration.getModels().toString().replace("\\\"", "\""));
+                // Escape single quotes and new lines
+                json = json.replace("\'", "\\\'").replace("\\n", "\\\\n");
+                bufferedWriter.write("\t\tcase \"" + name + "(" + revision + ")\": return \'" + json + "\';\n");
+
+                File resourceFile = new File(resourcesDir, name + "(" + revision + ").json");
+
+                try (BufferedWriter resourceFileWriter = new BufferedWriter(new FileWriter(resourceFile))) {
+                    resourceFileWriter.write(json);
+                }
+
+                result.add(resourceFile);
+            }
+            bufferedWriter.write("\t}\n\treturn \"\";\n}");
         }
-        bufferedWriter.write("\t}\n\treturn \"\";\n}");
-        bufferedWriter.close();
 
         result.add(resourcesJsFile);
         return result;
@@ -121,17 +132,13 @@ public class StaticDocGenerator extends ApiDocGenerator implements BasicCodeGene
 
     @Override
     public void setAdditionalConfig(final Map<String, String> additionalConfig) {
-        this.additionalConfig = additionalConfig;
     }
 
     @Override
     public void setResourceBaseDir(final File resourceBaseDir) {
-        this.resourceBaseDir = resourceBaseDir;
     }
 
     @Override
     public void setMavenProject(final MavenProject mavenProject) {
-        this.mavenProject = mavenProject;
-        this.projectBaseDir = mavenProject.getBasedir();
     }
 }
index 1f4b3b52c0e7c66a52d2f1723e5f2e1e2afa316b..76030f380c835952f19d1297950f69c69dd00bbc 100644 (file)
@@ -31,6 +31,7 @@ public class ApiDocGenerator extends BaseYangSwaggerGenerator {
     }
 
     public ApiDeclaration getApiDeclaration(final String module, final String revision, final UriInfo uriInfo) {
+        Preconditions.checkState(schemaService != null);
         final SchemaContext schemaContext = schemaService.getGlobalContext();
         Preconditions.checkState(schemaContext != null);
         return super.getApiDeclaration(module, revision, uriInfo, schemaContext, "");
@@ -43,10 +44,6 @@ public class ApiDocGenerator extends BaseYangSwaggerGenerator {
         return INSTANCE;
     }
 
-    public void setDraft(final boolean newDraft) {
-        super.setDraft(newDraft);
-    }
-
     public void setSchemaService(final SchemaService schemaService) {
         this.schemaService = schemaService;
     }
index 7db2161cc008d12421b6951566fe771277e5cef8..f309982e54bceb9a1c0d060ae6ba9c69b949f0d4 100644 (file)
@@ -10,7 +10,9 @@ 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.IOException;
 import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
 import java.nio.charset.StandardCharsets;
 import java.util.Map.Entry;
 import javax.ws.rs.core.Response;
@@ -82,7 +84,6 @@ public class ApiDocServiceImpl implements ApiDocService {
         return Response.seeOther(uriInfo.getBaseUriBuilder().path("../explorer/index.html").build()).build();
     }
 
-    @SuppressWarnings("checkstyle:IllegalCatch")
     @Override
     public synchronized Response getListOfMounts(final UriInfo uriInfo) {
         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -98,10 +99,16 @@ public class ApiDocServiceImpl implements ApiDocService {
             }
             writer.writeEndArray();
             writer.flush();
-        } catch (final Exception e) {
-            return Response.status(500).entity(e.getMessage()).build();
+        } catch (IOException e) {
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
+        }
+
+        try {
+            String responseStr = baos.toString(StandardCharsets.UTF_8.name());
+            return Response.status(Response.Status.OK).entity(responseStr).build();
+        } catch (UnsupportedEncodingException e) {
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
         }
-        return Response.status(200).entity(baos.toString()).build();
     }
 
     @Override
index 9c333f793c2e8aa282fb71348284a385460989d4..85462a76781aa3012edd3ca80caefce11ded5803 100644 (file)
@@ -42,7 +42,6 @@ import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
@@ -64,7 +63,7 @@ public class BaseYangSwaggerGenerator {
 
     // private Map<String, ApiDeclaration> MODULE_DOC_CACHE = new HashMap<>()
     private final ObjectMapper mapper = new ObjectMapper();
-    private static boolean newDraft;
+    private volatile boolean newDraft;
 
     protected BaseYangSwaggerGenerator() {
         this.mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
@@ -230,7 +229,7 @@ public class BaseYangSwaggerGenerator {
         return null;
     }
 
-    private static void addRootPostLink(final Module module, final DataNodeContainer node,
+    private void addRootPostLink(final Module module, final DataNodeContainer node,
             final List<Parameter> pathParams, final String resourcePath, final String dataStore, final List<Api> apis) {
         if (containsListOrContainer(module.getChildNodes())) {
             final Api apiForRootPostUri = new Api();
@@ -295,7 +294,7 @@ public class BaseYangSwaggerGenerator {
         }
     }
 
-    protected static String getContent(final String dataStore) {
+    protected String getContent(final String dataStore) {
         if (newDraft) {
             if ("operational".contains(dataStore)) {
                 return "?content=nonconfig";
@@ -352,9 +351,8 @@ public class BaseYangSwaggerGenerator {
         return operations;
     }
 
-    private static String createPath(final DataSchemaNode schemaNode, final List<Parameter> pathParams,
+    private String createPath(final DataSchemaNode schemaNode, final List<Parameter> pathParams,
             final SchemaContext schemaContext) {
-        final ArrayList<LeafSchemaNode> pathListParams = new ArrayList<>();
         final StringBuilder path = new StringBuilder();
         final String localName = resolvePathArgumentsName(schemaNode, schemaContext);
         path.append(localName);
@@ -368,7 +366,6 @@ public class BaseYangSwaggerGenerator {
 
             for (final QName listKey : listKeys) {
                 final DataSchemaNode dataChildByName = ((DataNodeContainer) schemaNode).getDataChildByName(listKey);
-                pathListParams.add((LeafSchemaNode) dataChildByName);
                 final String pathParamIdentifier;
                 if (newDraft) {
                     pathParamIdentifier = keyBuilder.append("{").append(listKey.getLocalName()).append("}").toString();
@@ -444,6 +441,10 @@ public class BaseYangSwaggerGenerator {
     }
 
     public void setDraft(final boolean draft) {
-        BaseYangSwaggerGenerator.newDraft = draft;
+        this.newDraft = draft;
+    }
+
+    protected boolean isNewDraft() {
+        return newDraft;
     }
 }
index 4a4eba98d1d2bc51d09b9cbeeb982b8076c31727..42c194aa95567c4ea36bf21b688a811e09788cdf 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.netconf.sal.rest.doc.model.builder;
 
+import com.google.common.collect.ImmutableList;
 import java.util.ArrayList;
 import java.util.List;
 import org.opendaylight.netconf.sal.rest.doc.swagger.Operation;
@@ -22,12 +23,7 @@ public final class OperationBuilder {
     public static final String CONFIG = "(config)";
     public static final String TOP = "-TOP";
 
-    public static final List<String> CONSUMES_PUT_POST = new ArrayList<>();
-
-    static {
-        CONSUMES_PUT_POST.add("application/json");
-        CONSUMES_PUT_POST.add("application/xml");
-    }
+    public static final List<String> CONSUMES_PUT_POST = ImmutableList.of("application/json", "application/xml");
 
     private OperationBuilder() {
 
index caf01d4ba55c08d25e9d60125be008a6da88ca3f..e81d1e5c158c37d56ba25bc6978704e100f7ac17 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.netconf.sal.rest.doc.mountpoints;
 
 import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedList;
@@ -39,7 +40,6 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
 
     private static final String DATASTORES_REVISION = "-";
     private static final String DATASTORES_LABEL = "Datastores";
-    private static final String RESTCONF_DRAFT = "18";
     private static final AtomicReference<MountPointSwagger> SELF_REF = new AtomicReference<>();
 
     private DOMMountPointService mountService;
@@ -51,9 +51,9 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
 
     private final AtomicLong idKey = new AtomicLong(0);
     private SchemaService globalSchema;
-    private static boolean newDraft;
 
     public Map<String, Long> getInstanceIdentifiers() {
+        Preconditions.checkState(globalSchema != null);
         final Map<String, Long> urlToId = new HashMap<>();
         synchronized (this.lock) {
             final SchemaContext context = this.globalSchema.getGlobalContext();
@@ -90,7 +90,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
             if (arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
                 final NodeIdentifierWithPredicates nodeId = (NodeIdentifierWithPredicates) arg;
                 for (final Entry<QName, Object> entry : nodeId.getKeyValues().entrySet()) {
-                    if (newDraft) {
+                    if (isNewDraft()) {
                         builder.deleteCharAt(builder.length() - 1).append("=").append(entry.getValue()).append('/');
                     } else {
                         builder.append(entry.getValue()).append('/');
@@ -104,6 +104,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
     }
 
     private String getYangMountUrl(final YangInstanceIdentifier key) {
+        Preconditions.checkState(globalSchema != null);
         final String modName = findModuleName(key, this.globalSchema.getGlobalContext());
         return generateUrlPrefixFromInstanceID(key, modName) + "yang-ext:mount";
     }
@@ -143,6 +144,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
             return null;
         }
 
+        Preconditions.checkState(mountService != null);
         final Optional<DOMMountPoint> mountPoint = this.mountService.getMountPoint(id);
         if (!mountPoint.isPresent()) {
             return null;
@@ -224,7 +226,8 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
             SELF_REF.compareAndSet(null, new MountPointSwagger());
             swagger = SELF_REF.get();
         }
-        newDraft = false;
+
+        swagger.setDraft(false);
         return swagger;
     }
 
@@ -234,7 +237,8 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
             SELF_REF.compareAndSet(null, new MountPointSwagger());
             swagger = SELF_REF.get();
         }
-        newDraft = true;
+
+        swagger.setDraft(true);
         return swagger;
     }
 }