Merge "Simplify boolean expressions"
authorJakub Morvay <jmorvay@cisco.com>
Wed, 23 Aug 2017 08:40:31 +0000 (08:40 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 23 Aug 2017 08:40:31 +0000 (08:40 +0000)
netconf/aaa-authn-odl-plugin/src/main/java/org/opendaylight/aaa/odl/CredentialServiceAuthProvider.java
netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/EditConfig.java
netconf/mdsal-netconf-connector/src/test/java/org/opendaylight/netconf/mdsal/connector/ops/NetconfMDSalMappingTest.java
netconf/netconf-util/pom.xml
netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java
netconf/tools/netconf-cli/src/main/java/org/opendaylight/netconf/cli/writer/custom/DataWriter.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/restconf/impl/RestconfImpl.java
restconf/sal-rest-connector/src/main/java/org/opendaylight/netconf/sal/streams/listeners/AbstractNotificationsData.java
restconf/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java

index 19e72dfe08bf9aec4d1397b085a3271e8e1de2df..3d86ee1751adfd5037c8c369a42124e4a3f0f442 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.aaa.odl;
 
-import java.util.Map;
 import org.opendaylight.aaa.api.AuthenticationException;
 import org.opendaylight.aaa.api.Claim;
 import org.opendaylight.aaa.api.CredentialAuth;
@@ -27,11 +26,6 @@ import org.slf4j.LoggerFactory;
 public final class CredentialServiceAuthProvider implements AuthProvider, AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(CredentialServiceAuthProvider.class);
 
-    /**
-     * Singleton instance with delayed instantiation.
-     */
-    public static volatile Map.Entry<BundleContext, CredentialServiceAuthProvider> INSTANCE;
-
     // FIXME CredentialAuth is generic and it causes warnings during compilation
     // Maybe there should be a PasswordCredentialAuth implements CredentialAuth<PasswordCredentials>
     private volatile CredentialAuth<PasswordCredentials> nullableCredService;
index f7ad8b5ffa8488495025969958046e0892c3f189..7c86dd26b44b8307ca4e0f08a1619139f4af1359 100644 (file)
@@ -8,8 +8,10 @@
 
 package org.opendaylight.netconf.mdsal.connector.ops;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableMap;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -260,7 +262,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
     }
 
     private static Datastore extractTargetParameter(final XmlElement operationElement) throws DocumentedException {
-        final NodeList elementsByTagName = operationElement.getDomElement().getElementsByTagName(TARGET_KEY);
+        final NodeList elementsByTagName = getElementsByTagName(operationElement, TARGET_KEY);
         // Direct lookup instead of using XmlElement class due to performance
         if (elementsByTagName.getLength() == 0) {
             final Map<String, String> errorInfo = ImmutableMap.of("bad-attribute", TARGET_KEY, "bad-element",
@@ -278,7 +280,7 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
     }
 
     private static ModifyAction getDefaultOperation(final XmlElement operationElement) throws DocumentedException {
-        final NodeList elementsByTagName = operationElement.getDomElement().getElementsByTagName(DEFAULT_OPERATION_KEY);
+        final NodeList elementsByTagName = getElementsByTagName(operationElement, DEFAULT_OPERATION_KEY);
         if (elementsByTagName.getLength() == 0) {
             return ModifyAction.MERGE;
         } else if (elementsByTagName.getLength() > 1) {
@@ -303,6 +305,21 @@ public class EditConfig extends AbstractSingletonNetconfOperation {
         return childNode.get();
     }
 
+    @VisibleForTesting
+    static NodeList getElementsByTagName(final XmlElement operationElement, final String key) throws
+            DocumentedException {
+        final Element element = operationElement.getDomElement();
+        final NodeList elementsByTagName;
+
+        if (Strings.isNullOrEmpty(element.getPrefix())) {
+            elementsByTagName = element.getElementsByTagName(key);
+        } else {
+            elementsByTagName = element.getElementsByTagNameNS(operationElement.getNamespace(), key);
+        }
+
+        return elementsByTagName;
+    }
+
     @Override
     protected String getOperationName() {
         return OPERATION_NAME;
index 4d53fa3999b22493b98e3703176d2832d09d1cbc..d44bc8482eea020d7e41e88253957f349754aaa7 100644 (file)
@@ -32,9 +32,11 @@ import javax.xml.transform.stream.StreamResult;
 import org.custommonkey.xmlunit.DetailedDiff;
 import org.custommonkey.xmlunit.Diff;
 import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.opendaylight.controller.cluster.databroker.ConcurrentDOMDataBroker;
 import org.opendaylight.controller.config.util.xml.DocumentedException;
@@ -69,12 +71,14 @@ import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
 public class NetconfMDSalMappingTest {
     private static final Logger LOG = LoggerFactory.getLogger(NetconfMDSalMappingTest.class);
 
+    private static final String TARGET_KEY = "target";
     private static final String RPC_REPLY_ELEMENT = "rpc-reply";
     private static final String DATA_ELEMENT = "data";
     private static final String FILTER_NODE = "filter";
@@ -329,11 +333,11 @@ public class NetconfMDSalMappingTest {
     @Test
     public void testAugmentedContainerReplace() throws Exception {
         verifyResponse(edit("messages/mapping/editConfigs/editConfig_empty_modules_create.xml"),
-            RPC_REPLY_OK);
+                RPC_REPLY_OK);
         verifyResponse(commit(), RPC_REPLY_OK);
 
         verifyResponse(edit("messages/mapping/editConfigs/editConfig_augmented_container_replace.xml"),
-            RPC_REPLY_OK);
+                RPC_REPLY_OK);
         verifyResponse(commit(), RPC_REPLY_OK);
 
         deleteDatastore();
@@ -342,11 +346,11 @@ public class NetconfMDSalMappingTest {
     @Test
     public void testLeafFromAugmentReplace() throws Exception {
         verifyResponse(edit("messages/mapping/editConfigs/editConfig_empty_modules_create.xml"),
-            RPC_REPLY_OK);
+                RPC_REPLY_OK);
         verifyResponse(commit(), RPC_REPLY_OK);
 
         verifyResponse(edit("messages/mapping/editConfigs/editConfig_leaf_from_augment_replace.xml"),
-            RPC_REPLY_OK);
+                RPC_REPLY_OK);
         verifyResponse(commit(), RPC_REPLY_OK);
 
         deleteDatastore();
@@ -538,6 +542,61 @@ public class NetconfMDSalMappingTest {
         deleteDatastore();
     }
 
+    @Test
+    public void testEditConfigGetElementByTagName() throws Exception {
+        EditConfig editConfig = new EditConfig("test_edit-config", Mockito.mock(CurrentSchemaContext.class),
+                Mockito.mock(TransactionProvider.class));
+
+        String stringWithoutPrefix =
+                "<rpc xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"0\">\n"
+                        + "  <edit-config>\n"
+                        + "    <target>\n"
+                        + "      <candidate/>\n"
+                        + "    </target>\n"
+                        + "  </edit-config>\n"
+                        + "</rpc>";
+        XmlElement xe = getXmlElement(stringWithoutPrefix);
+        NodeList nodeList = editConfig.getElementsByTagName(xe, TARGET_KEY);
+        Assert.assertEquals(1, nodeList.getLength());
+
+        String stringWithPrefix =
+                "<nc:rpc xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"0\">\n"
+                        + "  <nc:edit-config>\n"
+                        + "    <nc:target>\n"
+                        + "      <nc:candidate/>\n"
+                        + "    </nc:target>\n"
+                        + "  </nc:edit-config>\n"
+                        + "</nc:rpc>";
+
+        xe = getXmlElement(stringWithPrefix);
+        nodeList = editConfig.getElementsByTagName(xe, TARGET_KEY);
+        Assert.assertEquals(1, nodeList.getLength());
+
+        String stringWithoutTarget =
+                "<nc:rpc xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\" message-id=\"0\">\n"
+                        + "  <nc:edit-config>\n"
+                        + "    <nc:target>\n"
+                        + "    </nc:target>\n"
+                        + "  </nc:edit-config>\n"
+                        + "</nc:rpc>";
+        xe = getXmlElement(stringWithoutTarget);
+
+        try {
+            nodeList = editConfig.getElementsByTagName(xe, TARGET_KEY);
+            XmlElement.fromDomElement((Element) nodeList.item(0)).getOnlyChildElement();
+            Assert.fail("Not specified target, we should fail");
+        } catch (DocumentedException documentedException) {
+            // Ignore
+        }
+
+    }
+
+    private XmlElement getXmlElement(final String elementAsString) throws Exception {
+        Document document = XmlUtil.readXmlToDocument(elementAsString);
+        Element element = document.getDocumentElement();
+        return XmlElement.fromDomElement(element);
+    }
+
     @Test
     public void testReplaceMapEntry() throws Exception {
         verifyResponse(edit("messages/mapping/editConfigs/edit-config-replace-map-entry.xml"), RPC_REPLY_OK);
index 6cb0fca5df74b5af3c45fe535c57eee14386e1cb..c5c94ada2976d18b40fa7ff7ac74ff282c4997e6 100644 (file)
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-data-impl</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-data-codec-xml</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.osgi</groupId>
       <artifactId>org.osgi.compendium</artifactId>
index d81e5c9be72c37df19bcb7c69b3c240c41308991..134aefecc23e4ef19b6ccb85117d249c2870cda4 100644 (file)
@@ -21,7 +21,7 @@ import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
 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.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.slf4j.Logger;
@@ -40,7 +40,7 @@ public final class NetconfUtil {
 
     private NetconfUtil() {}
 
-    public static Document checkIsMessageOk(Document response) throws DocumentedException {
+    public static Document checkIsMessageOk(final Document response) throws DocumentedException {
         XmlElement element = XmlElement.fromDomDocument(response);
         Preconditions.checkState(element.getName().equals(XmlMappingConstants.RPC_REPLY_KEY));
         element = element.getOnlyChildElement();
index 05cca30c3d3aedc35bab4ee97c4672df1dd083c9..cd999405f6ad7f243716cb3434bec5ea05f6dec6 100644 (file)
@@ -20,7 +20,7 @@ import org.opendaylight.netconf.cli.writer.impl.NormalizedNodeWriter;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
+import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
@@ -50,7 +50,7 @@ public class DataWriter extends AbstractWriter<DataSchemaNode> {
 
         for (final Object childNodeObject : ((DataContainerNode) dataNode).getValue()) {
             final NormalizedNode<?, ?> childNode = (NormalizedNode<?, ?>) childNodeObject;
-            final Optional<DataSchemaNode> schemaNode = XmlDocumentUtils.findFirstSchema(childNode.getNodeType(),
+            final Optional<DataSchemaNode> schemaNode = SchemaUtils.findFirstSchema(childNode.getNodeType(),
                 remoteSchemaContext.getDataDefinitions());
             Preconditions.checkState(schemaNode.isPresent(), "Unknown data node %s, not defined in schema",
                 childNode.getNodeType());
index 4abc492dff87e6bdadcd89e000507358faab2115..19a130fafe6f921aecda5c6f30ea8e7480dd00aa 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.netconf.sal.restconf.impl;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.CharMatcher;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
@@ -37,6 +38,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.ExecutionException;
@@ -830,7 +832,7 @@ public class RestconfImpl implements RestconfService {
             try {
                 result.getFutureOfPutData().checkedGet();
                 return Response.status(result.getStatus()).build();
-            } catch (TransactionCommitFailedException e) {
+            } catch (final TransactionCommitFailedException e) {
                 if (e instanceof OptimisticLockFailedException) {
                     if (--tries <= 0) {
                         LOG.debug("Got OptimisticLockFailedException on last try - failing " + identifier);
@@ -893,7 +895,8 @@ public class RestconfImpl implements RestconfService {
         }
     }
 
-    private static void isEqualUriAndPayloadKeyValues(final Map<QName, Object> uriKeyValues, final MapEntryNode payload,
+    @VisibleForTesting
+    public static void isEqualUriAndPayloadKeyValues(final Map<QName, Object> uriKeyValues, final MapEntryNode payload,
             final List<QName> keyDefinitions) {
 
         final Map<QName, Object> mutableCopyUriKeyValues = Maps.newHashMap(uriKeyValues);
@@ -905,7 +908,7 @@ public class RestconfImpl implements RestconfService {
 
             final Object dataKeyValue = payload.getIdentifier().getKeyValues().get(keyDefinition);
 
-            if (!uriKeyValue.equals(dataKeyValue)) {
+            if (!Objects.deepEquals(uriKeyValue, dataKeyValue)) {
                 final String errMsg = "The value '" + uriKeyValue + "' for key '" + keyDefinition.getLocalName()
                         + "' specified in the URI doesn't match the value '" + dataKeyValue
                         + "' specified in the message body. ";
@@ -978,7 +981,7 @@ public class RestconfImpl implements RestconfService {
             future.checkedGet();
         } catch (final RestconfDocumentedException e) {
             throw e;
-        } catch (TransactionCommitFailedException e) {
+        } catch (final TransactionCommitFailedException e) {
             LOG.info("Error creating data " + (uriInfo != null ? uriInfo.getPath() : ""), e);
             throw new RestconfDocumentedException(e.getMessage(), e, e.getErrorList());
         }
@@ -1059,7 +1062,7 @@ public class RestconfImpl implements RestconfService {
 
         try {
             future.checkedGet();
-        } catch (TransactionCommitFailedException e) {
+        } catch (final TransactionCommitFailedException e) {
             final Optional<Throwable> searchedException = Iterables.tryFind(Throwables.getCausalChain(e),
                     Predicates.instanceOf(ModifiedNodeDoesNotExistException.class));
             if (searchedException.isPresent()) {
@@ -1173,7 +1176,7 @@ public class RestconfImpl implements RestconfService {
         final TemporalAccessor p;
         try {
             p = FORMATTER.parse(value);
-        } catch (DateTimeParseException e) {
+        } catch (final DateTimeParseException e) {
             throw new RestconfDocumentedException("Cannot parse of value in date: " + value, e);
         }
         return Instant.from(p);
index f531a62a8d08e3bad3f4089842c22bc1c1b27461..8b548ade594341a9bdde0e05a9a3bd87d2962c70 100644 (file)
@@ -36,7 +36,6 @@ 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.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;
 import org.slf4j.Logger;
@@ -51,6 +50,7 @@ import org.w3c.dom.Element;
 abstract class AbstractNotificationsData {
     private static final Logger LOG = LoggerFactory.getLogger(AbstractNotificationsData.class);
     private static final TransformerFactory TF = TransformerFactory.newInstance();
+    private static final XMLOutputFactory OF = XMLOutputFactory.newFactory();
 
     private TransactionChainHandler transactionChainHandler;
     private SchemaContextHandler schemaHandler;
@@ -124,15 +124,14 @@ abstract class AbstractNotificationsData {
      */
     protected DOMResult writeNormalizedNode(final NormalizedNode<?, ?> normalized, final SchemaContext context,
             final SchemaPath schemaPath) throws IOException, XMLStreamException {
-        final XMLOutputFactory xmlFactory = XMLOutputFactory.newFactory();
-        final Document doc = XmlDocumentUtils.getDocument();
+        final Document doc = UntrustedXML.newDocumentBuilder().newDocument();
         final DOMResult result = new DOMResult(doc);
         NormalizedNodeWriter normalizedNodeWriter = null;
         NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
         XMLStreamWriter writer = null;
 
         try {
-            writer = xmlFactory.createXMLStreamWriter(result);
+            writer = OF.createXMLStreamWriter(result);
             normalizedNodeStreamWriter = XMLStreamNormalizedNodeStreamWriter.create(writer, context, schemaPath);
             normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(normalizedNodeStreamWriter);
 
index 37b0e595ce1ce798298e2f274dfbae1147a14295..c08b3349989469d993b880f86fc458d0e98ebef6 100644 (file)
@@ -24,8 +24,11 @@ import com.google.common.util.concurrent.Futures;
 import java.io.FileNotFoundException;
 import java.net.URI;
 import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import javax.ws.rs.core.MultivaluedHashMap;
@@ -43,14 +46,20 @@ import org.opendaylight.netconf.sal.restconf.impl.BrokerFacade;
 import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
 import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
 import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
+import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
 import org.opendaylight.netconf.sal.restconf.impl.RestconfImpl;
 import org.opendaylight.netconf.sal.streams.listeners.Notificator;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
@@ -84,6 +93,44 @@ public class RestconfImplTest {
         this.restconfImpl.setControllerContext(controllerContext);
     }
 
+    @Test
+    public void binaryKeyTest() {
+        final List<Byte> al = new ArrayList<>();
+        al.add(new Byte((byte) 1));
+        binaryKeyTest(al, al);
+    }
+
+    private void binaryKeyTest(final List<Byte> al, final List<Byte> al2) {
+
+        final QName keyDef = QName.create("test:key:binary", "2017-14-08", "b1");
+
+        final Map<QName, Object> uriKeyValues = new HashMap<>();
+        uriKeyValues.put(keyDef, al.toArray());
+
+        final MapEntryNode payload = mock(MapEntryNode.class);
+        final NodeIdentifierWithPredicates nodeIdWithPred =
+                new NodeIdentifierWithPredicates(keyDef, keyDef, al2.toArray());
+        when(payload.getIdentifier()).thenReturn(nodeIdWithPred);
+
+        final List<QName> keyDefinitions = new ArrayList<>();
+        keyDefinitions.add(keyDef);
+        RestconfImpl.isEqualUriAndPayloadKeyValues(uriKeyValues, payload, keyDefinitions);
+    }
+
+    @Test
+    public void binaryKeyFailTest() {
+        final List<Byte> al = new ArrayList<>();
+        al.add(new Byte((byte) 1));
+        final List<Byte> al2 = new ArrayList<>();
+        try {
+            binaryKeyTest(al, al2);
+        } catch (final RestconfDocumentedException e) {
+            final RestconfError err = e.getErrors().iterator().next();
+            assertEquals(ErrorType.PROTOCOL, err.getErrorType());
+            assertEquals(ErrorTag.INVALID_VALUE, err.getErrorTag());
+        }
+    }
+
     @SuppressWarnings("unchecked")
     @Test
     public void testExample() throws FileNotFoundException, ParseException {