X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-dom-adapter%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fdom%2Fadapter%2FBindingToNormalizedNodeCodec.java;h=d296fa2fc329b036cbf4a7d78226b64cea226ac7;hb=e8046bf8787da3e07b463c5729bf0137717714f0;hp=55fde2cd655b19b5e47517d3ca0ec7895f84cf50;hpb=6e6ebc43866204667658f8bbf7cfb6233caffdc7;p=mdsal.git diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java index 55fde2cd65..d296fa2fc3 100644 --- a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java +++ b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingToNormalizedNodeCodec.java @@ -11,6 +11,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; +import com.google.common.annotations.Beta; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -21,28 +22,26 @@ import java.lang.reflect.Method; import java.time.Instant; import java.util.AbstractMap.SimpleEntry; import java.util.Collection; -import java.util.HashSet; import java.util.Map.Entry; import java.util.Optional; -import java.util.Set; import java.util.concurrent.TimeUnit; -import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.PreDestroy; import javax.inject.Inject; import javax.inject.Singleton; import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.binding.runtime.api.BindingRuntimeContext; +import org.opendaylight.binding.runtime.api.BindingRuntimeGenerator; +import org.opendaylight.binding.runtime.api.ClassLoadingStrategy; +import org.opendaylight.binding.runtime.api.DefaultBindingRuntimeContext; import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree; import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeFactory; -import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeNode; import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode; import org.opendaylight.mdsal.binding.dom.codec.api.BindingLazyContainerNode; import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; +import org.opendaylight.mdsal.binding.dom.codec.api.MissingSchemaException; import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry; -import org.opendaylight.mdsal.binding.dom.codec.impl.MissingSchemaException; -import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy; -import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext; import org.opendaylight.mdsal.binding.spec.naming.BindingMapping; import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier; @@ -63,16 +62,12 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; -import org.opendaylight.yangtools.yang.data.impl.schema.Builders; -import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; import org.opendaylight.yangtools.yang.model.api.ActionDefinition; -import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus; -import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; +import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextListener; import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -85,8 +80,8 @@ import org.slf4j.LoggerFactory; * NOTE: this class is non-final to allow controller adapter migration without duplicated code. */ @Singleton -public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, - BindingNormalizedNodeSerializer, SchemaContextListener, AutoCloseable { +public class BindingToNormalizedNodeCodec implements BindingNormalizedNodeSerializer, EffectiveModelContextListener, + AutoCloseable { private static final long WAIT_DURATION_SEC = 5; private static final Logger LOG = LoggerFactory.getLogger(BindingToNormalizedNodeCodec.class); @@ -100,27 +95,43 @@ public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, }); private final BindingNormalizedNodeCodecRegistry codecRegistry; private final ClassLoadingStrategy classLoadingStrategy; + private final BindingRuntimeGenerator generator; private final FutureSchema futureSchema; + private ListenerRegistration listenerRegistration; @Inject - public BindingToNormalizedNodeCodec(final ClassLoadingStrategy classLoadingStrategy, - final BindingNormalizedNodeCodecRegistry codecRegistry) { - this(classLoadingStrategy, codecRegistry, false); + public BindingToNormalizedNodeCodec(final BindingRuntimeGenerator generator, + final ClassLoadingStrategy classLoadingStrategy, final BindingNormalizedNodeCodecRegistry codecRegistry) { + this(generator, classLoadingStrategy, codecRegistry, false); + } + + @Beta + public BindingToNormalizedNodeCodec(final BindingRuntimeContext runtimeContext) { + generator = (final SchemaContext context) -> { + throw new UnsupportedOperationException("Static context assigned"); + }; + classLoadingStrategy = runtimeContext.getStrategy(); + codecRegistry = new BindingNormalizedNodeCodecRegistry(runtimeContext); + // TODO: this should have a specialized constructor or not be needed + futureSchema = FutureSchema.create(0, TimeUnit.SECONDS, false); + futureSchema.onRuntimeContextUpdated(runtimeContext); } - public BindingToNormalizedNodeCodec(final ClassLoadingStrategy classLoadingStrategy, - final BindingNormalizedNodeCodecRegistry codecRegistry, final boolean waitForSchema) { + public BindingToNormalizedNodeCodec(final BindingRuntimeGenerator generator, + final ClassLoadingStrategy classLoadingStrategy, final BindingNormalizedNodeCodecRegistry codecRegistry, + final boolean waitForSchema) { + this.generator = requireNonNull(generator, "generator"); this.classLoadingStrategy = requireNonNull(classLoadingStrategy, "classLoadingStrategy"); this.codecRegistry = requireNonNull(codecRegistry, "codecRegistry"); this.futureSchema = FutureSchema.create(WAIT_DURATION_SEC, TimeUnit.SECONDS, waitForSchema); } - public static BindingToNormalizedNodeCodec newInstance(final ClassLoadingStrategy classLoadingStrategy, - final DOMSchemaService schemaService) { + public static BindingToNormalizedNodeCodec newInstance(final BindingRuntimeGenerator generator, + final ClassLoadingStrategy classLoadingStrategy, final DOMSchemaService schemaService) { final BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(); - BindingToNormalizedNodeCodec instance = new BindingToNormalizedNodeCodec( - classLoadingStrategy, codecRegistry, true); + BindingToNormalizedNodeCodec instance = new BindingToNormalizedNodeCodec(generator, classLoadingStrategy, + codecRegistry, true); instance.listenerRegistration = schemaService.registerSchemaContextListener(instance); return instance; } @@ -135,20 +146,6 @@ public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, } } - /** - * Translates supplied Binding Instance Identifier into NormalizedNode - * instance identifier. - * - * @param binding - * Binding Instance Identifier - * @return DOM Instance Identifier - * @throws IllegalArgumentException - * If supplied Instance Identifier is not valid. - */ - public final YangInstanceIdentifier toNormalized(final InstanceIdentifier binding) { - return codecRegistry.toYangInstanceIdentifier(binding); - } - @Override public final YangInstanceIdentifier toYangInstanceIdentifier(final InstanceIdentifier binding) { return codecRegistry.toYangInstanceIdentifier(binding); @@ -169,22 +166,6 @@ public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, } } - /** - * Converts Binding Map.Entry to DOM Map.Entry. - * - *

- * Same as {@link #toNormalizedNode(InstanceIdentifier, DataObject)}. - * - * @param binding Map Entry with InstanceIdentifier as key and DataObject as value. - * @return DOM Map Entry with {@link YangInstanceIdentifier} as key and {@link NormalizedNode} - * as value. - */ - @SuppressWarnings({"unchecked", "rawtypes"}) - public final Entry> toNormalizedNode( - final Entry, DataObject> binding) { - return toNormalizedNode((InstanceIdentifier) binding.getKey(), binding.getValue()); - } - @Override public final Entry, DataObject> fromNormalizedNode(final YangInstanceIdentifier path, final NormalizedNode data) { @@ -220,7 +201,8 @@ public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, } @Override - public final InstanceIdentifier fromYangInstanceIdentifier(final YangInstanceIdentifier dom) { + public final InstanceIdentifier fromYangInstanceIdentifier( + final YangInstanceIdentifier dom) { return codecRegistry.fromYangInstanceIdentifier(dom); } @@ -275,51 +257,14 @@ public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, } } - public final Optional, DataObject>> toBinding( - final @NonNull Entry> normalized) - throws DeserializationException { - try { - /* - * This cast is required, due to generics behaviour in openjdk / oracle javac. - * - *

- * InstanceIdentifier has definition InstanceIdentifier, - * this means '?' is always  . Eclipse compiler - * is able to determine this relationship and treats - * Entry, DataObject> and Entry - * as assignable. However openjdk / oracle javac treats this two types - * as incompatible and issues a compile error. - * - *

- * It is safe to lose generic information and cast it to other generic signature. - */ - @SuppressWarnings("unchecked") - final Entry, DataObject> binding = Entry.class.cast( - codecRegistry.fromNormalizedNode(normalized.getKey(), normalized.getValue())); - return Optional.ofNullable(binding); - } catch (final IllegalArgumentException e) { - return Optional.empty(); - } - } - @Override - public void onGlobalContextUpdated(final SchemaContext context) { - final BindingRuntimeContext runtimeContext = BindingRuntimeContext.create(classLoadingStrategy, context); + public void onModelContextUpdated(final EffectiveModelContext newModelContext) { + final BindingRuntimeContext runtimeContext = DefaultBindingRuntimeContext.create( + generator.generateTypeMapping(newModelContext), classLoadingStrategy); codecRegistry.onBindingRuntimeContextUpdated(runtimeContext); futureSchema.onRuntimeContextUpdated(runtimeContext); } - /** - * Deprecated. - * - * @deprecated Use {@link BindingNormalizedNodeCodecRegistry#deserializeFunction} instead. - */ - @Deprecated - public final Function>, Optional> deserializeFunction( - final InstanceIdentifier path) { - return codecRegistry.deserializeFunction(path)::apply; - } - public final BindingNormalizedNodeCodecRegistry getCodecRegistry() { return codecRegistry; } @@ -332,10 +277,6 @@ public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, } } - public final BindingNormalizedNodeCodecRegistry getCodecFactory() { - return codecRegistry; - } - // FIXME: This should be probably part of Binding Runtime context public final ImmutableBiMap getRpcMethodToSchemaPath(final Class key) { final Module module = getModuleBlocking(key); @@ -400,16 +341,6 @@ public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, return key.getMethod(methodName, inputClz); } - @Override - public final BindingCodecTree create(final BindingRuntimeContext context) { - return codecRegistry.create(context); - } - - @Override - public final BindingCodecTree create(final SchemaContext context, final Class... bindingClasses) { - return codecRegistry.create(context, bindingClasses); - } - protected @NonNull Entry, BindingDataObjectCodecTreeNode> getSubtreeCodec( final YangInstanceIdentifier domIdentifier) { @@ -424,30 +355,13 @@ public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, return new SimpleEntry<>(bindingPath, codecContext); } - @SuppressWarnings("unchecked") - public final Set> getNotificationClasses(final Set interested) { - final Set> result = new HashSet<>(); - final BindingRuntimeContext runtimeContext = runtimeContext(); - for (final NotificationDefinition notification : runtimeContext.getSchemaContext().getNotifications()) { - if (interested.contains(notification.getPath())) { - try { - result.add((Class) runtimeContext.getClassForSchema(notification)); - } catch (final IllegalStateException e) { - // Ignore - LOG.warn("Class for {} is currently not known.", notification.getPath(), e); - } - } - } - return result; - } - - SchemaPath getActionPath(final Class> type) { + final SchemaPath getActionPath(final Class> type) { final ActionDefinition schema = runtimeContext().getActionDefinition(type); checkArgument(schema != null, "Failed to find schema for %s", type); return schema.getPath(); } - private BindingRuntimeContext runtimeContext() { + final BindingRuntimeContext runtimeContext() { return futureSchema.runtimeContext(); } @@ -455,31 +369,6 @@ public class BindingToNormalizedNodeCodec implements BindingCodecTreeFactory, return ImmutableSet.copyOf(Iterators.transform(path.getPathArguments().iterator(), PathArgument::getType)); } - protected NormalizedNode instanceIdentifierToNode(final YangInstanceIdentifier parentPath) { - return ImmutableNodes.fromInstanceId(runtimeContext().getSchemaContext(), parentPath); - } - - /** - * This method creates an empty list container of a particular type. - * - * @deprecated This method is not generally useful, as empty lists do not convey information in YANG (they are - * equivalent to non-present lists). It also leaks implementation details to a broader scope and should - * never have been public in the first place. - */ - @Deprecated - public NormalizedNode getDefaultNodeFor(final YangInstanceIdentifier parentMapPath) { - final BindingCodecTreeNode mapCodec = requireNonNull( - codecRegistry.getCodecContext().getSubtreeCodec(parentMapPath), - "Codec not found for yang instance identifier: " + parentMapPath); - final WithStatus schema = mapCodec.getSchema(); - if (schema instanceof ListSchemaNode) { - final ListSchemaNode castedSchema = (ListSchemaNode) schema; - return castedSchema.isUserOrdered() ? Builders.orderedMapBuilder(castedSchema).build() - : Builders.mapBuilder(castedSchema).build(); - } - throw new IllegalArgumentException("Path does not point to list schema node"); - } - protected Collection toDOMDataTreeIdentifiers( final Collection> subtrees) { return subtrees.stream().map(this::toDOMDataTreeIdentifier).collect(Collectors.toSet());