summaryrefslogtreecommitdiffstats
path: root/v3po/vpp-translate-utils/src
diff options
context:
space:
mode:
authorMaros Marsalek <mmarsale@cisco.com>2016-05-17 09:10:39 +0200
committerMaros Marsalek <mmarsale@cisco.com>2016-05-23 09:24:12 +0000
commit799ee62f15dff07534beaf98a3ac551deffade38 (patch)
treea47c4696cf6ecff4fbb83c161c5d8e7e6b8af3c8 /v3po/vpp-translate-utils/src
parentf19306a9263cb8dd8c10a4867633fbbe14db2e4c (diff)
HONEYCOMB-61: Add BA broker for context data tree
With broker, context data can be accessed in a transactional manner, same as config data + Renamed data-api concepts to not include DataTree + Renamed context related concepts to better distinguish between them + Now passing full ReadContext to read customizers + Naming context is backed by context data broker Change-Id: I0b2876dd74a31a9ced7d9b5145672868e12f8b82 Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Diffstat (limited to 'v3po/vpp-translate-utils/src')
-rw-r--r--v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java10
-rw-r--r--v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/DataTreeNamingContext.java193
-rw-r--r--v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java89
-rw-r--r--v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java7
-rw-r--r--v3po/vpp-translate-utils/src/main/yang/vpp-util.yang9
5 files changed, 73 insertions, 235 deletions
diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java
index 45ac193cf..e1a5bf2bc 100644
--- a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java
+++ b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java
@@ -45,17 +45,17 @@ public abstract class AbstractInterfaceTypeCustomizer<D extends DataObject>
}
private void checkProperInterfaceType(@Nonnull final WriteContext writeContext,
- @Nonnull final InstanceIdentifier<D> id) {
+ @Nonnull final InstanceIdentifier<D> id) {
final InstanceIdentifier<Interface> ifcTypeFromIid = id.firstIdentifierOf(Interface.class);
checkArgument(ifcTypeFromIid != null, "Instance identifier does not contain {} type", Interface.class);
checkArgument(id.firstKeyOf(Interface.class) != null, "Instance identifier does not contain keyed {} type",
Interface.class);
- final Optional<DataObject> interfaceConfigOperational = writeContext.readAfter(ifcTypeFromIid);
- checkState(interfaceConfigOperational.isPresent(),
- "Unable to get Interface configuration for an interface being updated under ID");
+ final Optional<Interface> interfaceConfig = writeContext.readAfter(ifcTypeFromIid);
+ checkState(interfaceConfig.isPresent(),
+ "Unable to get Interface configuration for an interface: %s currently being updated", ifcTypeFromIid);
IllegalInterfaceTypeException
- .checkInterfaceType((Interface) interfaceConfigOperational.get(), getExpectedInterfaceType());
+ .checkInterfaceType(interfaceConfig.get(), getExpectedInterfaceType());
}
protected abstract Class<? extends InterfaceType> getExpectedInterfaceType();
diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/DataTreeNamingContext.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/DataTreeNamingContext.java
deleted file mode 100644
index 3b20b2876..000000000
--- a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/DataTreeNamingContext.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.honeycomb.v3po.translate.v3po.util;
-
-import com.google.common.collect.Lists;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.ThreadSafe;
-import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts;
-import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
-import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Naming context keeping a mapping between int index and string name.
- * Provides artificial names to unknown indices.
- */
-@ThreadSafe
-public class DataTreeNamingContext extends NamingContext {
-
- // FIXME this has to be accessed by readers/writers in a transactional manner and the transaction will only be committed once
- // the Read or Write operation finishes successfully
- // Context datatree has to become a first class citizen of Honeycomb, and Honeycomb needs to create and provide
- // context read write transaction as part of context to read/write customizers
- // This will then become just a utility writer relying on transaction provided by the infrastructure
- // Btw. the context transaction needs to disable commit/submit when being passed to customizers
-
- private static final Logger LOG = LoggerFactory.getLogger(DataTreeNamingContext.class);
-
- private static final QName NAME_KEY_QNAME = QName.create(Contexts.QNAME, "name");
- private static final QName INDEX_QNAME = QName.create(Contexts.QNAME, "index");
-
- private final String instanceName;
- private final DataTree contextDataTree;
-
- private final YangInstanceIdentifier.NodeIdentifierWithPredicates namingContextNodeId;
- private final YangInstanceIdentifier namingContextIid;
-
- public DataTreeNamingContext(final String artificialNamePrefix, final String instanceName,
- final DataTree contextDataTree) {
- super(artificialNamePrefix);
- this.instanceName = instanceName;
- this.contextDataTree = contextDataTree;
-
- namingContextNodeId = getNodeId(
- org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.QNAME,
- Collections.singletonMap(NAME_KEY_QNAME, instanceName));
- namingContextIid = YangInstanceIdentifier.create(
- getNodeId(Contexts.QNAME),
- getNodeId(org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.QNAME),
- namingContextNodeId);
-
- // FIXME read current mappings and initialize map
- mergeNewContextInDataTree(instanceName);
- }
-
- // TODO move the data tree aspect into a dedicated class
- private void mergeNewContextInDataTree(final String instanceName) {
- final DataTreeModification dataTreeModification = getModification();
-
- final YangInstanceIdentifier.NodeIdentifier namingContextsNodeIdForMapNode = getNodeId(
- org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.QNAME);
-
- final ContainerNode newMapping = Builders.containerBuilder()
- .withNodeIdentifier(getNodeId(Contexts.QNAME))
- .withChild(Builders.mapBuilder()
- .withNodeIdentifier(namingContextsNodeIdForMapNode)
- .withChild(Builders.mapEntryBuilder()
- .withNodeIdentifier(namingContextNodeId)
- .withChild(ImmutableNodes.leafNode(NAME_KEY_QNAME, instanceName))
- .withChild(Builders.containerBuilder()
- .withNodeIdentifier(getNodeId(Mappings.QNAME))
- .withChild(Builders.mapBuilder()
- .withNodeIdentifier(getNodeId(Mapping.QNAME))
- .build())
- .build())
- .build())
- .build())
- .build();
-
- // FIXME add logs or debug to resolve:
-// 2016-05-13 15:48:52,401 | WARN | config-pusher | DataTreeNamingContext | 240 - io.fd.honeycomb.v3po.vpp-translate-utils - 1.0.0.SNAPSHOT | Unable to update context: interface-context in context data tree
-// org.opendaylight.yangtools.yang.data.api.schema.tree.ModifiedNodeDoesNotExistException: Node /(urn:honeycomb:params:xml:ns:yang:naming:context?revision=2016-05-13)contexts/naming-context/naming-context[{(urn:honeycomb:params:xml:ns:yang:naming:context?revision=2016-05-13)name=interface-context}] does not exist. Cannot apply modification to its children.
-// at org.opendaylight.yangtools.yang.data.impl.schema.tree.AbstractNodeContainerModificationStrategy.checkTouchApplicable(AbstractNodeContainerModificationStrategy.java:276)[55:org.opendaylight.yangtools.yang-data-impl:0.8.0.Beryllium]
- // FIXME looks like a timing issue, did not occur when debugging
-
- dataTreeModification.merge(YangInstanceIdentifier.create(getNodeId(Contexts.QNAME)), newMapping);
-
- commitModification(dataTreeModification);
- }
-
- private void commitModification(final DataTreeModification dataTreeModification) {
- try {
- dataTreeModification.ready();
- contextDataTree.validate(dataTreeModification);
- contextDataTree.commit(contextDataTree.prepare(dataTreeModification));
- } catch (DataValidationFailedException e) {
- LOG.warn("Unable to update context: {} in context data tree", instanceName, e);
- throw new IllegalStateException("Unable to update context in context data tree", e);
- }
- }
-
- private DataTreeModification getModification() {
- final DataTreeSnapshot dataTreeSnapshot = contextDataTree.takeSnapshot();
- return dataTreeSnapshot.newModification();
- }
-
- private static YangInstanceIdentifier.NodeIdentifierWithPredicates getNodeId(@Nonnull final QName qName,
- @Nonnull final Map<QName, Object> keys) {
- return new YangInstanceIdentifier.NodeIdentifierWithPredicates(qName, keys);
- }
-
- private static YangInstanceIdentifier.NodeIdentifier getNodeId(@Nonnull final QName qName) {
- return new YangInstanceIdentifier.NodeIdentifier(qName);
- }
-
- public synchronized void addName(final int index, final String name) {
- addMappingToDataTree(name, index);
- super.addName(index, name);
- }
-
- private void addMappingToDataTree(final String name, final int index) {
- final DataTreeModification dataTreeModification = getModification();
-
- final YangInstanceIdentifier.NodeIdentifierWithPredicates mappingNodeId = getNodeId(Mapping.QNAME,
- Collections.singletonMap(NAME_KEY_QNAME, name));
-
- final List<YangInstanceIdentifier.PathArgument> pathArguments = namingContextIid.getPathArguments();
- final ArrayList<YangInstanceIdentifier.PathArgument> newPathArgs = Lists.newArrayList(pathArguments);
- newPathArgs.add(getNodeId(Mappings.QNAME));
- newPathArgs.add(getNodeId(Mapping.QNAME));
- newPathArgs.add(mappingNodeId);
-
- final YangInstanceIdentifier identifier = YangInstanceIdentifier.create(newPathArgs);
-
- final NormalizedNode<?, ?> newMapping = Builders.mapEntryBuilder()
- .withNodeIdentifier(mappingNodeId)
- .withChild(ImmutableNodes.leafNode(NAME_KEY_QNAME, name))
- .withChild(ImmutableNodes.leafNode(INDEX_QNAME, index))
- .build();
-
- dataTreeModification.write(identifier, newMapping);
-
- commitModification(dataTreeModification);
- }
-
- public synchronized int removeName(@Nonnull final String name) {
- removeMappingFromDataTree(name);
- return super.removeName(name);
- }
-
- private void removeMappingFromDataTree(final String name) {
- final DataTreeModification dataTreeModification = getModification();
-
- final YangInstanceIdentifier.NodeIdentifierWithPredicates mappingNodeId = getNodeId(Mapping.QNAME,
- Collections.singletonMap(NAME_KEY_QNAME, name));
-
- final YangInstanceIdentifier identifier = YangInstanceIdentifier.create(
- namingContextIid.getLastPathArgument(), getNodeId(Mappings.QNAME), getNodeId(Mapping.QNAME), mappingNodeId);
-
- dataTreeModification.delete(identifier);
-
- commitModification(dataTreeModification);
- }
-}
diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java
index 9affd0695..d32f27203 100644
--- a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java
+++ b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java
@@ -17,48 +17,88 @@
package io.fd.honeycomb.v3po.translate.v3po.util;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
+import com.google.common.base.Optional;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContextKey;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Naming context keeping a mapping between int index and string name.
- * Provides artificial names to unknown indices.
+ * Utility adapter on top of {@link MappingContext}
*/
-public class NamingContext implements AutoCloseable {
+public final class NamingContext implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(NamingContext.class);
- private final BiMap<String, Integer> nameMapping = HashBiMap.create();
private final String artificialNamePrefix;
+ private KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext, NamingContextKey>
+ namingContextIid;
- public NamingContext(final String artificialNamePrefix) {
+ /**
+ * Collector expecting only a single resulting item from a stream
+ */
+ private static final Collector<Mapping, ?, Mapping> SINGLE_ITEM_COLLECTOR = Collectors.collectingAndThen(
+ Collectors.toList(),
+ list -> {
+ if (list.size() != 1) {
+ throw new IllegalStateException("Unexpected size of list: " + list + ". Single item expected");
+ }
+ return list.get(0);
+ });
+
+ public NamingContext(final String artificialNamePrefix, final String instanceName) {
this.artificialNamePrefix = artificialNamePrefix;
+ namingContextIid = InstanceIdentifier.create(Contexts.class).child(
+ org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.class,
+ new NamingContextKey(instanceName));
}
@Nonnull
- public synchronized String getName(final int index) {
- if(!nameMapping.inverse().containsKey(index)) {
+ public synchronized String getName(final int index, final MappingContext mappingContext) {
+ if (!containsName(index, mappingContext)) {
final String artificialName = getArtificialName(index);
LOG.info("Assigning artificial name: {} for index: {}", artificialName, index);
- addName(index, artificialName);
+ addName(index, artificialName, mappingContext);
}
- return nameMapping.inverse().get(index);
+
+ final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class));
+ checkState(read.isPresent(), "Mapping for index: %s is not present. But should be", index);
+
+ return read.get().getMapping().stream()
+ .filter(mapping -> mapping.getIndex().equals(index))
+ .collect(SINGLE_ITEM_COLLECTOR).getName();
+ }
+
+ public synchronized boolean containsName(final int index, final MappingContext mappingContext) {
+ final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class));
+ return read.isPresent()
+ ? read.get().getMapping().stream().anyMatch(mapping -> mapping.getIndex().equals(index))
+ : false;
}
- public synchronized boolean containsName(final int index) {
- return nameMapping.inverse().containsKey(index);
+ public synchronized void addName(final int index, final String name, final MappingContext mappingContext) {
+ final KeyedInstanceIdentifier<Mapping, MappingKey> mappingIid = getMappingIid(name);
+ mappingContext.put(mappingIid, new MappingBuilder().setIndex(index).setName(name).build());
}
- public synchronized void addName(final int index, final String name) {
- nameMapping.put(name, index);
+ private KeyedInstanceIdentifier<Mapping, MappingKey> getMappingIid(final String name) {
+ return namingContextIid.child(Mappings.class).child(Mapping.class, new MappingKey(name));
}
- public synchronized int removeName(final String name) {
- return nameMapping.remove(name);
+ public synchronized void removeName(final String name, final MappingContext mappingContext) {
+ mappingContext.delete(getMappingIid(name));
}
/**
@@ -68,14 +108,15 @@ public class NamingContext implements AutoCloseable {
* @return integer index value matching supplied name
* @throws IllegalArgumentException if name was not found
*/
- public synchronized int getIndex(String name) {
- checkArgument(nameMapping.containsKey(name), "Name %s not found. Known names: %s",
- name, nameMapping);
- return nameMapping.get(name);
+ public synchronized int getIndex(final String name, final MappingContext mappingContext) {
+ final Optional<Mapping> read = mappingContext.read(getMappingIid(name));
+ checkArgument(read.isPresent(), "No mapping stored for name: %s", name);
+ return read.get().getIndex();
+
}
- public synchronized boolean containsIndex(String interfaceName) {
- return nameMapping.containsKey(interfaceName);
+ public synchronized boolean containsIndex(final String name, final MappingContext mappingContext) {
+ return mappingContext.read(getMappingIid(name)).isPresent();
}
private String getArtificialName(final int index) {
@@ -84,6 +125,6 @@ public class NamingContext implements AutoCloseable {
@Override
public void close() throws Exception {
- nameMapping.clear();
+ /// Not removing the mapping from backing storage
}
}
diff --git a/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java b/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java
index 50b577a25..60a816d89 100644
--- a/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java
+++ b/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java
@@ -1,6 +1,6 @@
package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.util.rev160406;
-import io.fd.honeycomb.v3po.translate.v3po.util.DataTreeNamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
public class NamingContextImplModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.util.rev160406.AbstractNamingContextImplModule {
public NamingContextImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -18,10 +18,9 @@ public class NamingContextImplModule extends org.opendaylight.yang.gen.v1.urn.ho
@Override
public java.lang.AutoCloseable createInstance() {
- return new DataTreeNamingContext(
+ return new NamingContext(
getArtificialNamePrefix(),
- getIdentifier().getInstanceName(),
- getContextDataTreeDependency());
+ getIdentifier().getInstanceName());
}
}
diff --git a/v3po/vpp-translate-utils/src/main/yang/vpp-util.yang b/v3po/vpp-translate-utils/src/main/yang/vpp-util.yang
index bd903848c..23615d09e 100644
--- a/v3po/vpp-translate-utils/src/main/yang/vpp-util.yang
+++ b/v3po/vpp-translate-utils/src/main/yang/vpp-util.yang
@@ -31,15 +31,6 @@ module vpp-util {
leaf artificial-name-prefix {
type string;
}
-
- container context-data-tree {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity dapi:data-tree;
- }
- }
- }
}
}