Depends on yangtools commit https://git.opendaylight.org/gerrit/#/c/5579/ .
Instead of having multiple bundle trackers for config and netconf, keep only
one. Each bundle containing yang files should use sal code generator, which
generates YangModuleInfo objects. Using this instead of speculatively having
to parse all current yang files for each adding bundle event allows not having
to deal with broken yang dependencies when bundle events come in wrong order.
Put SchemaContextProvider to OSGi SR in config-manager, so that any bundle
working with yang can use it. This replaces too specific YangStoreService which
was coupled with yang-jmx-generator. Users can listen for changes directly
on OSGi SR - they receive service changed event when yang module is added or
removed.
Change-Id: Iabcb35929a1eeef0df328f3f948d70e1bfcbba0d
Signed-off-by: Tomas Olvecky <tolvecky@cisco.com>
<artifactId>yang-jmx-generator</artifactId>
<version>${config.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-api</artifactId>
- <version>${config.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-impl</artifactId>
- <version>${config.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>logback-config</artifactId>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.manager.impl.osgi;
-
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class BindingIndependentMappingServiceTracker implements ServiceTrackerCustomizer<BindingIndependentMappingService, BindingIndependentMappingService> {
- private static final Logger logger = LoggerFactory.getLogger(BindingIndependentMappingServiceTracker.class);
-
- private final ConfigManagerActivator activator;
- private final BundleContext ctx;
- private BindingIndependentMappingService service;
-
- public BindingIndependentMappingServiceTracker(BundleContext context, ConfigManagerActivator activator) {
- this.ctx = context;
- this.activator = activator;
- }
-
- @Override
- public synchronized BindingIndependentMappingService addingService(
- ServiceReference<BindingIndependentMappingService> moduleFactoryServiceReference) {
-
- if (service != null) {
- // FIXME
- // Second registration appears from
- // org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModule
- logger.debug("BindingIndependentMappingService was already added as {}" + " now added as {}",
- service, ctx.getService(moduleFactoryServiceReference));
- return null;
- }
-
- BindingIndependentMappingService service = ctx.getService(moduleFactoryServiceReference);
- this.service = service;
- CodecRegistry codecRegistry = service.getCodecRegistry();
- logger.debug("Codec registry acquired {}", codecRegistry);
-// activator.initConfigManager(ctx, codecRegistry);
- return service;
- }
-
- @Override
- public void modifiedService(ServiceReference <BindingIndependentMappingService> moduleFactoryServiceReference, BindingIndependentMappingService o) {
- // TODO crash
- }
-
- @Override
- public void removedService(ServiceReference<BindingIndependentMappingService> moduleFactoryServiceReference, BindingIndependentMappingService o) {
- // TODO crash
- }
-}
*/
package org.opendaylight.controller.config.manager.impl.osgi;
-import java.lang.management.ManagementFactory;
-import java.util.Collection;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.MBeanServer;
-
import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
import org.opendaylight.controller.config.manager.impl.jmx.ConfigRegistryJMXRegistrator;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.CodecRegistryProvider;
import org.opendaylight.controller.config.manager.impl.osgi.mapping.ModuleInfoBundleTracker;
-import org.opendaylight.controller.config.manager.impl.osgi.mapping.RuntimeGeneratedMappingServiceActivator;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.RefreshingSCPModuleInfoRegistry;
+import org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-public class ConfigManagerActivator implements BundleActivator {
- private static final Logger logger = LoggerFactory.getLogger(ConfigManagerActivator.class);
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanServer;
+import java.lang.management.ManagementFactory;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import static org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil.registerService;
+import static org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil.wrap;
+
+public class ConfigManagerActivator implements BundleActivator {
private final MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer();
- private ExtensibleBundleTracker<Collection<ObjectRegistration<YangModuleInfo>>> bundleTracker;
- private ConfigRegistryImpl configRegistry;
- private ConfigRegistryJMXRegistrator configRegistryJMXRegistrator;
- private ServiceRegistration<?> configRegistryServiceRegistration;
- private RuntimeGeneratedMappingServiceActivator mappingServiceActivator;
+
+ private AutoCloseable autoCloseable;
@Override
public void start(BundleContext context) {
- // track bundles containing YangModuleInfo
- ModuleInfoBundleTracker moduleInfoBundleTracker = new ModuleInfoBundleTracker();
- mappingServiceActivator = new RuntimeGeneratedMappingServiceActivator(moduleInfoBundleTracker);
- CodecRegistry codecRegistry = mappingServiceActivator.startRuntimeMappingService(context).getCodecRegistry();
+ ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();// the inner strategy is backed by thread context cl?
+
+ RefreshingSCPModuleInfoRegistry moduleInfoRegistryWrapper = new RefreshingSCPModuleInfoRegistry(
+ moduleInfoBackedContext, moduleInfoBackedContext, context);
+
+ ModuleInfoBundleTracker moduleInfoBundleTracker = new ModuleInfoBundleTracker(moduleInfoRegistryWrapper);
+
+ CodecRegistryProvider codecRegistryProvider = new CodecRegistryProvider(moduleInfoBackedContext, context);
// start config registry
BundleContextBackedModuleFactoriesResolver bundleContextBackedModuleFactoriesResolver = new BundleContextBackedModuleFactoriesResolver(
context);
- configRegistry = new ConfigRegistryImpl(bundleContextBackedModuleFactoriesResolver, configMBeanServer,
- codecRegistry);
+ ConfigRegistryImpl configRegistry = new ConfigRegistryImpl(bundleContextBackedModuleFactoriesResolver, configMBeanServer,
+ codecRegistryProvider.getCodecRegistry());
// track bundles containing factories
BlankTransactionServiceTracker blankTransactionServiceTracker = new BlankTransactionServiceTracker(
blankTransactionServiceTracker);
// start extensible tracker
- bundleTracker = new ExtensibleBundleTracker<>(context, moduleInfoBundleTracker, moduleFactoryBundleTracker);
+ ExtensibleBundleTracker<Collection<ObjectRegistration<YangModuleInfo>>> bundleTracker = new ExtensibleBundleTracker<>(context, moduleInfoBundleTracker, moduleFactoryBundleTracker);
bundleTracker.open();
// register config registry to OSGi
- configRegistryServiceRegistration = context.registerService(ConfigRegistryImpl.class, configRegistry, null);
+ AutoCloseable configRegReg = registerService(context, configRegistry, ConfigRegistryImpl.class);
// register config registry to jmx
- configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(configMBeanServer);
+ ConfigRegistryJMXRegistrator configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(configMBeanServer);
try {
configRegistryJMXRegistrator.registerToJMX(configRegistry);
} catch (InstanceAlreadyExistsException e) {
throw new IllegalStateException("Config Registry was already registered to JMX", e);
}
+ // TODO wire directly via moduleInfoBundleTracker
ServiceTracker<ModuleFactory, Object> serviceTracker = new ServiceTracker<>(context, ModuleFactory.class,
blankTransactionServiceTracker);
serviceTracker.open();
+
+ List<AutoCloseable> list = Arrays.asList(
+ codecRegistryProvider, configRegistry, wrap(bundleTracker), configRegReg, configRegistryJMXRegistrator, wrap(serviceTracker));
+ autoCloseable = OsgiRegistrationUtil.aggregate(list);
}
@Override
- public void stop(BundleContext context) {
- try {
- configRegistry.close();
- } catch (Exception e) {
- logger.warn("Exception while closing config registry", e);
- }
- try {
- bundleTracker.close();
- } catch (Exception e) {
- logger.warn("Exception while closing extender", e);
- }
- try {
- configRegistryJMXRegistrator.close();
- } catch (Exception e) {
- logger.warn(
- "Exception while closing config registry jmx registrator",
- e);
- }
- try {
- configRegistryServiceRegistration.unregister();
- } catch (Exception e) {
- logger.warn("Exception while unregistering config registry", e);
- }
- try {
- mappingServiceActivator.close();
- } catch (Exception e) {
- logger.warn("Exception while closing mapping service", e);
- }
+ public void stop(BundleContext context) throws Exception {
+ autoCloseable.close();
}
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.manager.impl.osgi.mapping;
+
+import javassist.ClassPool;
+import org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
+import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Creates and initializes {@link RuntimeGeneratedMappingServiceImpl}, which is used to get {@link CodecRegistry}.
+ * Also maintains service registrations of {@link RuntimeGeneratedMappingServiceImpl}.
+ */
+// TODO move to yang runtime
+public class CodecRegistryProvider implements AutoCloseable {
+ private static final ClassPool CLASS_POOL = ClassPool.getDefault();
+
+ private final RuntimeGeneratedMappingServiceImpl service;
+ private final AutoCloseable registration;
+
+ public CodecRegistryProvider(ClassLoadingStrategy classLoadingStrategy, BundleContext context) {
+ service = new RuntimeGeneratedMappingServiceImpl(classLoadingStrategy);
+ service.setPool(CLASS_POOL);
+ service.init();
+ registration = OsgiRegistrationUtil.registerService(context, service,
+ SchemaServiceListener.class, BindingIndependentMappingService.class);
+ }
+
+ public CodecRegistry getCodecRegistry() {
+ return service.getCodecRegistry();
+ }
+
+ @Override
+ public void close() throws Exception {
+ registration.close();
+ }
+}
*/
package org.opendaylight.controller.config.manager.impl.osgi.mapping;
-import static java.lang.String.format;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-
import org.apache.commons.io.IOUtils;
import org.opendaylight.yangtools.concepts.ObjectRegistration;
-import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry;
import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import static java.lang.String.format;
+
/**
- * Tracks bundles and attempts to retrieve YangModuleInfo.
+ * Tracks bundles and attempts to retrieve YangModuleInfo, which is then fed into ModuleInfoRegistry
*/
public final class ModuleInfoBundleTracker implements BundleTrackerCustomizer<Collection<ObjectRegistration<YangModuleInfo>>> {
private static final Logger logger = LoggerFactory.getLogger(ModuleInfoBundleTracker.class);
- public static final String GET_MODULE_INFO_METHOD = "getModuleInfo";
public static final String MODULE_INFO_PROVIDER_PATH_PREFIX = "META-INF/services/";
- private final ModuleInfoBackedContext moduleInfoLoadingStrategy = ModuleInfoBackedContext.create();
- public GeneratedClassLoadingStrategy getModuleInfoLoadingStrategy() {
- return moduleInfoLoadingStrategy;
+ private final ModuleInfoRegistry moduleInfoRegistry;
+
+ public ModuleInfoBundleTracker(ModuleInfoRegistry moduleInfoRegistry) {
+ this.moduleInfoRegistry = moduleInfoRegistry;
}
@Override
public Collection<ObjectRegistration<YangModuleInfo>> addingBundle(Bundle bundle, BundleEvent event) {
URL resource = bundle.getEntry(MODULE_INFO_PROVIDER_PATH_PREFIX + YangModelBindingProvider.class.getName());
-
+ logger.debug("Got addingBundle({}) with YangModelBindingProvider resource {}", bundle, resource);
if(resource==null) {
return null;
}
-
List<ObjectRegistration<YangModuleInfo>> registrations = new LinkedList<>();
try (InputStream inputStream = resource.openStream()) {
List<String> lines = IOUtils.readLines(inputStream);
for (String moduleInfoName : lines) {
+ logger.trace("Retrieve ModuleInfo({}, {})", moduleInfoName, bundle);
YangModuleInfo moduleInfo = retrieveModuleInfo(moduleInfoName, bundle);
- registrations.add(moduleInfoLoadingStrategy.registerModuleInfo(moduleInfo));
+ registrations.add(moduleInfoRegistry.registerModuleInfo(moduleInfo));
}
-
} catch (Exception e) {
logger.error("Error while reading {}", resource, e);
throw new RuntimeException(e);
}
-
+ logger.trace("Got following registrations {}", registrations);
return registrations;
}
@Override
public void modifiedBundle(Bundle bundle, BundleEvent event, Collection<ObjectRegistration<YangModuleInfo>> object) {
- // NOOP
}
@Override
return;
}
- for (ObjectRegistration<YangModuleInfo> reg : regs) {
+ for (Registration<YangModuleInfo> reg : regs) {
try {
reg.close();
} catch (Exception e) {
errorMessage = logMessage("Could not instantiate {} in bundle {}, reason {}", moduleInfoClass, bundle, e);
throw new IllegalStateException(errorMessage, e);
} catch (IllegalAccessException e) {
- errorMessage = logMessage("Illegal access during instatiation of class {} in bundle {}, reason {}",
+ errorMessage = logMessage("Illegal access during instantiation of class {} in bundle {}, reason {}",
moduleInfoClass, bundle, e);
throw new IllegalStateException(errorMessage, e);
}
try {
return bundle.loadClass(moduleInfoClass);
} catch (ClassNotFoundException e) {
- String errorMessage = logMessage("Could not find class {} in bunde {}, reason {}", moduleInfoClass, bundle, e);
+ String errorMessage = logMessage("Could not find class {} in bundle {}, reason {}", moduleInfoClass, bundle, e);
throw new IllegalStateException(errorMessage);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.manager.impl.osgi.mapping;
+
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import java.util.Hashtable;
+
+/**
+ * Update SchemaContext service in Service Registry each time new YangModuleInfo is added or removed.
+ */
+public class RefreshingSCPModuleInfoRegistry implements ModuleInfoRegistry, AutoCloseable {
+
+ private final ModuleInfoRegistry moduleInfoRegistry;
+ private final ServiceRegistration<SchemaContextProvider> osgiReg;
+
+ public RefreshingSCPModuleInfoRegistry(ModuleInfoRegistry moduleInfoRegistry,
+ SchemaContextProvider schemaContextProvider, BundleContext bundleContext) {
+ this.moduleInfoRegistry = moduleInfoRegistry;
+ osgiReg = bundleContext.registerService(SchemaContextProvider.class, schemaContextProvider, new Hashtable<String, String>());
+ }
+
+ private void updateService() {
+ osgiReg.setProperties(null); // send modifiedService event
+ }
+
+ @Override
+ public ObjectRegistration<YangModuleInfo> registerModuleInfo(YangModuleInfo yangModuleInfo) {
+ ObjectRegistration<YangModuleInfo> yangModuleInfoObjectRegistration = moduleInfoRegistry.registerModuleInfo(yangModuleInfo);
+ ObjectRegistrationWrapper wrapper = new ObjectRegistrationWrapper(yangModuleInfoObjectRegistration);
+ updateService();
+ return wrapper;
+ }
+
+
+ @Override
+ public void close() {
+ osgiReg.unregister();
+ }
+
+ private class ObjectRegistrationWrapper implements ObjectRegistration<YangModuleInfo> {
+ private final ObjectRegistration<YangModuleInfo> inner;
+
+ private ObjectRegistrationWrapper(ObjectRegistration<YangModuleInfo> inner) {
+ this.inner = inner;
+ }
+
+ @Override
+ public YangModuleInfo getInstance() {
+ return inner.getInstance();
+ }
+
+ @Override
+ public void close() throws Exception {
+ inner.close();
+ updateService();// send modify event when a bundle disappears
+ }
+
+
+ @Override
+ public String toString() {
+ return inner.toString();
+ }
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.manager.impl.osgi.mapping;
-
-import javassist.ClassPool;
-import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-import java.util.Hashtable;
-
-public class RuntimeGeneratedMappingServiceActivator implements AutoCloseable {
-
- private static final ClassPool CLASS_POOL = ClassPool.getDefault();
-
- private ServiceRegistration<SchemaServiceListener> listenerReg;
- private ServiceRegistration<BindingIndependentMappingService> mappingReg;
- private ModuleInfoBundleTracker moduleInfoBundleTracker;
-
- public RuntimeGeneratedMappingServiceActivator(ModuleInfoBundleTracker moduleInfoBundleTracker) {
- this.moduleInfoBundleTracker = moduleInfoBundleTracker;
- }
-
- public RuntimeGeneratedMappingServiceImpl startRuntimeMappingService(BundleContext context) {
- RuntimeGeneratedMappingServiceImpl service = new RuntimeGeneratedMappingServiceImpl(moduleInfoBundleTracker.getModuleInfoLoadingStrategy());
- service.setPool(CLASS_POOL);
- service.init();
- startRuntimeMappingService(service, context);
- return service;
- }
-
- private void startRuntimeMappingService(RuntimeGeneratedMappingServiceImpl service, BundleContext context) {
- Hashtable<String, String> properties = new Hashtable<String, String>();
- listenerReg = context.registerService(SchemaServiceListener.class, service, properties);
- mappingReg = context.registerService(BindingIndependentMappingService.class, service, properties);
-
- }
-
- @Override
- public void close() throws Exception {
- mappingReg.unregister();
- listenerReg.unregister();
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.manager.impl.util;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.BundleTracker;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class OsgiRegistrationUtil {
+ private static final Logger logger = LoggerFactory.getLogger(OsgiRegistrationUtil.class);
+
+ @SafeVarargs
+ public static <T> AutoCloseable registerService(BundleContext bundleContext, T service, Class<? super T> ... interfaces) {
+ checkNotNull(service);
+ checkNotNull(interfaces);
+ List<AutoCloseable> autoCloseableList = new ArrayList<>();
+ for (Class<? super T> ifc : interfaces) {
+ ServiceRegistration<? super T> serviceRegistration = bundleContext.registerService(ifc, service, null);
+ autoCloseableList.add(wrap(serviceRegistration));
+ }
+ return aggregate(autoCloseableList);
+ }
+
+ public static AutoCloseable wrap(final ServiceRegistration<?> reg) {
+ checkNotNull(reg);
+ return new AutoCloseable() {
+ @Override
+ public void close() throws Exception {
+ reg.unregister();
+ }
+ };
+ }
+
+ public static AutoCloseable wrap(final BundleTracker bundleTracker) {
+ checkNotNull(bundleTracker);
+ return new AutoCloseable() {
+ @Override
+ public void close() throws Exception {
+ bundleTracker.close();
+ }
+ };
+ }
+
+ public static AutoCloseable wrap(final ServiceTracker<?, ?> serviceTracker) {
+ checkNotNull(serviceTracker);
+ return new AutoCloseable() {
+ @Override
+ public void close() throws Exception {
+ serviceTracker.close();
+ }
+ };
+ }
+
+ /**
+ * Close list of auto closeables in reverse order
+ */
+ public static AutoCloseable aggregate(final List<? extends AutoCloseable> list) {
+ checkNotNull(list);
+
+ return new AutoCloseable() {
+ @Override
+ public void close() throws Exception {
+ Exception firstException = null;
+ for (ListIterator<? extends AutoCloseable> it = list.listIterator(list.size()); it.hasPrevious();) {
+ AutoCloseable ac = it.previous();
+ try {
+ ac.close();
+ } catch (Exception e) {
+ logger.warn("Exception while closing {}", ac, e);
+ if (firstException == null) {
+ firstException = e;
+ } else {
+ firstException.addSuppressed(e);
+ }
+ }
+ }
+ if (firstException != null) {
+ throw firstException;
+ }
+ }
+ };
+ }
+}
<module>config-persister-file-xml-adapter</module>
<module>yang-jmx-generator</module>
<module>yang-jmx-generator-plugin</module>
- <module>yang-store-api</module>
- <module>yang-store-impl</module>
<module>yang-test</module>
<module>logback-config</module>
<module>threadpool-config-api</module>
<artifactId>yang-maven-plugin-spi</artifactId>
<version>${yangtools.version}</version>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-api</artifactId>
- <version>${config.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
+++ /dev/null
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>config-subsystem</artifactId>
- <groupId>org.opendaylight.controller</groupId>
- <version>0.2.5-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>yang-store-api</artifactId>
- <name>${project.artifactId}</name>
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-jmx-generator</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>
- org.opendaylight.controller.config.yang.store.api,
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-target
-.classpath
-.settings
+++ /dev/null
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>config-subsystem</artifactId>
- <groupId>org.opendaylight.controller</groupId>
- <version>0.2.5-SNAPSHOT</version>
- <relativePath>..</relativePath>
- </parent>
- <artifactId>yang-store-impl</artifactId>
- <name>${project.artifactId}</name>
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-jmx-generator</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>binding-type-provider</artifactId>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>mockito-configuration</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.code.findbugs</groupId>
- <artifactId>jsr305</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.config.yang.store.impl.YangStoreActivator</Bundle-Activator>
- <Export-Package>
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <!-- test jar -->
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.yang.store.impl;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.util.tracker.BundleTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.concurrent.GuardedBy;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Note on consistency:
- * When this bundle is activated after other bundles containing yang files, the resolving order
- * is not preserved. We thus maintain two maps, one containing consistent snapshot, other inconsistent. The
- * container should eventually send all events and thus making the inconsistent map redundant.
- */
-public class ExtenderYangTracker extends BundleTracker<Object> implements YangStoreService, AutoCloseable {
-
- private static final Logger logger = LoggerFactory.getLogger(ExtenderYangTracker.class);
-
- private final Multimap<Bundle, URL> consistentBundlesToYangURLs = HashMultimap.create();
-
- /*
- Map of currently problematic yang files that should get fixed eventually after all events are received.
- */
- private final Multimap<Bundle, URL> inconsistentBundlesToYangURLs = HashMultimap.create();
-
- private final YangStoreCache cache = new YangStoreCache();
- private final MbeParser mbeParser;
-
-
- public ExtenderYangTracker(Optional<Pattern> maybeBlacklist, BundleContext bundleContext) {
- this(new MbeParser(), maybeBlacklist, bundleContext);
- }
-
- @GuardedBy("this")
- private Optional<Pattern> maybeBlacklist;
-
- @VisibleForTesting
- ExtenderYangTracker(MbeParser mbeParser, Optional<Pattern> maybeBlacklist, BundleContext bundleContext) {
- super(bundleContext, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, null);
- this.mbeParser = mbeParser;
- this.maybeBlacklist = maybeBlacklist;
- open();
- }
-
- @Override
- public synchronized Object addingBundle(Bundle bundle, BundleEvent event) {
-
- // Ignore system bundle:
- // system bundle might have config-api on classpath &&
- // config-api contains yang files =>
- // system bundle might contain yang files from that bundle
- if (bundle.getBundleId() == 0)
- return bundle;
-
- if (maybeBlacklist.isPresent()) {
- Matcher m = maybeBlacklist.get().matcher(bundle.getSymbolicName());
- if (m.matches()) {
- logger.debug("Ignoring {} because it is in blacklist {}", bundle, maybeBlacklist);
- return bundle;
- }
- }
-
- Enumeration<URL> enumeration = bundle.findEntries("META-INF/yang", "*.yang", false);
- if (enumeration != null && enumeration.hasMoreElements()) {
- synchronized (this) {
- List<URL> addedURLs = new ArrayList<>();
- while (enumeration.hasMoreElements()) {
- URL url = enumeration.nextElement();
- addedURLs.add(url);
- }
- logger.trace("Bundle {} has event {}, bundle state {}, URLs {}", bundle, event, bundle.getState(), addedURLs);
- // test that yang store is consistent
- Multimap<Bundle, URL> proposedNewState = HashMultimap.create(consistentBundlesToYangURLs);
- proposedNewState.putAll(inconsistentBundlesToYangURLs);
- proposedNewState.putAll(bundle, addedURLs);
-
- Preconditions.checkArgument(addedURLs.size() > 0, "No change can occur when no URLs are changed");
-
- try(YangStoreSnapshotImpl snapshot = createSnapshot(mbeParser, proposedNewState)) {
- onSnapshotSuccess(proposedNewState, snapshot);
- } catch(YangStoreException e) {
- onSnapshotFailure(bundle, addedURLs, e);
- }
- }
- }
- return bundle;
- }
-
- private synchronized void onSnapshotFailure(Bundle bundle, List<URL> addedURLs, Exception failureReason) {
- // inconsistent state
- inconsistentBundlesToYangURLs.putAll(bundle, addedURLs);
-
- logger.debug("Yang store is falling back to last consistent state containing {}, inconsistent yang files {}",
- consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, failureReason);
- logger.info("Yang store is falling back to last consistent state containing {} files, keeping {} inconsistent yang files due to {}",
- consistentBundlesToYangURLs.size(), inconsistentBundlesToYangURLs.size(), failureReason.toString());
- cache.setInconsistentURLsForReporting(inconsistentBundlesToYangURLs.values());
- }
-
- private synchronized void onSnapshotSuccess(Multimap<Bundle, URL> proposedNewState, YangStoreSnapshotImpl snapshot) {
- // consistent state
- // merge into
- consistentBundlesToYangURLs.clear();
- consistentBundlesToYangURLs.putAll(proposedNewState);
-
- logger.debug("Yang store updated to new consistent state containing {}", consistentBundlesToYangURLs);
-
- // If we cleared up some inconsistent models, report that
- if (!inconsistentBundlesToYangURLs.isEmpty()) {
- inconsistentBundlesToYangURLs.clear();
- logger.info("Yang store updated to new consistent state containing {} yang files", consistentBundlesToYangURLs.size());
- }
-
- updateCache(snapshot);
- cache.setInconsistentURLsForReporting(Collections.<URL> emptySet());
- }
-
- private synchronized void updateCache(YangStoreSnapshotImpl snapshot) {
- cache.cacheYangStore(consistentBundlesToYangURLs, snapshot);
- }
-
- @Override
- public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
- logger.debug("Modified bundle {} {} {}", bundle, event, object);
- }
-
- /**
- * If removing YANG files makes yang store inconsistent, method {@link #getYangStoreSnapshot()}
- * will throw exception. There is no rollback.
- */
- @Override
- public synchronized void removedBundle(Bundle bundle, BundleEvent event, Object object) {
- logger.debug("Removed bundle {} {} {}", bundle, event, object);
- inconsistentBundlesToYangURLs.removeAll(bundle);
- consistentBundlesToYangURLs.removeAll(bundle);
- }
-
- @Override
- public synchronized YangStoreSnapshot getYangStoreSnapshot()
- throws YangStoreException {
- Optional<YangStoreSnapshot> yangStoreOpt = cache.getSnapshotIfPossible(consistentBundlesToYangURLs);
- if (yangStoreOpt.isPresent()) {
- logger.debug("Returning cached yang store {}", yangStoreOpt.get());
- return yangStoreOpt.get();
- }
-
- YangStoreSnapshotImpl snapshot = createSnapshot(mbeParser, consistentBundlesToYangURLs);
- updateCache(snapshot);
- return snapshot;
- }
-
- private static YangStoreSnapshotImpl createSnapshot(MbeParser mbeParser, Multimap<Bundle, URL> multimap) throws YangStoreException {
- try {
- YangStoreSnapshotImpl yangStoreSnapshot = mbeParser.parseYangFiles(fromUrlsToInputStreams(multimap));
- logger.trace("{} module entries parsed successfully from {} yang files",
- yangStoreSnapshot.countModuleMXBeanEntries(), multimap.values().size());
- return yangStoreSnapshot;
- } catch (RuntimeException e) {
- StringBuffer causeStr = new StringBuffer();
- Throwable cause = e;
- while (cause != null) {
- causeStr.append(e.getMessage());
- causeStr.append("\n");
- cause = e.getCause();
- }
- throw new YangStoreException("Unable to parse yang files. \n" + causeStr.toString() +
- "URLs: " + multimap, e);
- }
- }
-
- private static Collection<InputStream> fromUrlsToInputStreams(Multimap<Bundle, URL> multimap) {
- return Collections2.transform(multimap.values(),
- new Function<URL, InputStream>() {
-
- @Override
- public InputStream apply(URL url) {
- try {
- return url.openStream();
- } catch (IOException e) {
- logger.warn("Unable to open stream from {}", url);
- throw new IllegalStateException(
- "Unable to open stream from " + url, e);
- }
- }
- });
- }
-
- public synchronized void setMaybeBlacklist(Optional<Pattern> maybeBlacklistPattern) {
- maybeBlacklist = maybeBlacklistPattern;
- cache.invalidate();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.yang.store.impl;
-
-import com.google.common.collect.Sets;
-import org.apache.commons.io.IOUtils;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-public class YangParserWrapper {
-
- /**
- * throw IllegalStateException if it is unable to parse yang files
- */
- public static SchemaContext parseYangFiles(Collection<? extends InputStream> yangFilesAsInputStreams) {
- YangParserImpl parser = getYangParserInstance();
- Map<InputStream, Module> mappedYangModules = null;
- try {
- mappedYangModules = parseYangFiles(parser, yangFilesAsInputStreams);
- } catch (YangStoreException e) {
- throw new IllegalStateException("Unable to parse yang files", e);
- }
- return getSchemaContextFromModules(parser, mappedYangModules);
- }
-
- static YangParserImpl getYangParserInstance() {
- return new YangParserImpl();
- }
-
- static SchemaContext getSchemaContextFromModules(YangModelParser parser, Map<InputStream, Module> allYangModules) {
- return parser.resolveSchemaContext(Sets
- .newHashSet(allYangModules.values()));
- }
-
- static Map<InputStream, Module> parseYangFiles(YangModelParser parser, Collection<? extends InputStream> allInput) throws YangStoreException {
- List<InputStream> bufferedInputStreams = new ArrayList<>();
- for (InputStream is : allInput) {
- String content;
- try {
- content = IOUtils.toString(is);
- } catch (IOException e) {
- throw new YangStoreException("Can not get yang as String from "
- + is, e);
- }
- InputStream buf = new ByteArrayInputStream(content.getBytes());
- bufferedInputStreams.add(buf);
- }
-
- return parser
- .parseYangModelsFromStreamsMapped(bufferedInputStreams);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.yang.store.impl;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.regex.Pattern;
-
-public class YangStoreActivator implements BundleActivator {
- private static final Logger logger = LoggerFactory.getLogger(YangStoreActivator.class);
-
- @Override
- public void start(BundleContext context) throws Exception {
- // get blacklist
- Optional<Pattern> maybeBlacklistPattern = Optional.absent();
- String blacklist = context.getProperty("yangstore.blacklist");
- if (blacklist != null) {
- try {
- maybeBlacklistPattern = Optional.of(Pattern.compile(blacklist));
- } catch (RuntimeException e) {
- logger.error("Cannot parse blacklist regex " + blacklist, e);
- throw e;
- }
- }
- ExtenderYangTracker extenderYangTracker = new ExtenderYangTracker(maybeBlacklistPattern, context);
- Dictionary<String, ?> properties = new Hashtable<>();
- context.registerService(YangStoreService.class, extenderYangTracker, properties);
- }
-
- @Override
- public void stop(BundleContext context) throws Exception {
-
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. 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.controller.config.yang.store.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.osgi.framework.Bundle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.concurrent.GuardedBy;
-import java.net.URL;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-class YangStoreCache {
- private static final Logger logger = LoggerFactory.getLogger(YangStoreCache.class);
-
- @GuardedBy("this")
- private Set<URL> cachedUrls = null;
- @GuardedBy("this")
- private Optional<YangStoreSnapshot> cachedYangStoreSnapshot = getInitialSnapshot();
- @GuardedBy("this")
- private Collection<URL> inconsistentURLsForReporting = Collections.emptySet();
-
- synchronized Optional<YangStoreSnapshot> getSnapshotIfPossible(Multimap<Bundle, URL> bundlesToYangURLs) {
- Set<URL> urls = setFromMultimapValues(bundlesToYangURLs);
-
- if (cachedUrls==null || cachedUrls.equals(urls)) {
- Preconditions.checkState(cachedYangStoreSnapshot.isPresent());
- YangStoreSnapshot freshSnapshot = YangStoreSnapshotImpl.copy(cachedYangStoreSnapshot.get());
- if (inconsistentURLsForReporting.size() > 0){
- logger.warn("Some yang URLs are ignored: {}", inconsistentURLsForReporting);
- }
- return Optional.of(freshSnapshot);
- }
-
- return Optional.absent();
- }
-
- private static Set<URL> setFromMultimapValues(
- Multimap<Bundle, URL> bundlesToYangURLs) {
- Set<URL> urls = Sets.newHashSet(bundlesToYangURLs.values());
- Preconditions.checkState(bundlesToYangURLs.size() == urls.size());
- return urls;
- }
-
- synchronized void cacheYangStore(Multimap<Bundle, URL> urls,
- YangStoreSnapshot yangStoreSnapshot) {
- this.cachedUrls = setFromMultimapValues(urls);
- this.cachedYangStoreSnapshot = Optional.of(yangStoreSnapshot);
- }
-
- synchronized void invalidate() {
- cachedUrls.clear();
- if (cachedYangStoreSnapshot.isPresent()){
- cachedYangStoreSnapshot.get().close();
- cachedYangStoreSnapshot = Optional.absent();
- }
- }
-
- public synchronized void setInconsistentURLsForReporting(Collection<URL> urls){
- inconsistentURLsForReporting = urls;
- }
-
- private Optional<YangStoreSnapshot> getInitialSnapshot() {
- YangStoreSnapshot initialSnapshot = new YangStoreSnapshot() {
- @Override
- public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
- return Collections.emptyMap();
- }
-
- @Override
- public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
- return Collections.emptyMap();
- }
-
- @Override
- public Set<Module> getModules() {
- return Collections.emptySet();
- }
-
- @Override
- public Map<Module, String> getModulesToSources() {
- return Collections.emptyMap();
- }
-
- @Override
- public String getModuleSource(Module module) {
- throw new IllegalArgumentException("Cannot get sources in empty snapshot");
- }
-
- @Override
- public int countModuleMXBeanEntries() {
- return 0;
- }
-
- @Override
- public void close() {
- }
- };
- return Optional.of(initialSnapshot);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.yang.store.impl;
-
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-public class YangStoreSnapshotImpl implements YangStoreSnapshot {
- private static final Logger logger = LoggerFactory.getLogger(YangStoreSnapshotImpl.class);
-
- @Deprecated
- private final Map<String /* Namespace from yang file */,
- Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> moduleMXBeanEntryMap;
-
- private final Map<Module, String> modulesToSources;
- private final Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries;
-
- public YangStoreSnapshotImpl(Map<String, Map<String, ModuleMXBeanEntry>> moduleMXBeanEntryMap,
- Map<Module, String> modulesToSources,
- Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries) {
-
- this.moduleMXBeanEntryMap = Collections.unmodifiableMap(moduleMXBeanEntryMap);
- this.modulesToSources = Collections.unmodifiableMap(modulesToSources);
- this.qNamesToIdentitiesToModuleMXBeanEntries = Collections.unmodifiableMap(qNamesToIdentitiesToModuleMXBeanEntries);
- }
-
- public static YangStoreSnapshotImpl copy(YangStoreSnapshot yangStoreSnapshot) {
- return new YangStoreSnapshotImpl(
- yangStoreSnapshot.getModuleMXBeanEntryMap(),
- yangStoreSnapshot.getModulesToSources(),
- yangStoreSnapshot.getQNamesToIdentitiesToModuleMXBeanEntries());
- }
-
- /**
- * @return all loaded config modules. Key of outer map is namespace of yang file.
- * Key of inner map is name of module entry. Value is module entry.
- */
- @Override
- public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
- return moduleMXBeanEntryMap;
- }
-
- @Override
- public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
- return qNamesToIdentitiesToModuleMXBeanEntries;
- }
-
- @Override
- public Set<Module> getModules() {
- return modulesToSources.keySet();
- }
-
- @Override
- public String getModuleSource(Module module) {
- String result = modulesToSources.get(module);
- if (result == null) {
- logger.trace("Cannot find module {} in {}", module, modulesToSources);
- throw new IllegalArgumentException("Module not found in this snapshot:" + module);
- }
- return result;
- }
-
- @Override
- public Map<Module, String> getModulesToSources() {
- return modulesToSources;
- }
-
- @Override
- public int countModuleMXBeanEntries() {
- int i = 0;
- for (Map<String, ModuleMXBeanEntry> value : moduleMXBeanEntryMap
- .values()) {
- i += value.keySet().size();
- }
- return i;
- }
-
- @Override
- public void close() {
- // TODO: reference counting
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.config.yang.store.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleListener;
-
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyCollectionOf;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-public class ExtenderYangTrackerCustomizerTest {
-
-
- private ExtenderYangTracker tested;
- @Mock
- private MbeParser parser;
- @Mock
- private YangStoreSnapshotImpl yangStoreSnapshot;
- @Mock
- private BundleContext bundleContext;
-
- private Map<String, Map.Entry<Module, String>> moduleMap = Maps.newHashMap();
-
- @Before
- public void setUp() throws YangStoreException {
-
- moduleMap.put("1", new Map.Entry<Module, String>() {
- @Override
- public Module getKey() {
- return mock(Module.class);
- }
-
- @Override
- public String getValue() {
- return "v";
- }
-
- @Override
- public String setValue(String value) {
- return "v";
- }
- });
-
- MockitoAnnotations.initMocks(this);
- doNothing().when(bundleContext).addBundleListener(any(BundleListener.class));
- doReturn(new Bundle[0]).when(bundleContext).getBundles();
- tested = new ExtenderYangTracker(parser, Optional.<Pattern>absent(), bundleContext);
- doReturn(yangStoreSnapshot).when(parser).parseYangFiles(
- anyCollectionOf(InputStream.class));
- doReturn(22).when(yangStoreSnapshot).countModuleMXBeanEntries();
- doReturn("mock yang store").when(yangStoreSnapshot).toString();
- doNothing().when(yangStoreSnapshot).close();
- doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getModuleMXBeanEntryMap();
- doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getModulesToSources();
- doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getQNamesToIdentitiesToModuleMXBeanEntries();
- }
-
- @Test
- public void testCache() throws MalformedURLException, YangStoreException,
- InterruptedException {
- Bundle bundle = getMockedBundle(5, false);
- tested.addingBundle(bundle, null);
- bundle = getMockedBundle(2, false);
- tested.addingBundle(bundle, null);
- bundle = getMockedBundle(10, false);
- tested.addingBundle(bundle, null);
- YangStoreSnapshot returnedStore;
-
- returnedStore = tested.getYangStoreSnapshot();
-
-
- tested.removedBundle(bundle, null, null);
- tested.getYangStoreSnapshot();
-
- bundle = getMockedBundle(10, false);
- tested.addingBundle(bundle, null);
-
- for(int i = 0; i< 20; i++){
- tested.getYangStoreSnapshot();
- }
-
- verify(parser, times(5)).parseYangFiles(anyCollectionOf(InputStream.class));
-
- returnedStore = tested.getYangStoreSnapshot();
-
- verifyNoMoreInteractions(parser);
- }
-
- int bundleCounter = 1;
-
- private Bundle getMockedBundle(int sizeOfUrls, boolean system)
- throws MalformedURLException {
- Bundle mock = mock(Bundle.class);
- doReturn(32).when(mock).getState();//mock just for logging
-
- List<URL> urls = Lists.newArrayList();
- for (int i = 0; i < sizeOfUrls; i++) {
- urls.add(new URL("http://127.0." + bundleCounter++ + "." + i));
- }
- Enumeration<URL> abc = new TestEnumeration(urls);
-
- doReturn(abc).when(mock).findEntries("META-INF/yang", "*.yang", false);
- if (system)
- doReturn(0L).when(mock).getBundleId();
- else
- doReturn(1L).when(mock).getBundleId();
-
- doReturn("mockedBundle").when(mock).toString();
- doReturn("mockedBundle").when(mock).getSymbolicName();
-
- return mock;
- }
-
- private static final class TestEnumeration implements Enumeration<URL> {
-
- private final List<URL> urls;
- int currentPos = 0;
-
- public TestEnumeration(List<URL> urls) {
- this.urls = urls;
- }
-
- @Override
- public boolean hasMoreElements() {
- try {
- urls.get(currentPos);
- } catch (IndexOutOfBoundsException e) {
- return false;
- }
- return true;
- }
-
- @Override
- public URL nextElement() {
- URL url = urls.get(currentPos++);
- return url;
- }
-
- }
-}
<plugin>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>config</id>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <yangFilesRootDir>src/main/yang</yangFilesRootDir>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>
- org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
- </codeGeneratorClass>
- <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
- <additionalConfiguration>
- <namespaceToPackage1>
- urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
- </namespaceToPackage1>
- </additionalConfiguration>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
-
- <execution>
- <id>types</id>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <yangFilesRootDir>src/main/yang/types</yangFilesRootDir>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>
- org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
- </codeGeneratorClass>
- <outputBaseDir>
- ${project.build.directory}/generated-sources/sal
- </outputBaseDir>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
- </executions>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-jmx-generator-plugin</artifactId>
- <version>${config.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>maven-sal-api-gen-plugin</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
- </dependencies>
</plugin>
<plugin>
<groupId>org.opendaylight.controller</groupId>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-jmx-generator</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-impl</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>logback-config</artifactId>
netconf.config.persister.2.properties.fileStorage=configuration/current/controller.currentconfig.xml
netconf.config.persister.2.properties.numberOfBackups=1
-yangstore.blacklist=.*controller.model.*
-
# Set Default start level for framework
osgi.bundles.defaultStartLevel=4
# Extra packages to import from the boot class loader
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-impl</artifactId>
- <version>${config.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>logback-config</artifactId>
<version>${netconf.version}</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-impl</artifactId>
- <version>${config.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
</codeGeneratorClass>
<outputBaseDir>
- target/generated-sources/sal
+ ${salGeneratorPath}
</outputBaseDir>
</generator>
<generator>
<module>sal-binding-broker</module>
<module>sal-binding-util</module>
- <module>sal-binding-dom-it</module>
+
<!-- Samples -->
<module>samples</module>
</activation>
<modules>
<module>sal-binding-it</module>
+ <module>sal-binding-dom-it</module>
<!--module>clustered-data-store/integrationtest</module -->
<!--module>zeromq-routingtable/integrationtest</module -->
<!--module>sal-remoterpc-connector/integrationtest</module -->
</profiles>
<properties>
+ <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Plugin Versions -->
</namespaceToPackage1>
</additionalConfiguration>
</generator>
+
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ ${salGeneratorPath}
+ </outputBaseDir>
+ </generator>
+
+
<generator>
<codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
<outputBaseDir>target/site/models</outputBaseDir>
org.opendaylight.controller.sal.binding.codegen.*,
<!--org.opendaylight.controller.sal.binding.dom.*,-->
org.opendaylight.controller.sal.binding.osgi.*,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.binding.impl.rev131028
</Private-Package>
</instructions>
</configuration>
org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
</codeGeneratorClass>
<outputBaseDir>
- target/generated-sources/sal
+ ${salGeneratorPath}
</outputBaseDir>
</generator>
<generator>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-netconf-connector</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-impl</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>logback-config</artifactId>
*/
package org.opendaylight.controller.test.sal.binding.it;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.options.DefaultCompositeOption;
+import org.ops4j.pax.exam.util.PathUtils;
+
import static org.ops4j.pax.exam.CoreOptions.frameworkProperty;
import static org.ops4j.pax.exam.CoreOptions.junitBundles;
import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.options.DefaultCompositeOption;
-import org.ops4j.pax.exam.util.PathUtils;
-
public class TestHelper {
public static final String CONTROLLER = "org.opendaylight.controller";
mavenBundle("commons-io", "commons-io").versionAsInProject(), //
mavenBundle(CONTROLLER, "config-manager").versionAsInProject(), //
mavenBundle(CONTROLLER, "yang-jmx-generator").versionAsInProject(), //
- mavenBundle(CONTROLLER, "yang-store-api").versionAsInProject(), //
- mavenBundle(CONTROLLER, "yang-store-impl").versionAsInProject(), //
mavenBundle(CONTROLLER, "logback-config").versionAsInProject(), //
mavenBundle(CONTROLLER, "config-persister-api").versionAsInProject(), //
mavenBundle(CONTROLLER, "netconf-api").versionAsInProject(), //
systemProperty("netconf.config.persister.1.properties.fileStorage")
.value(PathUtils.getBaseDir() + "/src/test/resources/controller.xml"), //
systemProperty("netconf.config.persister.1.properties.numberOfBackups").value("1") //
- //systemProperty("yangstore.blacklist").value(".*controller.model.*") //
);
</namespaceToPackage1>
</additionalConfiguration>
</generator>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ ${salGeneratorPath}
+ </outputBaseDir>
+ </generator>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ ${salGeneratorPath}
+ </outputBaseDir>
+ </generator>
<generator>
<codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
<outputBaseDir>target/site/models</outputBaseDir>
</namespaceToPackage1>
</additionalConfiguration>
</generator>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ ${salGeneratorPath}
+ </outputBaseDir>
+ </generator>
<generator>
<codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
<outputBaseDir>target/site/models</outputBaseDir>
org.opendaylight.controller.sal.dom.broker.util,
org.opendaylight.controller.config.yang.md.sal.dom.impl,
org.opendaylight.controller.config.yang.md.sal.dom.statistics,
- org.opendaylight.yangtools.yang.util
+ org.opendaylight.yangtools.yang.util,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.dom.impl.rev131028.*
</Private-Package>
<Import-Package>
*
*/
package org.opendaylight.controller.sal.dom.broker.impl;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public interface SchemaContextProvider {
-
- SchemaContext getSchemaContext();
+/**
+ * @deprecated Use org.opendaylight.yangtools.yang.model.api.SchemaContextProvider instead
+ */
+@Deprecated
+public interface SchemaContextProvider extends org.opendaylight.yangtools.yang.model.api.SchemaContextProvider{
}
<version>${netconf.version}</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-api</artifactId>
- <version>${netconf.version}</version>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-client</artifactId>
<type>test-jar</type>
<version>${netconf.version}</version>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-impl</artifactId>
- <scope>test</scope>
- <version>${netconf.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-impl</artifactId>
- <scope>test</scope>
- <type>test-jar</type>
- <version>${netconf.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>logback-config</artifactId>
org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
</codeGeneratorClass>
<outputBaseDir>
- target/generated-sources/
+ ${salGeneratorPath}
</outputBaseDir>
</generator>
<generator>
</namespaceToPackage1>
</additionalConfiguration>
</generator>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ ${salGeneratorPath}
+ </outputBaseDir>
+ </generator>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>target/site/models</outputBaseDir>
+ </generator>
+
<generator>
<codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
<outputBaseDir>target/site/models</outputBaseDir>
<version>${netconf.version}</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-impl</artifactId>
- <version>${config.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>logback-config</artifactId>
</namespaceToPackage1>
</additionalConfiguration>
</generator>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ ${salGeneratorPath}
+ </outputBaseDir>
+ </generator>
</codeGenerators>
<inspectDependencies>true</inspectDependencies>
</configuration>
<artifactId>yang-jmx-generator-plugin</artifactId>
<version>${config.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${yangtools.version}</version>
+ </dependency>
</dependencies>
</plugin>
</namespaceToPackage1>
</additionalConfiguration>
</generator>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ ${salGeneratorPath}
+ </outputBaseDir>
+ </generator>
</codeGenerators>
<inspectDependencies>true</inspectDependencies>
</configuration>
<artifactId>yang-jmx-generator-plugin</artifactId>
<version>${config.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${yangtools.version}</version>
+ </dependency>
</dependencies>
</plugin>
<plugin>
org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
</codeGeneratorClass>
<outputBaseDir>
- target/generated-sources/sal
+ ${salGeneratorPath}
</outputBaseDir>
</generator>
</codeGenerators>
<artifactId>yang-jmx-generator</artifactId>
<version>${config.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-api</artifactId>
- <version>${config.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-impl</artifactId>
- <version>${config.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>logback-config</artifactId>
mavenBundle(ODL, "config-manager").versionAsInProject(),
mavenBundle(ODL, "config-util").versionAsInProject(),
mavenBundle(ODL, "yang-jmx-generator").versionAsInProject(),
- mavenBundle(ODL, "yang-store-api").versionAsInProject(),
- mavenBundle(ODL, "yang-store-impl").versionAsInProject(),
mavenBundle(ODL, "logback-config").versionAsInProject(),
mavenBundle(ODL, "config-persister-api").versionAsInProject(),
// mavenBundle(ODL,"config-persister-file-adapter").versionAsInProject(),
<groupId>${project.groupId}</groupId>
<artifactId>netconf-util</artifactId>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-api</artifactId>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-mapping-api</artifactId>
<artifactId>netconf-impl</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-impl</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>mockito-configuration</artifactId>
javax.management.openmbean,
org.opendaylight.controller.config.api,
org.opendaylight.controller.config.api.jmx,
- org.opendaylight.controller.config.yang.store.api,
org.opendaylight.controller.config.yangjmxgenerator,
org.opendaylight.controller.config.yangjmxgenerator.attribute,
org.opendaylight.controller.netconf.api,
org.slf4j,
org.w3c.dom,
com.google.common.io,
- org.opendaylight.yangtools.yang.model.api.type
+ org.opendaylight.yangtools.yang.model.api.type,
+ org.opendaylight.yangtools.sal.binding.generator.spi,
+ org.opendaylight.yangtools.sal.binding.yang.types
</Import-Package>
<Export-Package>
</Export-Package>
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
import javax.management.openmbean.OpenType;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Hashtable;
-
import static com.google.common.base.Preconditions.checkState;
-public class Activator implements BundleActivator, YangStoreServiceTracker.YangStoreTrackerListener {
+public class Activator implements BundleActivator {
private static final Logger logger = LoggerFactory.getLogger(Activator.class);
private ConfigRegistryLookupThread configRegistryLookup = null;
@Override
- public void start(BundleContext context) throws Exception {
+ public void start(final BundleContext context) throws Exception {
this.context = context;
- YangStoreServiceTracker tracker = new YangStoreServiceTracker(context, this);
- tracker.open();
+
+ ServiceTrackerCustomizer<SchemaContextProvider, ConfigRegistryLookupThread> customizer = new ServiceTrackerCustomizer<SchemaContextProvider, ConfigRegistryLookupThread>() {
+ @Override
+ public ConfigRegistryLookupThread addingService(ServiceReference<SchemaContextProvider> reference) {
+ logger.debug("Got addingService(SchemaContextProvider) event, starting ConfigRegistryLookupThread");
+ checkState(configRegistryLookup == null, "More than one onYangStoreAdded received");
+
+ SchemaContextProvider schemaContextProvider = reference.getBundle().getBundleContext().getService(reference);
+
+ YangStoreServiceImpl yangStoreService = new YangStoreServiceImpl(schemaContextProvider);
+ configRegistryLookup = new ConfigRegistryLookupThread(yangStoreService);
+ configRegistryLookup.start();
+ return configRegistryLookup;
+ }
+
+ @Override
+ public void modifiedService(ServiceReference<SchemaContextProvider> reference, ConfigRegistryLookupThread configRegistryLookup) {
+ logger.debug("Got modifiedService(SchemaContextProvider) event");
+ configRegistryLookup.yangStoreService.refresh();
+
+ }
+
+ @Override
+ public void removedService(ServiceReference<SchemaContextProvider> reference, ConfigRegistryLookupThread configRegistryLookup) {
+ configRegistryLookup.interrupt();
+ if (osgiRegistration != null) {
+ osgiRegistration.unregister();
+ }
+ osgiRegistration = null;
+ Activator.this.configRegistryLookup = null;
+ }
+ };
+
+ ServiceTracker<SchemaContextProvider, ConfigRegistryLookupThread> listenerTracker = new ServiceTracker<>(context, SchemaContextProvider.class, customizer);
+ listenerTracker.open();
}
@Override
}
}
- @Override
- public synchronized void onYangStoreAdded(YangStoreService yangStoreService) {
- checkState(configRegistryLookup == null, "More than one onYangStoreAdded received");
- configRegistryLookup = new ConfigRegistryLookupThread(yangStoreService);
- configRegistryLookup.start();
- }
-
- @Override
- public synchronized void onYangStoreRemoved() {
- configRegistryLookup.interrupt();
- if (osgiRegistration != null) {
- osgiRegistration.unregister();
- }
- osgiRegistration = null;
- configRegistryLookup = null;
- }
-
private class ConfigRegistryLookupThread extends Thread {
- private final YangStoreService yangStoreService;
+ private final YangStoreServiceImpl yangStoreService;
- private ConfigRegistryLookupThread(YangStoreService yangStoreService) {
+ private ConfigRegistryLookupThread(YangStoreServiceImpl yangStoreService) {
super("config-registry-lookup");
this.yangStoreService = yangStoreService;
}
public void run() {
NetconfOperationServiceFactoryImpl factory = new NetconfOperationServiceFactoryImpl(yangStoreService);
logger.debug("Registering into OSGi");
- osgiRegistration = context.registerService(new String[]{NetconfOperationServiceFactory.class.getName()}, factory,
- new Hashtable<String, Object>());
+ osgiRegistration = context.registerService(NetconfOperationServiceFactory.class, factory, null);
}
}
}
import com.google.common.base.Optional;
import com.google.common.collect.Sets;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.DiscardChanges;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Validate;
package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
import org.opendaylight.controller.config.api.LookupRegistry;
import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
import org.opendaylight.yangtools.yang.model.api.Module;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
* Manages life cycle of {@link YangStoreSnapshot}.
private final String moduleNamespace;
public YangStoreCapability(Module module, String moduleContent) {
- super(getAsString(module));
+ super(toCapabilityURI(module));
this.content = moduleContent;
this.moduleName = module.getName();
this.moduleNamespace = module.getNamespace().toString();
return Optional.of(content);
}
- private static String getAsString(Module module) {
- final StringBuffer capabilityContent = new StringBuffer();
- capabilityContent.append(module.getNamespace());
- capabilityContent.append("?module=");
- capabilityContent.append(module.getName());
- capabilityContent.append("&revision=");
- capabilityContent.append(Util.writeDate(module.getRevision()));
- return capabilityContent.toString();
+ private static String toCapabilityURI(Module module) {
+ return String.valueOf(module.getNamespace()) + "?module="
+ + module.getName() + "&revision=" + Util.writeDate(module.getRevision());
}
@Override
* 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.controller.config.yang.store.api;
+package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
public class YangStoreException extends Exception {
* 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.controller.config.yang.store.api;
+package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
/**
* Yang store OSGi service
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.netconf.confignetconfconnector.osgi;
+
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+
+import javax.annotation.concurrent.GuardedBy;
+
+public class YangStoreServiceImpl implements YangStoreService {
+ private final SchemaContextProvider service;
+ @GuardedBy("this")
+ private YangStoreSnapshotImpl cache = null;
+
+ public YangStoreServiceImpl(SchemaContextProvider service) {
+ this.service = service;
+ }
+
+ @Override
+ public synchronized YangStoreSnapshotImpl getYangStoreSnapshot() throws YangStoreException {
+ if (cache == null) {
+ cache = new YangStoreSnapshotImpl(service.getSchemaContext());
+ }
+ return cache;
+ }
+
+ /**
+ * Called when schema context changes, invalidates cache.
+ */
+ public synchronized void refresh() {
+ cache = null;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.netconf.confignetconfconnector.osgi;
-
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-class YangStoreServiceTracker extends ServiceTracker<YangStoreService, YangStoreService> {
- private final YangStoreTrackerListener listener;
-
- YangStoreServiceTracker(BundleContext context, final YangStoreTrackerListener listener) {
- super(context, YangStoreService.class, null);
- this.listener = listener;
- }
-
- @Override
- public synchronized YangStoreService addingService(final ServiceReference<YangStoreService> reference) {
- final YangStoreService yangStoreService = super.addingService(reference);
- listener.onYangStoreAdded(yangStoreService);
- return yangStoreService;
- }
-
- @Override
- public synchronized void removedService(final ServiceReference<YangStoreService> reference,
- final YangStoreService service) {
- listener.onYangStoreRemoved();
- }
-
- static interface YangStoreTrackerListener {
- void onYangStoreAdded(YangStoreService yangStoreService);
- void onYangStoreRemoved();
- }
-}
* 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.controller.config.yang.store.api;
+package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
import java.util.Map;
import java.util.Set;
Map<QName, Map<String /* identity local name */, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries();
- /**
- * Get number of parsed ModuleMXBeanEntry instances.
- */
- int countModuleMXBeanEntries();
-
/**
* Get all modules discovered when this snapshot was created.
* @return all modules discovered. If one module exists with two different revisions, return both.
*/
Set<Module> getModules();
- /**
- * Get all modules together with their yang sources.
- */
- Map<Module, String> getModulesToSources();
-
- /**
- * Retrieve source of module as it appeared during creation of this snapshot.
- * @param module
- * @return yang source of given module
- * @throws java.lang.IllegalArgumentException if module does not belong to this snapshot
- */
- String getModuleSource(Module module);
+ String getModuleSource(ModuleIdentifier moduleIdentifier);
@Override
void close();
* 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.controller.config.yang.store.impl;
-import com.google.common.collect.Lists;
+package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
+
import com.google.common.collect.Maps;
-import org.apache.commons.io.IOUtils;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.controller.config.yangjmxgenerator.PackageTranslator;
import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
+
+public class YangStoreSnapshotImpl implements YangStoreSnapshot {
+ private static final Logger logger = LoggerFactory.getLogger(YangStoreSnapshotImpl.class);
+
+
+ private final Map<String /* Namespace from yang file */,
+ Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> moduleMXBeanEntryMap;
+
-public class MbeParser {
- private static final Logger logger = LoggerFactory.getLogger(MbeParser.class);
+ private final Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries;
- public YangStoreSnapshotImpl parseYangFiles(Collection<? extends InputStream> allInput) throws YangStoreException {
- YangParserImpl parser = YangParserWrapper.getYangParserInstance();
+ private final SchemaContext schemaContext;
- Map<InputStream, Module> allYangModules = YangParserWrapper.parseYangFiles(parser, allInput);
- SchemaContext resolveSchemaContext = YangParserWrapper.getSchemaContextFromModules(parser, allYangModules);
+ public YangStoreSnapshotImpl(SchemaContext resolveSchemaContext) {
logger.trace("Resolved modules:{}", resolveSchemaContext.getModules());
+ this.schemaContext = resolveSchemaContext;
// JMX generator
Map<String, String> namespaceToPackageMapping = Maps.newHashMap();
- PackageTranslator packageTranslator = new PackageTranslator(
- namespaceToPackageMapping);
-
+ PackageTranslator packageTranslator = new PackageTranslator(namespaceToPackageMapping);
Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
-
Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
// create SIE structure qNamesToSIEs
for (Module module : resolveSchemaContext.getModules()) {
String packageName = packageTranslator.getPackageName(module);
Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
- .create(module, packageName,knownSEITracker);
-
- for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries
- .entrySet()) {
-
+ .create(module, packageName, knownSEITracker);
+ for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries.entrySet()) {
// merge value into qNamesToSIEs
if (qNamesToSIEs.containsKey(sieEntry.getKey()) == false) {
qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue());
} else {
- throw new IllegalStateException(
- "Cannot add two SIE with same qname "
+ throw new IllegalStateException("Cannot add two SIE with same qname "
+ sieEntry.getValue());
}
}
}
Map<String, Map<String, ModuleMXBeanEntry>> moduleMXBeanEntryMap = Maps.newHashMap();
- Map<Module, String> modulesToSources = new HashMap<>();
- Map<QName, Map<String /* identity local name */, ModuleMXBeanEntry>>
- qNamesToIdentitiesToModuleMXBeanEntries = new HashMap<>();
+
+ Map<QName, Map<String /* identity local name */, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries = new HashMap<>();
- for (Entry<InputStream, Module> moduleEntry : allYangModules.entrySet()) {
- Module module = moduleEntry.getValue();
+ for (Module module : schemaContext.getModules()) {
String packageName = packageTranslator.getPackageName(module);
TypeProviderWrapper typeProviderWrapper = new TypeProviderWrapper(
new TypeProviderImpl(resolveSchemaContext));
- String yangAsString = reReadInputStream(moduleEntry);
QName qName = new QName(module.getNamespace(), module.getRevision(), module.getName());
Collections.unmodifiableMap(ModuleMXBeanEntry.create(module, qNamesToSIEs, resolveSchemaContext,
typeProviderWrapper, packageName));
moduleMXBeanEntryMap.put(module.getNamespace().toString(), namesToMBEs);
- modulesToSources.put(module, yangAsString);
+
qNamesToIdentitiesToModuleMXBeanEntries.put(qName, namesToMBEs);
}
+ this.moduleMXBeanEntryMap = Collections.unmodifiableMap(moduleMXBeanEntryMap);
+ this.qNamesToIdentitiesToModuleMXBeanEntries = Collections.unmodifiableMap(qNamesToIdentitiesToModuleMXBeanEntries);
- return new YangStoreSnapshotImpl(moduleMXBeanEntryMap, modulesToSources, qNamesToIdentitiesToModuleMXBeanEntries);
}
- private String reReadInputStream(Entry<InputStream, Module> moduleEntry) {
- String yangAsString;
- try {
- moduleEntry.getKey().reset();
- yangAsString = IOUtils.toString(moduleEntry.getKey());
- } catch (IOException e) {
- throw new IllegalStateException("Cannot reread " + moduleEntry.getValue(), e);
- }
- return yangAsString;
+ @Override
+ public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
+ return moduleMXBeanEntryMap;
}
- @Deprecated
- public Map<Module, String> parseYangFilesToString(Collection<? extends InputStream> allYangs) {
-
- logger.error("Using deprecated method that will be removed soon", new UnsupportedOperationException("Deprecated"));
- YangParserImpl parser = YangParserWrapper.getYangParserInstance();
+ @Override
+ public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
+ return qNamesToIdentitiesToModuleMXBeanEntries;
+ }
- Map<InputStream, Module> allYangModules = parser
- .parseYangModelsFromStreamsMapped(Lists.newArrayList(allYangs));
- Map<Module, String> retVal = new HashMap<>();
+ @Override
+ public Set<Module> getModules() {
+ return schemaContext.getModules();
+ }
- for (Entry<InputStream, Module> entry : allYangModules.entrySet()) {
- try {
- retVal.put(entry.getValue(), IOUtils.toString(entry.getKey()));
- } catch (IOException e) {
- throw new IllegalStateException(
- "Can not create string from yang file.");
- }
- }
- return retVal;
+ @Override
+ public String getModuleSource(org.opendaylight.yangtools.yang.model.api.ModuleIdentifier moduleIdentifier) {
+ return schemaContext.getModuleSource(moduleIdentifier).get();
}
+ @Override
+ public void close() {
+
+ }
}
import com.google.common.base.Preconditions;
import java.text.ParseException;
-import java.text.SimpleDateFormat;
import java.util.Date;
-public final class Util {
+import static org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil.getRevisionFormat;
- /**
- * Used for date <-> xml serialization
- */
- private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+public final class Util {
public static String writeDate(final Date date) {
- return dateFormat.format(date);
+ return getRevisionFormat().format(date);
}
public static Date readDate(final String s) throws ParseException {
- return dateFormat.parse(s);
+ return getRevisionFormat().parse(s);
}
public static void checkType(final Object value, final Class<?> clazz) {
package org.opendaylight.controller.netconf.confignetconfconnector;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
-
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Ignore;
import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.config.yang.store.impl.MbeParser;
import org.opendaylight.controller.config.yang.test.impl.ComplexDtoBInner;
import org.opendaylight.controller.config.yang.test.impl.ComplexList;
import org.opendaylight.controller.config.yang.test.impl.Deep;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.get.Get;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc.RuntimeRpc;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreServiceImpl;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouterImpl;
import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
public class NetconfMappingTest extends AbstractConfigTest {
final List<InputStream> yangDependencies = getYangs();
final Map<String, Map<String, ModuleMXBeanEntry>> mBeanEntries = Maps.newHashMap();
- mBeanEntries.putAll(new MbeParser().parseYangFiles(yangDependencies).getModuleMXBeanEntryMap());
+
+ YangParserImpl yangParser = new YangParserImpl();
+ final SchemaContext schemaContext = yangParser.resolveSchemaContext(new HashSet<>(yangParser.parseYangModelsFromStreamsMapped(yangDependencies).values()));
+ YangStoreServiceImpl yangStoreService = new YangStoreServiceImpl(new SchemaContextProvider() {
+ @Override
+ public SchemaContext getSchemaContext() {
+ return schemaContext ;
+ }
+ });
+ mBeanEntries.putAll(yangStoreService.getYangStoreSnapshot().getModuleMXBeanEntryMap());
return mBeanEntries;
}
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
import org.junit.Test;
import org.junit.matchers.JUnitMatchers;
import org.opendaylight.controller.config.api.LookupRegistry;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
import org.opendaylight.yangtools.yang.common.QName;
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-api</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>xmlunit</groupId>
<artifactId>xmlunit</artifactId>
package org.opendaylight.controller.netconf.impl.mapping.operations;
-import java.util.HashMap;
-import java.util.Map;
-
+import com.google.common.base.Optional;
+import com.google.common.collect.Maps;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Optional;
-import com.google.common.collect.Maps;
+import java.util.HashMap;
+import java.util.Map;
public final class DefaultGetSchema extends AbstractLastNetconfOperation {
public static final String GET_SCHEMA = "get-schema";
package org.opendaylight.controller.netconf.impl;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import java.io.DataOutputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import javax.management.ObjectName;
-
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
import org.apache.commons.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
-import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.client.NetconfClient;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
+import java.io.DataOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.MockitoAnnotations.initMocks;
public class ConcurrentClientsTest {
private EventLoopGroup nettyGroup;
private NetconfClientDispatcher netconfClientDispatcher;
- @Mock
- private YangStoreService yangStoreService;
- @Mock
- private ConfigRegistryJMXClient jmxClient;
-
private final InetSocketAddress netconfAddress = new InetSocketAddress("127.0.0.1", 8303);
static final Logger logger = LoggerFactory.getLogger(ConcurrentClientsTest.class);
@Before
public void setUp() throws Exception {
- { // init mocks
- MockitoAnnotations.initMocks(this);
- final YangStoreSnapshot yStore = mock(YangStoreSnapshot.class);
- doReturn(yStore).when(this.yangStoreService).getYangStoreSnapshot();
- doReturn(Collections.emptyMap()).when(yStore).getModuleMXBeanEntryMap();
-
- final ConfigTransactionJMXClient mockedTCl = mock(ConfigTransactionJMXClient.class);
- doReturn(mockedTCl).when(this.jmxClient).getConfigTransactionClient(any(ObjectName.class));
-
- doReturn(Collections.emptySet()).when(jmxClient).lookupConfigBeans();
- }
-
+ initMocks(this);
nettyGroup = new NioEventLoopGroup();
NetconfHelloMessageAdditionalHeader additionalHeader = new NetconfHelloMessageAdditionalHeader("uname", "10.10.10.1", "830", "tcp", "client");
netconfClientDispatcher = new NetconfClientDispatcher( nettyGroup, nettyGroup, additionalHeader, 5000);
<artifactId>config-util</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-api</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-api</artifactId>
<version>${config.version}</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-impl</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-impl</artifactId>
- <scope>test</scope>
- <type>test-jar</type>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>logback-config</artifactId>
* 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.controller.config.yang.store.impl;
+package org.opendaylight.controller.netconf.it;
import org.apache.commons.io.IOUtils;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreService;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreServiceImpl;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
import static org.junit.Assert.assertNotNull;
public class HardcodedYangStoreService implements YangStoreService {
- private final Collection<ByteArrayInputStream> byteArrayInputStreams;
+ private final List<InputStream> byteArrayInputStreams;
public HardcodedYangStoreService(
Collection<? extends InputStream> inputStreams)
throw new RuntimeException(e);
}
}
- return new MbeParser().parseYangFiles(byteArrayInputStreams);
+
+ YangParserImpl yangParser = new YangParserImpl();
+ final SchemaContext schemaContext = yangParser.resolveSchemaContext(new HashSet<>(yangParser.parseYangModelsFromStreamsMapped(byteArrayInputStreams).values()));
+ YangStoreServiceImpl yangStoreService = new YangStoreServiceImpl(new SchemaContextProvider() {
+ @Override
+ public SchemaContext getSchemaContext() {
+ return schemaContext ;
+ }
+ });
+ return yangStoreService.getYangStoreSnapshot();
}
}
*/
package org.opendaylight.controller.netconf.it;
-import static junit.framework.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import io.netty.channel.ChannelFuture;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import javax.management.InstanceNotFoundException;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-
import org.apache.commons.lang3.StringUtils;
import org.junit.After;
import org.junit.Assert;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
import org.opendaylight.controller.config.persist.api.Persister;
import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Element;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
+import javax.management.InstanceNotFoundException;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import static junit.framework.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
import org.junit.Test;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
import org.opendaylight.controller.netconf.client.NetconfClient;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.spi.ModuleFactory;
import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
import org.mockito.Mock;
import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
import org.opendaylight.controller.netconf.client.NetconfClient;
*/
package org.opendaylight.controller.netconf.it.pax;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.baseModelBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.bindingAwareSalBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.configMinumumBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.flowCapableModelBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.junitAndMockitoBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.mdSalCoreBundles;
-import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-
-import javax.inject.Inject;
-import javax.xml.parsers.ParserConfigurationException;
-
import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
import io.netty.channel.nio.NioEventLoopGroup;
import org.junit.Assert;
import org.junit.Test;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
+import javax.inject.Inject;
+import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
+import static org.junit.Assert.fail;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.baseModelBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.bindingAwareSalBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.configMinumumBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.flowCapableModelBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.junitAndMockitoBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.mdSalCoreBundles;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+
@RunWith(PaxExam.class)
public class IdentityRefNetconfTest {
- public static final int CLIENT_CONNECTION_TIMEOUT_MILLIS = 5000;
+ public static final int CLIENT_CONNECTION_TIMEOUT_MILLIS = 15000;
// Wait for controller to start
@Inject
private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 18383);
+
@Test
public void testIdRef() throws Exception {
- Preconditions.checkNotNull(broker, "Controller not initialized");
-
- NioEventLoopGroup nettyThreadgroup = new NioEventLoopGroup();
- NetconfClientDispatcher clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup,
- CLIENT_CONNECTION_TIMEOUT_MILLIS);
-
- NetconfMessage edit = xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml");
- NetconfMessage commit = xmlFileToNetconfMessage("netconfMessages/commit.xml");
- NetconfMessage getConfig = xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
-
- try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, CLIENT_CONNECTION_TIMEOUT_MILLIS, clientDispatcher)) {
- sendMessage(edit, netconfClient);
- sendMessage(commit, netconfClient);
- sendMessage(getConfig, netconfClient, "id-test",
- "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</afi>",
- "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</afi>",
- "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</safi>",
- "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</safi>");
- }
+ try {
+ Preconditions.checkNotNull(broker, "Controller not initialized");
+
+ NioEventLoopGroup nettyThreadgroup = new NioEventLoopGroup();
+ NetconfClientDispatcher clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup,
+ CLIENT_CONNECTION_TIMEOUT_MILLIS);
+
+ NetconfMessage edit = xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml");
+ NetconfMessage commit = xmlFileToNetconfMessage("netconfMessages/commit.xml");
+ NetconfMessage getConfig = xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
+
+ try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, CLIENT_CONNECTION_TIMEOUT_MILLIS, clientDispatcher)) {
+ sendMessage(edit, netconfClient);
+ sendMessage(commit, netconfClient);
+ sendMessage(getConfig, netconfClient, "id-test",
+ "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</afi>",
+ "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</afi>",
+ "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</safi>",
+ "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</safi>");
+ }
- clientDispatcher.close();
+ clientDispatcher.close();
+ } catch (Exception e) {
+ fail(Throwables.getStackTraceAsString(e));
+ }
}
+
private void sendMessage(NetconfMessage edit, NetconfClient netconfClient, String... containingResponse)
throws ExecutionException, InterruptedException, TimeoutException {
NetconfMessage response = netconfClient.sendRequest(edit).get();
<artifactId>config-util</artifactId>
<version>${config.version}</version>
</dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-api</artifactId>
- <version>${config.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-impl</artifactId>
- <version>${config.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>yang-store-impl</artifactId>
- <version>${config.version}</version>
- <type>test-jar</type>
- </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>yang-test</artifactId>