*/
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;
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;
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;
}
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",
}
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) {
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;
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;
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";
@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();
@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();
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);
<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>
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;
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();
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;
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());
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;
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;
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);
}
}
- 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);
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. ";
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());
}
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()) {
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);
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;
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;
*/
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);
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;
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;
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 {