From 5cb9c642338720be6cff093125703a9fbebbf22a Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 3 May 2017 13:21:54 +0200 Subject: [PATCH] BUG-8360: add mdsal-binding-dom-codec-osgi This is an OSGi binding producing all context needed required to implement binding/dom/external serialization. It is similar to how the config-manager service operates, except associated services are explicitly covered instead of sneaking them through properties. Change-Id: I31f2bdb11153d6e514dacf2b070b073d768c1ff3 Signed-off-by: Robert Varga --- binding/mdsal-binding-dom-codec-osgi/pom.xml | 102 +++++++++++ .../osgi/BindingRuntimeContextListener.java | 17 ++ .../osgi/BindingRuntimeContextService.java | 31 ++++ .../dom/codec/osgi/impl/Activator.java | 52 ++++++ .../osgi/impl/ModuleInfoBundleTracker.java | 165 ++++++++++++++++++ .../osgi/impl/OsgiModuleInfoRegistry.java | 95 ++++++++++ .../SimpleBindingRuntimeContextService.java | 86 +++++++++ binding/pom.xml | 1 + common/artifacts/pom.xml | 5 + common/features/features-mdsal/pom.xml | 4 + .../src/main/features/features.xml | 1 + .../odl-mdsal-binding-runtime/pom.xml | 4 +- 12 files changed, 561 insertions(+), 2 deletions(-) create mode 100644 binding/mdsal-binding-dom-codec-osgi/pom.xml create mode 100644 binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/BindingRuntimeContextListener.java create mode 100644 binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/BindingRuntimeContextService.java create mode 100644 binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/Activator.java create mode 100644 binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/ModuleInfoBundleTracker.java create mode 100644 binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/OsgiModuleInfoRegistry.java create mode 100644 binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/SimpleBindingRuntimeContextService.java diff --git a/binding/mdsal-binding-dom-codec-osgi/pom.xml b/binding/mdsal-binding-dom-codec-osgi/pom.xml new file mode 100644 index 0000000000..1785cda135 --- /dev/null +++ b/binding/mdsal-binding-dom-codec-osgi/pom.xml @@ -0,0 +1,102 @@ + + + + + + + org.opendaylight.odlparent + bundle-parent + 1.9.0-SNAPSHOT + + + + 4.0.0 + org.opendaylight.mdsal + mdsal-binding-dom-codec-osgi + 0.11.0-SNAPSHOT + bundle + + + + + org.opendaylight.mdsal + mdsal-artifacts + 2.3.0-SNAPSHOT + pom + import + + + org.opendaylight.yangtools + yangtools-artifacts + 1.2.0-SNAPSHOT + pom + import + + + + + + + org.opendaylight.mdsal + mdsal-binding-dom-codec + + + org.osgi + org.osgi.core + + + + junit + junit + + + org.opendaylight.yangtools + mockito-configuration + test + + + org.opendaylight.yangtools + yang-test-util + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.groupId}.${project.artifactId} + org.opendaylight.mdsal.binding.dom.codec.osgi.impl.Activator + + + + + + + + + ${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/ + + + + opendaylight-site + ${nexus.site.url}/${project.artifactId}/ + + + + diff --git a/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/BindingRuntimeContextListener.java b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/BindingRuntimeContextListener.java new file mode 100644 index 0000000000..7537e25dd2 --- /dev/null +++ b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/BindingRuntimeContextListener.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2017 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.mdsal.binding.dom.codec.osgi; + +import java.util.EventListener; +import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext; + +@Deprecated +public interface BindingRuntimeContextListener extends EventListener { + + void onBindingRuntimeContextUpdated(BindingRuntimeContext context); +} diff --git a/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/BindingRuntimeContextService.java b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/BindingRuntimeContextService.java new file mode 100644 index 0000000000..86ba87be1c --- /dev/null +++ b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/BindingRuntimeContextService.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2017 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.mdsal.binding.dom.codec.osgi; + +import com.google.common.annotations.Beta; +import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider; + +/** + * A {@link BindingRuntimeContext} enriched with the ability to look up {@link YangTextSchemaSource}s. + * + * @author Robert Varga + * + * @deprecated This service is exposed for transition purposes only. + */ +@Deprecated +@Beta +public interface BindingRuntimeContextService extends SchemaSourceProvider { + /** + * Return the current {@link BindingRuntimeContext}. + * + * @return Current BindingRuntimeContext. + */ + BindingRuntimeContext getBindingRuntimeContext(); +} diff --git a/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/Activator.java b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/Activator.java new file mode 100644 index 0000000000..dd51b15919 --- /dev/null +++ b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/Activator.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017 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.mdsal.binding.dom.codec.osgi.impl; + +import java.util.Collection; +import org.opendaylight.mdsal.binding.dom.codec.osgi.BindingRuntimeContextService; +import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext; +import org.opendaylight.yangtools.concepts.ObjectRegistration; +import org.opendaylight.yangtools.yang.binding.YangModuleInfo; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.osgi.util.tracker.BundleTracker; + +public final class Activator implements BundleActivator { + private BundleTracker>> moduleInfoResolvedBundleTracker; + private SimpleBindingRuntimeContextService service; + private ServiceRegistration registration; + + @Override + public void start(final BundleContext context) { + // XXX: this will use thread-context class loader, which is probably appropriate + final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create(); + + service = new SimpleBindingRuntimeContextService(context, moduleInfoBackedContext, moduleInfoBackedContext); + + final OsgiModuleInfoRegistry registry = new OsgiModuleInfoRegistry(moduleInfoBackedContext, + moduleInfoBackedContext, service); + + final ModuleInfoBundleTracker moduleInfoTracker = new ModuleInfoBundleTracker(registry); + moduleInfoResolvedBundleTracker = new BundleTracker<>(context, Bundle.RESOLVED | Bundle.STARTING + | Bundle.STOPPING | Bundle.ACTIVE, moduleInfoTracker); + moduleInfoResolvedBundleTracker.open(); + moduleInfoTracker.finishStart(); + + service.open(); + registration = context.registerService(BindingRuntimeContextService.class, service, null); + } + + @Override + public void stop(final BundleContext context) { + moduleInfoResolvedBundleTracker.close(); + service.close(); + registration.unregister(); + } +} diff --git a/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/ModuleInfoBundleTracker.java b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/ModuleInfoBundleTracker.java new file mode 100644 index 0000000000..fd93e312d3 --- /dev/null +++ b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/ModuleInfoBundleTracker.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2017 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.mdsal.binding.dom.codec.osgi.impl; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.ImmutableList; +import com.google.common.io.Resources; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.regex.Pattern; +import org.opendaylight.yangtools.concepts.ObjectRegistration; +import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider; +import org.opendaylight.yangtools.yang.binding.YangModuleInfo; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleEvent; +import org.osgi.util.tracker.BundleTrackerCustomizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tracks bundles and attempts to retrieve YangModuleInfo, which is then fed into ModuleInfoRegistry + */ +final class ModuleInfoBundleTracker implements BundleTrackerCustomizer>> { + private static final Logger LOG = LoggerFactory.getLogger(ModuleInfoBundleTracker.class); + // FIXME: this should be in a place shared with maven-sal-api-gen-plugin + private static final String MODULE_INFO_PROVIDER_PATH_PREFIX = "META-INF/services/"; + + private static final String YANG_MODLE_BINDING_PROVIDER_SERVICE = MODULE_INFO_PROVIDER_PATH_PREFIX + + YangModelBindingProvider.class.getName(); + + private static final Pattern BRACE_PATTERN = Pattern.compile("{}", Pattern.LITERAL); + + private final OsgiModuleInfoRegistry moduleInfoRegistry; + + private volatile boolean starting = true; + + ModuleInfoBundleTracker(final OsgiModuleInfoRegistry moduleInfoRegistry) { + this.moduleInfoRegistry = checkNotNull(moduleInfoRegistry); + } + + void finishStart() { + starting = false; + moduleInfoRegistry.updateService(); + } + + @Override + public Collection> addingBundle(final Bundle bundle, final BundleEvent event) { + final URL resource = bundle.getEntry(YANG_MODLE_BINDING_PROVIDER_SERVICE); + if (resource == null) { + LOG.debug("Bundle {} does not have an entry for {}", bundle, YANG_MODLE_BINDING_PROVIDER_SERVICE); + return ImmutableList.of(); + } + + LOG.debug("Got addingBundle({}) with YangModelBindingProvider resource {}", bundle, resource); + final List lines; + try { + lines = Resources.readLines(resource, StandardCharsets.UTF_8); + } catch (IOException e) { + LOG.error("Error while reading {} from bundle {}", resource, bundle, e); + return ImmutableList.of(); + } + + if (lines.isEmpty()) { + LOG.debug("Bundle {} has empty services for {}", bundle, YANG_MODLE_BINDING_PROVIDER_SERVICE); + return ImmutableList.of(); + } + + final List> registrations = new ArrayList<>(lines.size()); + for (String moduleInfoName : lines) { + LOG.trace("Retrieve ModuleInfo({}, {})", moduleInfoName, bundle); + final YangModuleInfo moduleInfo; + try { + moduleInfo = retrieveModuleInfo(moduleInfoName, bundle); + } catch (RuntimeException e) { + LOG.warn("Failed to acquire {} from bundle {}, ignoring it", moduleInfoName, bundle, e); + continue; + } + + registrations.add(moduleInfoRegistry.registerModuleInfo(moduleInfo)); + } + + if (!starting) { + moduleInfoRegistry.updateService(); + } + + LOG.trace("Bundle {} resultend in registrations {}", registrations); + return registrations; + } + + @Override + public void modifiedBundle(final Bundle bundle, final BundleEvent event, + final Collection> object) { + // No-op + } + + @Override + public void removedBundle(final Bundle bundle, final BundleEvent event, + final Collection> regs) { + if (regs == null) { + return; + } + + for (ObjectRegistration reg : regs) { + try { + reg.close(); + } catch (Exception e) { + LOG.warn("Unable to unregister YangModuleInfo {}", reg.getInstance(), e); + } + } + } + + private static YangModuleInfo retrieveModuleInfo(final String moduleInfoClass, final Bundle bundle) { + final Class clazz = loadClass(moduleInfoClass, bundle); + if (!YangModelBindingProvider.class.isAssignableFrom(clazz)) { + String errorMessage = logMessage("Class {} does not implement {} in bundle {}", clazz, + YangModelBindingProvider.class, bundle); + throw new IllegalStateException(errorMessage); + } + + final YangModelBindingProvider instance; + try { + Object instanceObj = clazz.newInstance(); + instance = YangModelBindingProvider.class.cast(instanceObj); + } catch (InstantiationException e) { + String errorMessage = logMessage("Could not instantiate {} in bundle {}, reason {}", moduleInfoClass, + bundle, e); + throw new IllegalStateException(errorMessage, e); + } catch (IllegalAccessException e) { + String errorMessage = logMessage("Illegal access during instantiation of class {} in bundle {}, reason {}", + moduleInfoClass, bundle, e); + throw new IllegalStateException(errorMessage, e); + } + + try { + return instance.getModuleInfo(); + } catch (NoClassDefFoundError | ExceptionInInitializerError e) { + throw new IllegalStateException("Error while executing getModuleInfo on " + instance, e); + } + } + + private static Class loadClass(final String moduleInfoClass, final Bundle bundle) { + try { + return bundle.loadClass(moduleInfoClass); + } catch (ClassNotFoundException e) { + String errorMessage = logMessage("Could not find class {} in bundle {}, reason {}", moduleInfoClass, bundle, + e); + throw new IllegalStateException(errorMessage); + } + } + + private static String logMessage(final String slfMessage, final Object... params) { + LOG.info(slfMessage, params); + return String.format(BRACE_PATTERN.matcher(slfMessage).replaceAll("%s"), params); + } +} diff --git a/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/OsgiModuleInfoRegistry.java b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/OsgiModuleInfoRegistry.java new file mode 100644 index 0000000000..6b63cf8a7a --- /dev/null +++ b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/OsgiModuleInfoRegistry.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017 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.mdsal.binding.dom.codec.osgi.impl; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.annotation.concurrent.GuardedBy; +import org.opendaylight.mdsal.binding.generator.api.ModuleInfoRegistry; +import org.opendaylight.yangtools.concepts.ObjectRegistration; +import org.opendaylight.yangtools.yang.binding.YangModuleInfo; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider; +import org.osgi.framework.ServiceRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Update SchemaContext service in Service Registry each time new YangModuleInfo is added or removed. + */ +final class OsgiModuleInfoRegistry implements ModuleInfoRegistry { + private static final Logger LOG = LoggerFactory.getLogger(OsgiModuleInfoRegistry.class); + + private final SimpleBindingRuntimeContextService runtimeContext; + private final SchemaContextProvider schemaContextProvider; + private final ModuleInfoRegistry moduleInfoRegistry; + + @GuardedBy("this") + private ServiceRegistration registration; + @GuardedBy("this") + private long generation; + + OsgiModuleInfoRegistry(final ModuleInfoRegistry moduleInfoRegistry, + final SchemaContextProvider schemaContextProvider, final SimpleBindingRuntimeContextService runtimeContext) { + + this.moduleInfoRegistry = checkNotNull(moduleInfoRegistry); + this.schemaContextProvider = checkNotNull(schemaContextProvider); + this.runtimeContext = checkNotNull(runtimeContext); + } + + synchronized void updateService() { + final SchemaContext context; + try { + context = schemaContextProvider.getSchemaContext(); + } catch (final RuntimeException e) { + // The ModuleInfoBackedContext throws a RuntimeException if it can't create the schema context. + LOG.error("Error updating the schema context", e); + return; + } + + try { + runtimeContext.updateBindingRuntimeContext(context); + } catch (final RuntimeException e) { + LOG.error("Error updating binding runtime context", e); + return; + } + } + + @Override + public ObjectRegistration registerModuleInfo(final YangModuleInfo yangModuleInfo) { + return new ObjectRegistrationWrapper(moduleInfoRegistry.registerModuleInfo(yangModuleInfo)); + } + + private class ObjectRegistrationWrapper implements ObjectRegistration { + private final ObjectRegistration inner; + + ObjectRegistrationWrapper(final ObjectRegistration inner) { + this.inner = checkNotNull(inner); + } + + @Override + public YangModuleInfo getInstance() { + return inner.getInstance(); + } + + @Override + public void close() throws Exception { + try { + inner.close(); + } finally { + // send modify event when a bundle disappears + updateService(); + } + } + + @Override + public String toString() { + return inner.toString(); + } + } +} diff --git a/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/SimpleBindingRuntimeContextService.java b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/SimpleBindingRuntimeContextService.java new file mode 100644 index 0000000000..3ebdbcb06c --- /dev/null +++ b/binding/mdsal-binding-dom-codec-osgi/src/main/java/org/opendaylight/mdsal/binding/dom/codec/osgi/impl/SimpleBindingRuntimeContextService.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2017 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.mdsal.binding.dom.codec.osgi.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Verify.verifyNotNull; + +import com.google.common.util.concurrent.CheckedFuture; +import javax.annotation.concurrent.GuardedBy; +import org.opendaylight.mdsal.binding.dom.codec.osgi.BindingRuntimeContextListener; +import org.opendaylight.mdsal.binding.dom.codec.osgi.BindingRuntimeContextService; +import org.opendaylight.mdsal.binding.generator.api.ClassLoadingStrategy; +import org.opendaylight.mdsal.binding.generator.util.BindingRuntimeContext; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException; +import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.ServiceTracker; + +@Deprecated +final class SimpleBindingRuntimeContextService extends + ServiceTracker + implements BindingRuntimeContextService { + private final SchemaSourceProvider sourceProvider; + private final ClassLoadingStrategy strategy; + private final Object lock = new Object(); + + @GuardedBy("lock") + private BindingRuntimeContext current; + + SimpleBindingRuntimeContextService(final BundleContext context, final ClassLoadingStrategy strategy, + final SchemaSourceProvider sourceProvider) { + super(context, BindingRuntimeContextListener.class, null); + this.sourceProvider = checkNotNull(sourceProvider); + this.strategy = checkNotNull(strategy); + } + + @Override + public CheckedFuture getSource( + final SourceIdentifier sourceIdentifier) { + return sourceProvider.getSource(sourceIdentifier); + } + + @Override + public BindingRuntimeContext getBindingRuntimeContext() { + synchronized (lock) { + checkState(current != null, "Runtime context is not initialized yet"); + return current; + } + } + + void updateBindingRuntimeContext(final SchemaContext schemaContext) { + final BindingRuntimeContext next = verifyNotNull(BindingRuntimeContext.create(strategy, schemaContext)); + + final BindingRuntimeContextListener[] listeners; + synchronized (lock) { + current = next; + listeners = this.getServices(new BindingRuntimeContextListener[0]); + } + + for (BindingRuntimeContextListener l : listeners) { + l.onBindingRuntimeContextUpdated(next); + } + } + + @Override + public BindingRuntimeContextListener addingService( + final ServiceReference reference) { + final BindingRuntimeContextListener listener = super.addingService(reference); + + synchronized (lock) { + listener.onBindingRuntimeContextUpdated(current); + } + + return listener; + } +} diff --git a/binding/pom.xml b/binding/pom.xml index dfd516e481..4699bf3f49 100644 --- a/binding/pom.xml +++ b/binding/pom.xml @@ -35,6 +35,7 @@ mdsal-binding-test-model mdsal-binding-dom-codec + mdsal-binding-dom-codec-osgi mdsal-binding-api mdsal-binding-util diff --git a/common/artifacts/pom.xml b/common/artifacts/pom.xml index d8cb9acdb1..1844e878bd 100644 --- a/common/artifacts/pom.xml +++ b/common/artifacts/pom.xml @@ -98,6 +98,11 @@ mdsal-binding-dom-codec 0.11.0-SNAPSHOT + + org.opendaylight.mdsal + mdsal-binding-dom-codec-osgi + 0.11.0-SNAPSHOT + org.opendaylight.mdsal diff --git a/common/features/features-mdsal/pom.xml b/common/features/features-mdsal/pom.xml index 11dd745603..7428c275de 100644 --- a/common/features/features-mdsal/pom.xml +++ b/common/features/features-mdsal/pom.xml @@ -140,6 +140,10 @@ ${project.groupId} mdsal-binding-dom-codec + + ${project.groupId} + mdsal-binding-dom-codec-osgi + ${project.groupId} diff --git a/common/features/features-mdsal/src/main/features/features.xml b/common/features/features-mdsal/src/main/features/features.xml index 43311d6071..e4cc848bc8 100644 --- a/common/features/features-mdsal/src/main/features/features.xml +++ b/common/features/features-mdsal/src/main/features/features.xml @@ -58,6 +58,7 @@ mvn:org.opendaylight.mdsal/mdsal-binding-generator-impl/{{VERSION}} mvn:org.opendaylight.mdsal/mdsal-binding-generator-util/{{VERSION}} mvn:org.opendaylight.mdsal/mdsal-binding-dom-codec/{{VERSION}} + mvn:org.opendaylight.mdsal/mdsal-binding-dom-codec-osgi/{{VERSION}} diff --git a/common/features/odl-mdsal-binding-runtime/pom.xml b/common/features/odl-mdsal-binding-runtime/pom.xml index b171cd9532..4d2096f077 100644 --- a/common/features/odl-mdsal-binding-runtime/pom.xml +++ b/common/features/odl-mdsal-binding-runtime/pom.xml @@ -71,7 +71,7 @@ ${project.groupId} - mdsal-binding-dom-codec + mdsal-binding-dom-codec-osgi @@ -91,4 +91,4 @@ - \ No newline at end of file + -- 2.36.6