From: Robert Varga Date: Mon, 27 Aug 2018 10:43:27 +0000 (+0200) Subject: Do not instantiate NormalizedNodes for filter X-Git-Tag: release/neon~139 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=1c545b9883f64305983a9c0ef73acdaa97866cc7;p=netconf.git Do not instantiate NormalizedNodes for filter Using ImmutableNodes.fromInstanceId() does not work for leaf nodes, as we do not have a value, which violates LeafNode contract -- leading to an IllegalStateException when a user attempts to read() a single leaf via a transaction. As it turns out, this is completely unnecessary, as all we are doing is iterating through the temporary NormalizedNode and creating NormalizedNodeStreamWriter events based on that. This patch replicates ImmutableNodes.fromInstanceId() logic, but simplifies it for this particular task, short-cutting NormalizedNode creation and emitting events directly as we are iterating over the YangInstanceIdentifier. JIRA: NETCONF-563 Change-Id: I0781e81d812ee979deaafb9dfa811e143866f4af Signed-off-by: Robert Varga --- diff --git a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java index 46bb6cbcd3..eb3613534a 100644 --- a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java +++ b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/NetconfUtil.java @@ -9,6 +9,7 @@ package org.opendaylight.netconf.util; import com.google.common.base.Preconditions; import java.io.IOException; +import java.util.Iterator; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -17,6 +18,8 @@ import org.opendaylight.netconf.api.DocumentedException; import org.opendaylight.netconf.api.xml.XmlElement; import org.opendaylight.netconf.api.xml.XmlNetconfConstants; import org.opendaylight.netconf.api.xml.XmlUtil; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; 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; @@ -74,4 +77,25 @@ public final class NetconfUtil { } } } + + public static void writeFilter(final YangInstanceIdentifier query, final DOMResult result, + final SchemaPath schemaPath, final SchemaContext context) throws IOException, XMLStreamException { + if (query.isEmpty()) { + // No query at all + return; + } + + final XMLStreamWriter xmlWriter = XML_FACTORY.createXMLStreamWriter(result); + try { + try (NormalizedNodeStreamWriter writer = + XMLStreamNormalizedNodeStreamWriter.create(xmlWriter, context, schemaPath)) { + final Iterator it = query.getPathArguments().iterator(); + final PathArgument first = it.next(); + StreamingContext.fromSchemaAndQNameChecked(context, first.getNodeType()).streamToWriter(writer, first, + it); + } + } finally { + xmlWriter.close(); + } + } } diff --git a/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/StreamingContext.java b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/StreamingContext.java new file mode 100644 index 0000000000..e1393609a5 --- /dev/null +++ b/netconf/netconf-util/src/main/java/org/opendaylight/netconf/util/StreamingContext.java @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2018 Pantheon Technologies, s.r.o. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.netconf.util; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter.UNKNOWN_SIZE; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode; +import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; +import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; +import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode; +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.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema; + +abstract class StreamingContext implements Identifiable { + private final T identifier; + + StreamingContext(final T identifier) { + this.identifier = identifier; + } + + static StreamingContext fromSchemaAndQNameChecked(final DataNodeContainer schema, final QName child) { + final Optional potential = findChildSchemaNode(schema, child); + checkArgument(potential.isPresent(), + "Supplied QName %s is not valid according to schema %s, potential children nodes: %s", child, schema, + schema.getChildNodes()); + + final DataSchemaNode result = potential.get(); + // We try to look up if this node was added by augmentation + if (schema instanceof DataSchemaNode && result.isAugmenting()) { + for (final AugmentationSchemaNode aug : ((AugmentationTarget)schema).getAvailableAugmentations()) { + final DataSchemaNode found = aug.getDataChildByName(result.getQName()); + if (found != null) { + return new Augmentation(aug, schema); + } + } + } + return fromDataSchemaNode(result); + } + + static StreamingContext fromDataSchemaNode(final DataSchemaNode potential) { + if (potential instanceof ContainerSchemaNode) { + return new Container((ContainerSchemaNode) potential); + } else if (potential instanceof ListSchemaNode) { + return fromListSchemaNode((ListSchemaNode) potential); + } else if (potential instanceof LeafSchemaNode) { + return new Leaf((LeafSchemaNode) potential); + } else if (potential instanceof ChoiceSchemaNode) { + return new Choice((ChoiceSchemaNode) potential); + } else if (potential instanceof LeafListSchemaNode) { + return fromLeafListSchemaNode((LeafListSchemaNode) potential); + } else if (potential instanceof AnyXmlSchemaNode) { + return new AnyXml((AnyXmlSchemaNode) potential); + } + return null; + } + + @Override + public final T getIdentifier() { + return identifier; + } + + abstract StreamingContext getChild(PathArgument child); + + abstract void streamToWriter(NormalizedNodeStreamWriter writer, PathArgument first, Iterator others) + throws IOException; + + abstract boolean isMixin(); + + private static Optional findChildSchemaNode(final DataNodeContainer parent, final QName child) { + DataSchemaNode potential = parent.getDataChildByName(child); + if (potential == null) { + potential = findChoice(Iterables.filter(parent.getChildNodes(), ChoiceSchemaNode.class), child); + } + return Optional.ofNullable(potential); + } + + private static ChoiceSchemaNode findChoice(final Iterable choices, final QName child) { + for (final ChoiceSchemaNode choice : choices) { + for (final CaseSchemaNode caze : choice.getCases().values()) { + if (findChildSchemaNode(caze, child).isPresent()) { + return choice; + } + } + } + return null; + } + + private static StreamingContext fromListSchemaNode(final ListSchemaNode potential) { + final List keyDefinition = potential.getKeyDefinition(); + if (keyDefinition == null || keyDefinition.isEmpty()) { + return new UnkeyedListMixin(potential); + } + return potential.isUserOrdered() ? new OrderedMapMixin(potential) + : new UnorderedMapMixin(potential); + } + + private static StreamingContext fromLeafListSchemaNode(final LeafListSchemaNode potential) { + return potential.isUserOrdered() ? new OrderedLeafListMixin(potential) + : new UnorderedLeafListMixin(potential); + } + + private abstract static class AbstractComposite extends StreamingContext { + AbstractComposite(final T identifier) { + super(identifier); + } + + @Override + final void streamToWriter(final NormalizedNodeStreamWriter writer, final PathArgument first, + final Iterator others) throws IOException { + if (!isMixin()) { + final QName type = getIdentifier().getNodeType(); + if (type != null) { + final QName firstType = first.getNodeType(); + checkArgument(type.equals(firstType), "Node QName must be %s was %s", type, firstType); + } + } + + emitElementStart(writer, first); + if (others.hasNext()) { + final PathArgument childPath = others.next(); + final StreamingContext childOp = getChildOperation(childPath); + childOp.streamToWriter(writer, childPath, others); + } + writer.endNode(); + } + + abstract void emitElementStart(NormalizedNodeStreamWriter writer, PathArgument arg) throws IOException; + + @SuppressWarnings("checkstyle:illegalCatch") + private StreamingContext getChildOperation(final PathArgument childPath) { + final StreamingContext childOp; + try { + childOp = getChild(childPath); + } catch (final RuntimeException e) { + throw new IllegalArgumentException(String.format("Failed to process child node %s", childPath), e); + } + checkArgument(childOp != null, "Node %s is not allowed inside %s", childPath, getIdentifier()); + return childOp; + } + } + + private abstract static class AbstractDataContainer extends AbstractComposite { + private final Map> byArg = new HashMap<>(); + private final DataNodeContainer schema; + + AbstractDataContainer(final T identifier, final DataNodeContainer schema) { + super(identifier); + this.schema = schema; + } + + @Override + final StreamingContext getChild(final PathArgument child) { + StreamingContext potential = byArg.get(child); + if (potential != null) { + return potential; + } + potential = fromLocalSchema(child); + if (potential != null) { + byArg.put(potential.getIdentifier(), potential); + } + return potential; + } + + private StreamingContext fromLocalSchema(final PathArgument child) { + if (child instanceof AugmentationIdentifier) { + return fromSchemaAndQNameChecked(schema, ((AugmentationIdentifier) child).getPossibleChildNames() + .iterator().next()); + } + return fromSchemaAndQNameChecked(schema, child.getNodeType()); + } + } + + private abstract static class AbstractMapMixin extends AbstractComposite { + private final ListEntry innerNode; + + AbstractMapMixin(final ListSchemaNode list) { + super(NodeIdentifier.create(list.getQName())); + this.innerNode = new ListEntry(new NodeIdentifierWithPredicates(list.getQName(), ImmutableMap.of()), list); + } + + @Override + final StreamingContext getChild(final PathArgument child) { + return child.getNodeType().equals(getIdentifier().getNodeType()) ? innerNode : null; + } + + @Override + final boolean isMixin() { + return true; + } + } + + private abstract static class AbstractSimple extends StreamingContext { + AbstractSimple(final T identifier) { + super(identifier); + } + + @Override + final StreamingContext getChild(final PathArgument child) { + return null; + } + + @Override + final boolean isMixin() { + return false; + } + } + + private static final class AnyXml extends AbstractSimple { + AnyXml(final AnyXmlSchemaNode schema) { + super(NodeIdentifier.create(schema.getQName())); + } + + @Override + void streamToWriter(final NormalizedNodeStreamWriter writer, final PathArgument first, + final Iterator others) throws IOException { + writer.anyxmlNode(getIdentifier(), null); + } + } + + private static final class Choice extends AbstractComposite { + private final ImmutableMap> byArg; + + Choice(final ChoiceSchemaNode schema) { + super(NodeIdentifier.create(schema.getQName())); + final ImmutableMap.Builder> byArgBuilder = ImmutableMap.builder(); + + for (final CaseSchemaNode caze : schema.getCases().values()) { + for (final DataSchemaNode cazeChild : caze.getChildNodes()) { + final StreamingContext childOp = fromDataSchemaNode(cazeChild); + byArgBuilder.put(childOp.getIdentifier(), childOp); + } + } + byArg = byArgBuilder.build(); + } + + @Override + StreamingContext getChild(final PathArgument child) { + return byArg.get(child); + } + + @Override + boolean isMixin() { + return true; + } + + @Override + void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException { + writer.startChoiceNode(getIdentifier(), UNKNOWN_SIZE); + } + } + + private static final class Leaf extends AbstractSimple { + Leaf(final LeafSchemaNode potential) { + super(new NodeIdentifier(potential.getQName())); + } + + @Override + void streamToWriter(final NormalizedNodeStreamWriter writer, final PathArgument first, + final Iterator others) throws IOException { + writer.leafNode(getIdentifier(), null); + } + } + + private static final class LeafListEntry extends AbstractSimple> { + LeafListEntry(final LeafListSchemaNode potential) { + super(new NodeWithValue<>(potential.getQName(), null)); + } + + @Override + void streamToWriter(final NormalizedNodeStreamWriter writer, final PathArgument first, + final Iterator others) throws IOException { + checkArgument(first instanceof NodeWithValue); + final NodeWithValue identifier = (NodeWithValue) first; + writer.leafSetEntryNode(identifier.getNodeType(), identifier.getValue()); + } + } + + private static final class ListEntry extends AbstractDataContainer { + ListEntry(final NodeIdentifierWithPredicates identifier, final ListSchemaNode schema) { + super(identifier, schema); + } + + @Override + boolean isMixin() { + return false; + } + + @Override + void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException { + final NodeIdentifierWithPredicates identifier = (NodeIdentifierWithPredicates) arg; + writer.startMapEntryNode(identifier, UNKNOWN_SIZE); + + for (Entry entry : identifier.getKeyValues().entrySet()) { + writer.leafNode(new NodeIdentifier(entry.getKey()), entry.getValue()); + } + } + } + + private static final class UnkeyedListItem extends AbstractDataContainer { + UnkeyedListItem(final ListSchemaNode schema) { + super(NodeIdentifier.create(schema.getQName()), schema); + } + + @Override + boolean isMixin() { + return false; + } + + @Override + void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException { + writer.startUnkeyedListItem(getIdentifier(), UNKNOWN_SIZE); + } + } + + private static final class Container extends AbstractDataContainer { + Container(final ContainerSchemaNode schema) { + super(NodeIdentifier.create(schema.getQName()), schema); + } + + @Override + boolean isMixin() { + return false; + } + + @Override + void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException { + writer.startContainerNode(getIdentifier(), UNKNOWN_SIZE); + } + } + + private abstract static class LeafListMixin extends AbstractComposite { + private final StreamingContext innerOp; + + LeafListMixin(final LeafListSchemaNode potential) { + super(NodeIdentifier.create(potential.getQName())); + innerOp = new LeafListEntry(potential); + } + + @Override + final StreamingContext getChild(final PathArgument child) { + return child instanceof NodeWithValue ? innerOp : null; + } + + @Override + final boolean isMixin() { + return true; + } + } + + private static final class OrderedLeafListMixin extends LeafListMixin { + OrderedLeafListMixin(final LeafListSchemaNode potential) { + super(potential); + } + + @Override + void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException { + writer.startOrderedLeafSet(getIdentifier(), UNKNOWN_SIZE); + } + } + + private static class UnorderedLeafListMixin extends LeafListMixin { + UnorderedLeafListMixin(final LeafListSchemaNode potential) { + super(potential); + } + + @Override + void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException { + writer.startLeafSet(getIdentifier(), UNKNOWN_SIZE); + } + } + + private static final class Augmentation extends AbstractDataContainer { + Augmentation(final AugmentationSchemaNode augmentation, final DataNodeContainer schema) { + super(DataSchemaContextNode.augmentationIdentifierFrom(augmentation), + EffectiveAugmentationSchema.create(augmentation, schema)); + } + + @Override + boolean isMixin() { + return true; + } + + @Override + void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException { + writer.startAugmentationNode(getIdentifier()); + } + } + + private static final class UnorderedMapMixin extends AbstractMapMixin { + UnorderedMapMixin(final ListSchemaNode list) { + super(list); + } + + @Override + void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException { + writer.startMapNode(getIdentifier(), UNKNOWN_SIZE); + } + } + + private static final class OrderedMapMixin extends AbstractMapMixin { + OrderedMapMixin(final ListSchemaNode list) { + super(list); + } + + @Override + void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException { + writer.startOrderedMapNode(getIdentifier(), UNKNOWN_SIZE); + } + } + + private static final class UnkeyedListMixin extends AbstractComposite { + private final UnkeyedListItem innerNode; + + UnkeyedListMixin(final ListSchemaNode list) { + super(NodeIdentifier.create(list.getQName())); + this.innerNode = new UnkeyedListItem(list); + } + + @Override + StreamingContext getChild(final PathArgument child) { + return child.getNodeType().equals(getIdentifier().getNodeType()) ? innerNode : null; + } + + @Override + boolean isMixin() { + return true; + } + + @Override + void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException { + writer.startUnkeyedList(getIdentifier(), UNKNOWN_SIZE); + } + } +} diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java index ea7abe2f74..9275020f3d 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/util/NetconfMessageTransformUtil.java @@ -209,15 +209,13 @@ public final class NetconfMessageTransformUtil { final SchemaContext ctx) { final NormalizedNodeAttrBuilder anyXmlBuilder = Builders.anyXmlBuilder() .withNodeIdentifier(NETCONF_FILTER_NODEID).withAttributes(SUBTREE_FILTER_ATTRIBUTES); - final NormalizedNode filterContent = ImmutableNodes.fromInstanceId(ctx, identifier); - final Element element = XmlUtil.createElement(BLANK_DOCUMENT, NETCONF_FILTER_QNAME.getLocalName(), Optional.of(NETCONF_FILTER_QNAME.getNamespace().toString())); element.setAttributeNS(NETCONF_FILTER_QNAME.getNamespace().toString(), NETCONF_TYPE_QNAME.getLocalName(), "subtree"); try { - NetconfUtil.writeNormalizedNode(filterContent, new DOMResult(element), SchemaPath.ROOT, ctx); + NetconfUtil.writeFilter(identifier, new DOMResult(element), SchemaPath.ROOT, ctx); } catch (IOException | XMLStreamException e) { throw new IllegalStateException("Unable to serialize filter element for path " + identifier, e); } diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java index 96a59a18bf..af0a8b238e 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/schema/mapping/NetconfMessageTransformerTest.java @@ -5,7 +5,6 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.netconf.sal.connect.netconf.schema.mapping; import static org.junit.Assert.assertEquals; @@ -31,6 +30,7 @@ import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTr import static org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil.toPath; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -234,6 +234,36 @@ public class NetconfMessageTransformerTest { assertEquals(schemaNode, schemaParent.getValue().iterator().next()); } + @Test + public void testGetConfigLeafRequest() throws Exception { + final DataContainerChild filter = toFilterStructure( + YangInstanceIdentifier.create(toId(NetconfState.QNAME), toId(Schemas.QNAME), toId(Schema.QNAME), + new NodeIdentifierWithPredicates(Schema.QNAME, ImmutableMap.of()), + toId(QName.create(Schemas.QNAME, "version"))), schema); + + final DataContainerChild source = NetconfBaseOps.getSourceNode(NETCONF_RUNNING_QNAME); + + final NetconfMessage netconfMessage = netconfMessageTransformer.toRpcRequest(toPath(NETCONF_GET_CONFIG_QNAME), + NetconfMessageTransformUtil.wrap(NETCONF_GET_CONFIG_QNAME, source, filter)); + + assertSimilarXml(netconfMessage, "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + ""); + } + @Test public void testGetConfigRequest() throws Exception { final DataContainerChild filter = toFilterStructure( @@ -477,8 +507,8 @@ public class NetconfMessageTransformerTest { assertEquals("now", leaf.getValue()); } - private void checkAction(QName actionQname, Node action , String inputLocalName, String inputNodeName, - String inputValue) { + private void checkAction(final QName actionQname, final Node action , final String inputLocalName, + final String inputNodeName, final String inputValue) { checkNode(action, null, actionQname.getLocalName(), null); Node childResetAt = action.getFirstChild(); @@ -488,7 +518,7 @@ public class NetconfMessageTransformerTest { assertEquals(firstChild.getData(), inputValue); } - private Node checkBasePartOfActionRequest(NetconfMessage actionRequest) { + private Node checkBasePartOfActionRequest(final NetconfMessage actionRequest) { Node baseRpc = actionRequest.getDocument().getFirstChild(); checkNode(baseRpc, "rpc", "rpc", NetconfMessageTransformUtil.NETCONF_QNAME.getNamespace().toString()); assertTrue(baseRpc.getLocalName().equals("rpc")); @@ -503,7 +533,7 @@ public class NetconfMessageTransformerTest { return childAction; } - private DOMDataTreeIdentifier prepareDataTreeId(Set nodeIdentifiers) { + private DOMDataTreeIdentifier prepareDataTreeId(final Set nodeIdentifiers) { YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder().append(nodeIdentifiers).build(); DOMDataTreeIdentifier domDataTreeIdentifier = @@ -512,7 +542,7 @@ public class NetconfMessageTransformerTest { return domDataTreeIdentifier; } - private ContainerNode initInputAction(QName qname, String value) { + private ContainerNode initInputAction(final QName qname, final String value) { ImmutableLeafNodeBuilder immutableLeafNodeBuilder = new ImmutableLeafNodeBuilder<>(); DataContainerChild build = immutableLeafNodeBuilder.withNodeIdentifier( NodeIdentifier.create(qname)).withValue(value).build(); @@ -521,8 +551,8 @@ public class NetconfMessageTransformerTest { return data; } - private void checkNode(Node childServer, String expectedLocalName, String expectedNodeName, - String expectedNamespace) { + private void checkNode(final Node childServer, final String expectedLocalName, final String expectedNodeName, + final String expectedNamespace) { assertNotNull(childServer); assertEquals(childServer.getLocalName(), expectedLocalName); assertEquals(childServer.getNodeName(), expectedNodeName);