From: Alessandro Boch Date: Wed, 19 Feb 2014 21:42:43 +0000 (+0000) Subject: Merge "ConfigurationService to create default config dir" X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~401 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=df2aabb0c61b9be04623c2a660c5a1592ff051f7;hp=0779bbaa14a81905ac2afbfa87d99e80de993f1a Merge "ConfigurationService to create default config dir" --- diff --git a/opendaylight/config/config-manager/pom.xml b/opendaylight/config/config-manager/pom.xml index 52377ae025..524cd1ff9e 100644 --- a/opendaylight/config/config-manager/pom.xml +++ b/opendaylight/config/config-manager/pom.xml @@ -46,6 +46,14 @@ org.opendaylight.yangtools mockito-configuration + + + + org.opendaylight.yangtools + binding-generator-impl + + + ${project.groupId} config-util diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BindingIndependentMappingServiceTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BindingIndependentMappingServiceTracker.java index 16a0605cd4..dbc862a53d 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BindingIndependentMappingServiceTracker.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BindingIndependentMappingServiceTracker.java @@ -44,7 +44,7 @@ public class BindingIndependentMappingServiceTracker implements ServiceTrackerCu this.service = service; CodecRegistry codecRegistry = service.getCodecRegistry(); logger.debug("Codec registry acquired {}", codecRegistry); - activator.initConfigManager(ctx, codecRegistry); +// activator.initConfigManager(ctx, codecRegistry); return service; } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java index e4e070885c..d464cb9006 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java @@ -8,14 +8,18 @@ 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.ModuleInfoBundleTracker; +import org.opendaylight.controller.config.manager.impl.osgi.mapping.RuntimeGeneratedMappingServiceActivator; import org.opendaylight.controller.config.spi.ModuleFactory; -import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; +import org.opendaylight.yangtools.concepts.Registration; +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; @@ -25,38 +29,40 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ConfigManagerActivator implements BundleActivator { - private static final Logger logger = LoggerFactory - .getLogger(ConfigManagerActivator.class); + private static final Logger logger = LoggerFactory.getLogger(ConfigManagerActivator.class); - private ExtenderBundleTracker extenderBundleTracker; + private ExtensibleBundleTracker>> bundleTracker; private ConfigRegistryImpl configRegistry; private ConfigRegistryJMXRegistrator configRegistryJMXRegistrator; private ServiceRegistration configRegistryServiceRegistration; - private ServiceTracker tracker; + private final MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer(); + + private RuntimeGeneratedMappingServiceActivator mappingServiceActivator; @Override public void start(BundleContext context) throws Exception { - BindingIndependentMappingServiceTracker mappingServiceTracker = new BindingIndependentMappingServiceTracker( - context, this); - tracker = new ServiceTracker( - context, BindingIndependentMappingService.class, mappingServiceTracker); - - logger.debug("Waiting for codec registry"); - - tracker.open(); - } - void initConfigManager(BundleContext context, CodecRegistry codecRegistry) { - BundleContextBackedModuleFactoriesResolver bundleContextBackedModuleFactoriesResolver = - new BundleContextBackedModuleFactoriesResolver(context); - MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer(); + // track bundles containing YangModuleInfo + ModuleInfoBundleTracker moduleInfoBundleTracker = new ModuleInfoBundleTracker(); + mappingServiceActivator = new RuntimeGeneratedMappingServiceActivator(moduleInfoBundleTracker); + CodecRegistry codecRegistry = mappingServiceActivator.startRuntimeMappingService(context).getCodecRegistry(); + // start config registry + BundleContextBackedModuleFactoriesResolver bundleContextBackedModuleFactoriesResolver = new BundleContextBackedModuleFactoriesResolver( + context); + configRegistry = new ConfigRegistryImpl(bundleContextBackedModuleFactoriesResolver, configMBeanServer, + codecRegistry); - // TODO push codecRegistry/IdentityCodec to dependencyResolver + // track bundles containing factories + BlankTransactionServiceTracker blankTransactionServiceTracker = new BlankTransactionServiceTracker( + configRegistry); + ModuleFactoryBundleTracker moduleFactoryBundleTracker = new ModuleFactoryBundleTracker( + blankTransactionServiceTracker); - configRegistry = new ConfigRegistryImpl( - bundleContextBackedModuleFactoriesResolver, configMBeanServer, codecRegistry); + // start extensible tracker + bundleTracker = new ExtensibleBundleTracker<>(context, moduleInfoBundleTracker, moduleFactoryBundleTracker); + bundleTracker.open(); // register config registry to OSGi configRegistryServiceRegistration = context.registerService(ConfigRegistryImpl.class, configRegistry, null); @@ -69,29 +75,20 @@ public class ConfigManagerActivator implements BundleActivator { throw new RuntimeException("Config Registry was already registered to JMX", e); } - // track bundles containing factories - BlankTransactionServiceTracker blankTransactionServiceTracker = new BlankTransactionServiceTracker(configRegistry); - extenderBundleTracker = new ExtenderBundleTracker(context, blankTransactionServiceTracker); - extenderBundleTracker.open(); - - ServiceTracker serviceTracker = new ServiceTracker(context, ModuleFactory.class, blankTransactionServiceTracker); + ServiceTracker serviceTracker = new ServiceTracker<>(context, ModuleFactory.class, + blankTransactionServiceTracker); serviceTracker.open(); } @Override public void stop(BundleContext context) throws Exception { - try { - tracker.close(); - } catch (Exception e) { - logger.warn("Exception while closing tracker", e); - } try { configRegistry.close(); } catch (Exception e) { logger.warn("Exception while closing config registry", e); } try { - extenderBundleTracker.close(); + bundleTracker.close(); } catch (Exception e) { logger.warn("Exception while closing extender", e); } @@ -107,5 +104,10 @@ public class ConfigManagerActivator implements BundleActivator { } 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); + } } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTracker.java new file mode 100644 index 0000000000..c1ebba7881 --- /dev/null +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTracker.java @@ -0,0 +1,95 @@ +/* + * 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.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; +import org.osgi.util.tracker.BundleTracker; +import org.osgi.util.tracker.BundleTrackerCustomizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * Extensible bundle tracker. Takes several BundleTrackerCustomizers and propagates bundle events to all of them. + * Primary customizer + * + * @param + */ +public final class ExtensibleBundleTracker extends BundleTracker { + + private final BundleTrackerCustomizer primaryTracker; + private final BundleTrackerCustomizer[] additionalTrackers; + + private static final Logger logger = LoggerFactory.getLogger(ExtensibleBundleTracker.class); + + public ExtensibleBundleTracker(BundleContext context, BundleTrackerCustomizer primaryBundleTrackerCustomizer, + BundleTrackerCustomizer... additionalBundleTrackerCustomizers) { + this(context, Bundle.ACTIVE, primaryBundleTrackerCustomizer, additionalBundleTrackerCustomizers); + } + + public ExtensibleBundleTracker(BundleContext context, int bundleState, + BundleTrackerCustomizer primaryBundleTrackerCustomizer, + BundleTrackerCustomizer... additionalBundleTrackerCustomizers) { + super(context, bundleState, null); + this.primaryTracker = primaryBundleTrackerCustomizer; + this.additionalTrackers = additionalBundleTrackerCustomizers; + logger.trace("Registered as extender with context {} and bundle state {}", context, bundleState); + } + + @Override + public T addingBundle(final Bundle bundle, final BundleEvent event) { + T primaryTrackerRetVal = primaryTracker.addingBundle(bundle, event); + + forEachAdditionalBundle(new BundleStrategy() { + @Override + public void execute(BundleTrackerCustomizer tracker) { + tracker.addingBundle(bundle, event); + } + }); + + return primaryTrackerRetVal; + } + + @Override + public void modifiedBundle(final Bundle bundle, final BundleEvent event, final T object) { + primaryTracker.modifiedBundle(bundle, event, object); + + forEachAdditionalBundle(new BundleStrategy() { + @Override + public void execute(BundleTrackerCustomizer tracker) { + tracker.modifiedBundle(bundle, event, null); + } + }); + + } + + @Override + public void removedBundle(final Bundle bundle, final BundleEvent event, final T object) { + primaryTracker.removedBundle(bundle, event, object); + + forEachAdditionalBundle(new BundleStrategy() { + @Override + public void execute(BundleTrackerCustomizer tracker) { + tracker.removedBundle(bundle, event, null); + } + }); + } + + private void forEachAdditionalBundle(BundleStrategy lambda) { + for (BundleTrackerCustomizer trac : additionalTrackers) { + lambda.execute(trac); + } + } + + private static interface BundleStrategy { + void execute(BundleTrackerCustomizer tracker); + } + +} diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtenderBundleTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java similarity index 90% rename from opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtenderBundleTracker.java rename to opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java index b55f3135d2..05ca43c3e2 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ExtenderBundleTracker.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java @@ -16,10 +16,9 @@ import java.util.List; import org.apache.commons.io.IOUtils; import org.opendaylight.controller.config.spi.ModuleFactory; import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; import org.osgi.framework.ServiceRegistration; -import org.osgi.util.tracker.BundleTracker; +import org.osgi.util.tracker.BundleTrackerCustomizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,14 +32,12 @@ import org.slf4j.LoggerFactory; * the services are unregistered automatically. * Code based on http://www.toedter.com/blog/?p=236 */ -public class ExtenderBundleTracker extends BundleTracker { +public class ModuleFactoryBundleTracker implements BundleTrackerCustomizer { private final BlankTransactionServiceTracker blankTransactionServiceTracker; - private static final Logger logger = LoggerFactory.getLogger(ExtenderBundleTracker.class); + private static final Logger logger = LoggerFactory.getLogger(ModuleFactoryBundleTracker.class); - public ExtenderBundleTracker(BundleContext context, BlankTransactionServiceTracker blankTransactionServiceTracker) { - super(context, Bundle.ACTIVE, null); + public ModuleFactoryBundleTracker(BlankTransactionServiceTracker blankTransactionServiceTracker) { this.blankTransactionServiceTracker = blankTransactionServiceTracker; - logger.trace("Registered as extender with context {}", context); } @Override @@ -62,9 +59,13 @@ public class ExtenderBundleTracker extends BundleTracker { return bundle; } + @Override + public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) { + // NOOP + } + @Override public void removedBundle(Bundle bundle, BundleEvent event, Object object) { - super.removedBundle(bundle,event,object); // workaround for service tracker not getting removed service event blankTransactionServiceTracker.blankTransaction(); } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/ModuleInfoBundleTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/ModuleInfoBundleTracker.java new file mode 100644 index 0000000000..8ba290f306 --- /dev/null +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/ModuleInfoBundleTracker.java @@ -0,0 +1,142 @@ +/* + * 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.apache.commons.io.IOUtils; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy; +import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext; +import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider; +import org.opendaylight.yangtools.yang.binding.YangModuleInfo; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleEvent; +import org.osgi.util.tracker.BundleTrackerCustomizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +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. + */ +public final class ModuleInfoBundleTracker implements BundleTrackerCustomizer>> { + + 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 ModuleInfoBackedContext moduleInfoLoadingStrategy = ModuleInfoBackedContext.create(); + + public GeneratedClassLoadingStrategy getModuleInfoLoadingStrategy() { + return moduleInfoLoadingStrategy; + } + + @Override + public Collection> addingBundle(Bundle bundle, BundleEvent event) { + URL resource = bundle.getEntry(MODULE_INFO_PROVIDER_PATH_PREFIX + YangModelBindingProvider.class.getName()); + + if(resource==null) { + return null; + } + + List> registrations = new LinkedList<>(); + + try (InputStream inputStream = resource.openStream()) { + List lines = IOUtils.readLines(inputStream); + for (String moduleInfoName : lines) { + YangModuleInfo moduleInfo = retrieveModuleInfo(moduleInfoName, bundle); + registrations.add(moduleInfoLoadingStrategy.registerModuleInfo(moduleInfo)); + } + + + } catch (Exception e) { + logger.error("Error while reading {}", resource, e); + throw new RuntimeException(e); + } + + return registrations; + } + + @Override + public void modifiedBundle(Bundle bundle, BundleEvent event, Collection> object) { + // NOOP + } + + @Override + public void removedBundle(Bundle bundle, BundleEvent event, Collection> regs) { + if(regs == null) { + return; + } + + for (Registration reg : regs) { + try { + reg.close(); + } catch (Exception e) { + throw new RuntimeException("Unable to unregister YangModuleInfo " + reg.getInstance(), e); + } + } + } + + private static YangModuleInfo retrieveModuleInfo(String moduleInfoClass, Bundle bundle) { + String errorMessage; + Class clazz = loadClass(moduleInfoClass, bundle); + + if (YangModelBindingProvider.class.isAssignableFrom(clazz) == false) { + errorMessage = logMessage("Class {} does not implement {} in bundle {}", clazz, YangModelBindingProvider.class, bundle); + throw new IllegalStateException(errorMessage); + } + + try { + Object instance = clazz.newInstance(); + Object result = clazz.getMethod(GET_MODULE_INFO_METHOD).invoke(instance); + + if (YangModuleInfo.class.isAssignableFrom(result.getClass()) == false) { + errorMessage = logMessage("Error invoking method not found {} in bundle {}, reason {}", + GET_MODULE_INFO_METHOD, bundle, "Not assignable from " + YangModuleInfo.class); + } else { + return (YangModuleInfo) result; + } + + } catch (InstantiationException e) { + errorMessage = logMessage("Could not instantiate {} in bundle {}, reason {}", moduleInfoClass, bundle, e); + } catch (IllegalAccessException e) { + errorMessage = logMessage("Illegal access during instatiation of class {} in bundle {}, reason {}", + moduleInfoClass, bundle, e); + } catch (NoSuchMethodException e) { + errorMessage = logMessage("Method not found {} in bundle {}, reason {}", GET_MODULE_INFO_METHOD, bundle, e); + } catch (InvocationTargetException e) { + errorMessage = logMessage("Error invoking method {} in bundle {}, reason {}", GET_MODULE_INFO_METHOD, + bundle, e); + } + + throw new IllegalStateException(errorMessage); + } + + private static Class loadClass(String moduleInfoClass, Bundle bundle) { + try { + return bundle.loadClass(moduleInfoClass); + } catch (ClassNotFoundException e) { + String errorMessage = logMessage("Could not find class {} in bunde {}, reason {}", moduleInfoClass, bundle, e); + throw new IllegalStateException(errorMessage); + } + } + + public static String logMessage(String slfMessage, Object... params) { + logger.info(slfMessage, params); + String formatMessage = slfMessage.replaceAll("\\{\\}", "%s"); + return format(formatMessage, params); + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/osgi/Activator.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RuntimeGeneratedMappingServiceActivator.java similarity index 56% rename from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/osgi/Activator.java rename to opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RuntimeGeneratedMappingServiceActivator.java index 84c98d7abf..a267a6b622 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/osgi/Activator.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RuntimeGeneratedMappingServiceActivator.java @@ -1,50 +1,51 @@ /* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * 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.sal.binding.osgi; +package org.opendaylight.controller.config.manager.impl.osgi.mapping; -import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; +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.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import java.util.Hashtable; -public class Activator implements BundleActivator { +public class RuntimeGeneratedMappingServiceActivator implements AutoCloseable { + + private static final ClassPool CLASS_POOL = ClassPool.getDefault(); - private ServiceRegistration reg; private ServiceRegistration listenerReg; private ServiceRegistration mappingReg; + private ModuleInfoBundleTracker moduleInfoBundleTracker; - @Override - public void start(BundleContext context) throws Exception { - RuntimeGeneratedMappingServiceImpl service = new RuntimeGeneratedMappingServiceImpl(); - service.setPool(SingletonHolder.CLASS_POOL); + 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 properties = new Hashtable(); listenerReg = context.registerService(SchemaServiceListener.class, service, properties); mappingReg = context.registerService(BindingIndependentMappingService.class, service, properties); - + } @Override - public void stop(BundleContext context) throws Exception { - if(listenerReg != null) { - listenerReg.unregister(); - } - if(mappingReg != null) { - mappingReg.unregister(); - } + public void close() throws Exception { + mappingReg.unregister(); + listenerReg.unregister(); } } diff --git a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java index 3c52d8c17a..2c4c211784 100644 --- a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java +++ b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java @@ -17,19 +17,14 @@ */ package org.opendaylight.controller.config.yang.netty.eventexecutor; -import io.netty.util.concurrent.AbstractEventExecutor; +import com.google.common.reflect.AbstractInvocationHandler; +import com.google.common.reflect.Reflection; import io.netty.util.concurrent.EventExecutor; -import io.netty.util.concurrent.EventExecutorGroup; -import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GlobalEventExecutor; -import io.netty.util.concurrent.ScheduledFuture; -import java.util.concurrent.Callable; +import java.lang.reflect.Method; import java.util.concurrent.TimeUnit; -/** -* -*/ public final class GlobalEventExecutorModule extends org.opendaylight.controller.config.yang.netty.eventexecutor.AbstractGlobalEventExecutorModule { @@ -51,91 +46,35 @@ public final class GlobalEventExecutorModule extends @Override public java.lang.AutoCloseable createInstance() { - return new GlobalEventExecutorCloseable(GlobalEventExecutor.INSTANCE); + final CloseableGlobalEventExecutorMixin closeableGlobalEventExecutorMixin = + new CloseableGlobalEventExecutorMixin(GlobalEventExecutor.INSTANCE); + return Reflection.newProxy(AutoCloseableEventExecutor.class, new AbstractInvocationHandler() { + @Override + protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getName().equals("close")) { + closeableGlobalEventExecutorMixin.close(); + return null; + } else { + return method.invoke(GlobalEventExecutor.INSTANCE, args); + } + } + }); } - static final private class GlobalEventExecutorCloseable extends AbstractEventExecutor implements AutoCloseable { - - private EventExecutor executor; - - public GlobalEventExecutorCloseable(EventExecutor executor) { - this.executor = executor; - } - - @Override - public EventExecutorGroup parent() { - return this.executor.parent(); - } - - @Override - public boolean inEventLoop(Thread thread) { - return this.executor.inEventLoop(thread); - } - - @Override - public boolean isShuttingDown() { - return this.executor.isShuttingDown(); - } - - @Override - public Future shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit) { - return this.executor.shutdownGracefully(quietPeriod, timeout, unit); - } - - @Override - public Future terminationFuture() { - return this.executor.terminationFuture(); - } - - @Override - public boolean isShutdown() { - return this.executor.isShutdown(); - } + public static interface AutoCloseableEventExecutor extends EventExecutor, AutoCloseable { - @Override - public boolean isTerminated() { - return this.executor.isTerminated(); - } - - @Override - public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { - return this.executor.awaitTermination(timeout, unit); - } - - @Override - public void execute(Runnable command) { - this.executor.execute(command); - } - - @Override - public void close() throws Exception { - shutdownGracefully(); - } - - @SuppressWarnings("deprecation") - @Override - public void shutdown() { - this.executor.shutdown(); - } - - @Override - public ScheduledFuture scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { - return this.executor.scheduleWithFixedDelay(command, initialDelay, delay, unit); - } + } - @Override - public ScheduledFuture schedule(Runnable command, long delay, TimeUnit unit) { - return this.executor.schedule(command, delay, unit); - } + public static class CloseableGlobalEventExecutorMixin implements AutoCloseable { + private final GlobalEventExecutor eventExecutor; - @Override - public ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit) { - return this.executor.schedule(callable, delay, unit); + public CloseableGlobalEventExecutorMixin(GlobalEventExecutor eventExecutor) { + this.eventExecutor = eventExecutor; } @Override - public ScheduledFuture scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { - return this.executor.scheduleAtFixedRate(command, initialDelay, period, unit); + public void close() { + eventExecutor.shutdownGracefully(0, 1, TimeUnit.SECONDS); } } } diff --git a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleFactory.java b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleFactory.java index c03ade8b5f..1585bbf6de 100644 --- a/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleFactory.java +++ b/opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleFactory.java @@ -7,21 +7,34 @@ */ /** -* Generated file - -* Generated from: yang module name: netty-event-executor yang module local name: netty-global-event-executor -* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Tue Nov 12 10:44:21 CET 2013 -* -* Do not modify this file unless it is present under src/main directory -*/ + * Generated file + + * Generated from: yang module name: netty-event-executor yang module local name: netty-global-event-executor + * Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + * Generated at: Tue Nov 12 10:44:21 CET 2013 + * + * Do not modify this file unless it is present under src/main directory + */ package org.opendaylight.controller.config.yang.netty.eventexecutor; -/** -* -*/ -public class GlobalEventExecutorModuleFactory extends org.opendaylight.controller.config.yang.netty.eventexecutor.AbstractGlobalEventExecutorModuleFactory -{ +import org.opendaylight.controller.config.api.DependencyResolver; +import org.osgi.framework.BundleContext; + +import static com.google.common.base.Preconditions.checkArgument; + +public class GlobalEventExecutorModuleFactory extends org.opendaylight.controller.config.yang.netty.eventexecutor.AbstractGlobalEventExecutorModuleFactory { + public static final String SINGLETON_NAME = "singleton"; + + @Override + public GlobalEventExecutorModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, GlobalEventExecutorModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) { + checkArgument(SINGLETON_NAME.equals(instanceName),"Illegal instance name '" + instanceName + "', only allowed name is " + SINGLETON_NAME); + return super.instantiateModule(instanceName, dependencyResolver, oldModule, oldInstance, bundleContext); + } + @Override + public GlobalEventExecutorModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) { + checkArgument(SINGLETON_NAME.equals(instanceName),"Illegal instance name '" + instanceName + "', only allowed name is " + SINGLETON_NAME); + return super.instantiateModule(instanceName, dependencyResolver, bundleContext); + } } diff --git a/opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java b/opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java index 71c4b192e5..f29895c6d0 100644 --- a/opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java +++ b/opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java @@ -8,9 +8,6 @@ package org.opendaylight.controller.config.yang.netty.eventexecutor; -import javax.management.InstanceAlreadyExistsException; -import javax.management.ObjectName; - import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.api.ConflictingVersionException; @@ -20,10 +17,16 @@ 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 javax.management.InstanceAlreadyExistsException; +import javax.management.ObjectName; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + public class GlobalEventExecutorModuleTest extends AbstractConfigTest { private GlobalEventExecutorModuleFactory factory; - private final String instanceName = "netty1"; + private final String instanceName = GlobalEventExecutorModuleFactory.SINGLETON_NAME; @Before public void setUp() { @@ -37,12 +40,23 @@ public class GlobalEventExecutorModuleTest extends AbstractConfigTest { ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); createInstance(transaction, instanceName); - createInstance(transaction, instanceName + 2); + transaction.validateConfig(); CommitStatus status = transaction.commit(); - assertBeanCount(2, factory.getImplementationName()); - assertStatus(status, 2, 0, 0); + assertBeanCount(1, factory.getImplementationName()); + assertStatus(status, 1, 0, 0); + } + + @Test + public void testConflictingName() throws Exception { + ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); + try { + createInstance(transaction, instanceName + "x"); + fail(); + }catch(IllegalArgumentException e){ + assertTrue(e.getMessage() + " failure", e.getMessage().contains("only allowed name is singleton")); + } } @Test diff --git a/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModule.java b/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModule.java index 3d5a3bf4ad..06c9ae885d 100644 --- a/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModule.java +++ b/opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModule.java @@ -21,6 +21,8 @@ import io.netty.channel.nio.NioEventLoopGroup; import org.opendaylight.controller.config.api.JmxAttributeValidationException; +import java.util.concurrent.TimeUnit; + /** * */ @@ -61,7 +63,7 @@ public final class NettyThreadgroupModule extends org.opendaylight.controller.co @Override public void close() throws Exception { - shutdownGracefully(); + shutdownGracefully(0, 1, TimeUnit.SECONDS); } } } diff --git a/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java index 584ea1766e..f9622192fe 100644 --- a/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java +++ b/opendaylight/config/shutdown-impl/src/main/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownServiceImpl.java @@ -82,6 +82,7 @@ class Impl implements ShutdownService { class StopSystemBundleThread extends Thread { private static final Logger logger = LoggerFactory.getLogger(StopSystemBundleThread.class); + public static final String CONFIG_MANAGER_SYMBOLIC_NAME = "org.opendaylight.controller.config-manager"; private final Bundle systemBundle; StopSystemBundleThread(Bundle systemBundle) { @@ -94,6 +95,14 @@ class StopSystemBundleThread extends Thread { try { // wait so that JMX response is received Thread.sleep(1000); + // first try to stop config-manager + Bundle configManager = findConfigManager(); + if (configManager != null){ + logger.debug("Stopping config-manager"); + configManager.stop(); + Thread.sleep(1000); + } + logger.debug("Stopping system bundle"); systemBundle.stop(); } catch (BundleException e) { logger.warn("Can not stop OSGi server", e); @@ -101,6 +110,16 @@ class StopSystemBundleThread extends Thread { logger.warn("Shutdown process interrupted", e); } } + + private Bundle findConfigManager() { + for(Bundle bundle: systemBundle.getBundleContext().getBundles()){ + if (CONFIG_MANAGER_SYMBOLIC_NAME.equals(bundle.getSymbolicName())) { + return bundle; + } + } + return null; + } + } class CallSystemExitThread extends Thread { diff --git a/opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java b/opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java index 5887e98f30..d1abe08d52 100644 --- a/opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java +++ b/opendaylight/config/shutdown-impl/src/test/java/org/opendaylight/controller/config/yang/shutdown/impl/ShutdownTest.java @@ -18,6 +18,7 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleF import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; import org.osgi.framework.Bundle; +import javax.management.InstanceNotFoundException; import javax.management.JMX; import javax.management.ObjectName; import java.util.Collections; @@ -26,15 +27,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModuleFactory.NAME; public class ShutdownTest extends AbstractConfigTest { private final ShutdownModuleFactory factory = new ShutdownModuleFactory(); @Mock - private Bundle mockedSysBundle; + private Bundle mockedSysBundle, mockedConfigManager; + @Before public void setUp() throws Exception { @@ -44,6 +44,13 @@ public class ShutdownTest extends AbstractConfigTest { doReturn(mockedSysBundle).when(mockedContext).getBundle(0); mockedContext.getBundle(0); doNothing().when(mockedSysBundle).stop(); + doNothing().when(mockedConfigManager).stop(); + doReturn(mockedContext).when(mockedSysBundle).getBundleContext(); + doReturn(new Bundle[]{mockedSysBundle, mockedConfigManager}).when(mockedContext).getBundles(); + doReturn("system bundle").when(mockedSysBundle).getSymbolicName(); + doReturn(StopSystemBundleThread.CONFIG_MANAGER_SYMBOLIC_NAME).when(mockedConfigManager).getSymbolicName(); + + ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); // initialize default instance transaction.commit(); @@ -80,13 +87,22 @@ public class ShutdownTest extends AbstractConfigTest { @Test public void testWithSecret() throws Exception { + String secret = "secret"; + setSecret(secret); + shutdownViaRuntimeJMX(secret); + } + + private void setSecret(String secret) throws InstanceNotFoundException { ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); ObjectName on = transaction.lookupConfigBean(NAME, NAME); ShutdownModuleMXBean proxy = transaction.newMXBeanProxy(on, ShutdownModuleMXBean.class); - String secret = "secret"; proxy.setSecret(secret); transaction.commit(); - shutdownViaRuntimeJMX(secret); + } + + @Test + public void testWrongSecret() throws Exception { + setSecret("secret"); try { ShutdownRuntimeMXBean runtime = JMX.newMXBeanProxy(platformMBeanServer, runtimeON, ShutdownRuntimeMXBean.class); runtime.shutdown("foo", 60000L, null); @@ -109,12 +125,9 @@ public class ShutdownTest extends AbstractConfigTest { assertStopped(); } - private void assertStopped() throws Exception { - Thread.sleep(2000); // happens on another thread + Thread.sleep(3000); // happens on another thread + verify(mockedConfigManager).stop(); verify(mockedSysBundle).stop(); - verifyNoMoreInteractions(mockedSysBundle); - reset(mockedSysBundle); - doNothing().when(mockedSysBundle).stop(); } } diff --git a/opendaylight/config/threadpool-config-impl/pom.xml b/opendaylight/config/threadpool-config-impl/pom.xml index 49a01819d8..08f1d554f6 100644 --- a/opendaylight/config/threadpool-config-impl/pom.xml +++ b/opendaylight/config/threadpool-config-impl/pom.xml @@ -71,7 +71,7 @@ org.opendaylight.controller.config.threadpool.util, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.threadpool.impl.rev130405.*, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.threadpool.impl.*, diff --git a/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang b/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang index 6ee379623b..c82da58c15 100644 --- a/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang +++ b/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang @@ -41,28 +41,20 @@ module config-test-impl { config:java-name-prefix IdentityTest; } - identity test-identity1 { - - } - - identity test-identity2 { - base test-identity1; - } - augment "/config:modules/config:module/config:configuration" { case impl-identity-test { when "/config:modules/config:module/config:type = 'impl-identity-test'"; leaf afi { type identityref { - base test-identity1; + base tt:test-identity1; } } container identities-container { leaf afi { type identityref { - base test-identity1; + base tt:test-identity1; } } } @@ -70,19 +62,19 @@ module config-test-impl { list identities { leaf afi { type identityref { - base test-identity1; + base tt:test-identity1; } } leaf safi { type identityref { - base test-identity1; + base tt:test-identity1; } } container identities-inner { leaf afi { type identityref { - base test-identity1; + base tt:test-identity1; } } } diff --git a/opendaylight/config/yang-test/src/main/yang/types/test-types.yang b/opendaylight/config/yang-test/src/main/yang/types/test-types.yang index 8c086d8ace..df5387be2c 100644 --- a/opendaylight/config/yang-test/src/main/yang/types/test-types.yang +++ b/opendaylight/config/yang-test/src/main/yang/types/test-types.yang @@ -31,4 +31,13 @@ module test-types { } } + + + identity test-identity1 { + + } + + identity test-identity2 { + base test-identity1; + } } diff --git a/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java b/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java index 31b4c78fe3..281c1aade5 100644 --- a/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java +++ b/opendaylight/config/yang-test/src/test/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleTest.java @@ -19,8 +19,8 @@ import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; 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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.test.impl.rev130403.TestIdentity1; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.test.impl.rev130403.TestIdentity2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2; import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry; import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec; diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml index 9ba590820a..2365c700f9 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml @@ -23,7 +23,7 @@ netty:netty-global-event-executor - global-event-executor + singleton @@ -43,7 +43,7 @@ netty:netty-event-executor global-event-executor - /modules/module[type='netty-global-event-executor'][name='global-event-executor'] + /modules/module[type='netty-global-event-executor'][name='singleton'] diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-capable-transaction.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-capable-transaction.yang index 1c675f015d..160291cf21 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-capable-transaction.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-capable-transaction.yang @@ -1,17 +1,17 @@ module flow-capable-transaction { - namespace "urn:opendaylight:flow:transaction"; + namespace "urn:opendaylight:flow:transaction"; prefix type; import opendaylight-inventory {prefix inv; revision-date "2013-08-19";} import ietf-inet-types {prefix inet; revision-date "2010-09-24";} import yang-ext {prefix ext; revision-date "2013-07-09";} - + revision "2013-11-03" { description "Initial revision"; } typedef transaction-id { - type uint64; + type uint64; } // This refers to MD-SAL transaction reference. grouping transaction-metadata { @@ -19,13 +19,22 @@ module flow-capable-transaction { type inet:uri; } } - + grouping transaction-aware { leaf transaction-id { type transaction-id; } } + grouping multipart-transaction-aware { + uses transaction-aware; + + leaf moreReplies { + type boolean; + default false; + } + } + rpc get-next-transaction-id { input { leaf node { @@ -34,7 +43,7 @@ module flow-capable-transaction { } } output { - uses transaction-aware; + uses transaction-aware; } } @@ -50,4 +59,4 @@ module flow-capable-transaction { } } } -} \ No newline at end of file +} diff --git a/opendaylight/md-sal/model/model-flow-service/src/main/yang/sal-table.yang b/opendaylight/md-sal/model/model-flow-service/src/main/yang/sal-table.yang index 66990d473f..b125116bb1 100644 --- a/opendaylight/md-sal/model/model-flow-service/src/main/yang/sal-table.yang +++ b/opendaylight/md-sal/model/model-flow-service/src/main/yang/sal-table.yang @@ -33,10 +33,7 @@ module sal-table { notification table-updated { uses "inv:node-context-ref"; - uses tr:transaction-aware; - leaf moreReplies { - type boolean; - } + uses tr:multipart-transaction-aware; uses table-type:table-features; } } diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-statistics.yang index 94e2c0a428..e0df924a0e 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-statistics.yang +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-statistics.yang @@ -10,51 +10,51 @@ module opendaylight-flow-statistics { import flow-node-inventory {prefix flow-node;revision-date "2013-08-19";} import flow-capable-transaction {prefix tr;} import ietf-inet-types {prefix inet; revision-date "2010-09-24";} - + revision "2013-08-19" { description "Initial revision of flow statistics service"; } - - //Augment flow statistics data to the flow-capable-node->table->flow - augment "/inv:nodes/inv:node/flow-node:table/flow-node:flow" { + + //Augment flow statistics data to the flow-capable-node->table->flow + augment "/inv:nodes/inv:node/flow-node:table/flow-node:flow" { ext:augment-identifier "flow-statistics-data"; uses flow-statistics; } - - grouping flow-statistics { + + grouping flow-statistics { container flow-statistics { //config "false"; - uses flow-types:flow; - uses stat-types:generic-statistics; + uses flow-types:flow; + uses stat-types:generic-statistics; + } + } + + typedef flow-id { + description "flow id"; + type inet:uri; + } + + grouping flow-and-statistics-map-list { + description "List of flow and statistics map"; + list flow-and-statistics-map-list { + key "flow-id"; + leaf flow-id { + type flow-id; + } + uses flow-and-statistics-map; } - } - - typedef flow-id { - description "flow id"; - type inet:uri; - } - - grouping flow-and-statistics-map-list { - description "List of flow and statistics map"; - list flow-and-statistics-map-list { - key "flow-id"; - leaf flow-id { - type flow-id; - } - uses flow-and-statistics-map; - } - } - - grouping flow-and-statistics-map{ - description "Mapping between flow and its statistics"; - uses flow-types:flow; - uses stat-types:generic-statistics; - } - + } + + grouping flow-and-statistics-map{ + description "Mapping between flow and its statistics"; + uses flow-types:flow; + uses stat-types:generic-statistics; + } + // RPC calls to fetch flow statistics rpc get-all-flows-statistics-from-all-flow-tables { - description "Fetch statistics of all the flow present in all the flow tables of the switch"; + description "Fetch statistics of all the flow present in all the flow tables of the switch"; input { uses inv:node-context-ref; } @@ -62,15 +62,15 @@ module opendaylight-flow-statistics { uses flow-and-statistics-map-list; uses tr:transaction-aware; } - + } rpc get-all-flow-statistics-from-flow-table { - description "Fetch statistics of all the flow present in the specific flow table of the switch"; + description "Fetch statistics of all the flow present in the specific flow table of the switch"; input { uses inv:node-context-ref; leaf table-id { - type table-types:table-id; + type table-types:table-id; } } output { @@ -80,7 +80,7 @@ module opendaylight-flow-statistics { } rpc get-flow-statistics-from-flow-table { - description "Fetch statistics of the specific flow present in the specific flow table of the switch"; + description "Fetch statistics of the specific flow present in the specific flow table of the switch"; input { uses inv:node-context-ref; uses flow-types:flow; @@ -92,61 +92,58 @@ module opendaylight-flow-statistics { } notification flows-statistics-update { - description "Flows statistics sent by switch"; - leaf moreReplies { + description "Flows statistics sent by switch"; + leaf moreReplies { type boolean; } uses inv:node; - uses flow-and-statistics-map-list; - uses tr:transaction-aware; + uses flow-and-statistics-map-list; + uses tr:transaction-aware; } - //Models for aggregate flow statistics collection - augment "/inv:nodes/inv:node/flow-node:table" { + //Models for aggregate flow statistics collection + augment "/inv:nodes/inv:node/flow-node:table" { ext:augment-identifier "aggregate-flow-statistics-data"; uses aggregate-flow-statistics; } - - grouping aggregate-flow-statistics { + + grouping aggregate-flow-statistics { container aggregate-flow-statistics { //config "false"; - uses stat-types:aggregate-flow-statistics; + uses stat-types:aggregate-flow-statistics; } - } - + } + // RPC calls to fetch aggregate flow statistics rpc get-aggregate-flow-statistics-from-flow-table-for-all-flows { - description "Fetch aggregate statistics for all the flows present in the specific flow table of the switch"; + description "Fetch aggregate statistics for all the flows present in the specific flow table of the switch"; input { uses inv:node-context-ref; leaf table-id { - type table-types:table-id; + type table-types:table-id; } } output { - uses stat-types:aggregate-flow-statistics; + uses stat-types:aggregate-flow-statistics; uses tr:transaction-aware; } } rpc get-aggregate-flow-statistics-from-flow-table-for-given-match { - description "Fetch aggregate statistics for all the flow matches to the given match from the given table of the switch"; + description "Fetch aggregate statistics for all the flow matches to the given match from the given table of the switch"; input { uses inv:node-context-ref; uses flow-types:flow; } output { - uses stat-types:aggregate-flow-statistics; + uses stat-types:aggregate-flow-statistics; uses tr:transaction-aware; } } notification aggregate-flow-statistics-update { - description "Aggregate flow statistics for a table, sent by switch"; - leaf moreReplies { - type boolean; - } + description "Aggregate flow statistics for a table, sent by switch"; uses inv:node; - uses stat-types:aggregate-flow-statistics; - uses tr:transaction-aware; + uses stat-types:aggregate-flow-statistics; + uses tr:multipart-transaction-aware; } } diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-table-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-table-statistics.yang index ab84f50f31..431ef50624 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-table-statistics.yang +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-table-statistics.yang @@ -2,7 +2,7 @@ module opendaylight-flow-table-statistics { namespace "urn:opendaylight:flow:table:statistics"; prefix flowtablestat; - import flow-capable-transaction {prefix tr;} + import flow-capable-transaction {prefix tr;} import yang-ext {prefix ext; revision-date "2013-07-09";} import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} import flow-node-inventory {prefix flow-node;revision-date "2013-08-19";} @@ -19,50 +19,47 @@ module opendaylight-flow-table-statistics { } //Augment flow table statistics data to the table - augment "/inv:nodes/inv:node/flow-node:table" { + augment "/inv:nodes/inv:node/flow-node:table" { ext:augment-identifier "flow-table-statistics-data"; uses flow-table-statistics; } - - grouping flow-table-statistics { + + grouping flow-table-statistics { container flow-table-statistics { //config "false"; - uses stat-types:generic-table-statistics; + uses stat-types:generic-table-statistics; } - } + } //RPC calls to fetch flow table statistics grouping flow-table-and-statistics-map { - list flow-table-and-statistics-map { - key "table-id"; - leaf table-id { - type table-types:table-id; - } - uses stat-types:generic-table-statistics; - } + list flow-table-and-statistics-map { + key "table-id"; + leaf table-id { + type table-types:table-id; + } + uses stat-types:generic-table-statistics; + } } rpc get-flow-tables-statistics { - description "Fetch statistics of all the flow tables present on the tarnet node"; - input { - uses inv:node-context-ref; - } - output { - uses flow-table-and-statistics-map; - uses tr:transaction-aware; - } + description "Fetch statistics of all the flow tables present on the tarnet node"; + input { + uses inv:node-context-ref; + } + output { + uses flow-table-and-statistics-map; + uses tr:transaction-aware; + } } //Notification to receive table statistics update notification flow-table-statistics-update { - description "Receive flow table statistics update"; - - leaf moreReplies { - type boolean; - } + description "Receive flow table statistics update"; + uses inv:node; - uses flow-table-and-statistics-map; - uses tr:transaction-aware; + uses flow-table-and-statistics-map; + uses tr:multipart-transaction-aware; } } diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-group-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-group-statistics.yang index 2f5c5bbe0a..7779819918 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-group-statistics.yang +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-group-statistics.yang @@ -16,37 +16,37 @@ module opendaylight-group-statistics { description "Initial revision of group statistics service"; } - grouping group-statistics { + grouping group-statistics { container group-statistics { //config "false"; uses group-types:group-statistics; } - } + } augment "/inv:nodes/inv:node/fni:group" { ext:augment-identifier "node-group-statistics"; uses group-statistics; } - grouping group-desc { + grouping group-desc { container group-desc { //config "false"; uses group-types:group; } - } + } augment "/inv:nodes/inv:node/fni:group" { ext:augment-identifier "node-group-desc-stats"; uses group-desc; } - grouping group-features { - container group-features { + grouping group-features { + container group-features { //config "false"; uses group-types:group-features-reply; } } - + augment "/inv:nodes/inv:node" { ext:augment-identifier "node-group-features"; uses group-features; @@ -103,29 +103,20 @@ module opendaylight-group-statistics { //Notification calls notification group-statistics-updated { - leaf moreReplies { - type boolean; - } uses inv:node; uses group-types:group-statistics-reply; - uses tr:transaction-aware; + uses tr:multipart-transaction-aware; } notification group-desc-stats-updated { - leaf moreReplies { - type boolean; - } uses inv:node; uses group-types:group-desc-stats-reply; - uses tr:transaction-aware; + uses tr:multipart-transaction-aware; } notification group-features-updated { - leaf moreReplies { - type boolean; - } uses inv:node; uses group-types:group-features-reply; - uses tr:transaction-aware; + uses tr:multipart-transaction-aware; } } diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-meter-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-meter-statistics.yang index b2cf78b61d..0055dc39bd 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-meter-statistics.yang +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-meter-statistics.yang @@ -90,32 +90,20 @@ module opendaylight-meter-statistics { //Notification calls notification meter-statistics-updated { - leaf moreReplies { - type boolean; - } - uses inv:node; uses meter-types:meter-statistics-reply; - uses tr:transaction-aware; + uses tr:multipart-transaction-aware; } notification meter-config-stats-updated { - leaf moreReplies { - type boolean; - } - uses inv:node; uses meter-types:meter-config-stats-reply; - uses tr:transaction-aware; + uses tr:multipart-transaction-aware; } notification meter-features-updated { - leaf moreReplies { - type boolean; - } - uses inv:node; uses meter-types:meter-features-reply; - uses tr:transaction-aware; + uses tr:multipart-transaction-aware; } } diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-port-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-port-statistics.yang index 22f0aca5e7..e711877a02 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-port-statistics.yang +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-port-statistics.yang @@ -2,7 +2,7 @@ module opendaylight-port-statistics { namespace "urn:opendaylight:port:statistics"; prefix portstat; - import flow-capable-transaction {prefix tr;} + import flow-capable-transaction {prefix tr;} import yang-ext {prefix ext; revision-date "2013-07-09";} import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} import opendaylight-statistics-types {prefix stat-types;revision-date "2013-09-25";} @@ -14,64 +14,61 @@ module opendaylight-port-statistics { revision "2013-12-14" { description "Initial revision of port statistics model"; } - + //Augment port statistics data to the flow-capable-node-connector - augment "/inv:nodes/inv:node/inv:node-connector" { + augment "/inv:nodes/inv:node/inv:node-connector" { ext:augment-identifier "flow-capable-node-connector-statistics-data"; uses flow-capable-node-connector-statistics; } - - grouping flow-capable-node-connector-statistics { + + grouping flow-capable-node-connector-statistics { container flow-capable-node-connector-statistics { //config "false"; uses stat-types:node-connector-statistics; } - } - + } + // RPC calls rpc get-all-node-connectors-statistics { - description "Get statistics for all node connectors from the node"; + description "Get statistics for all node connectors from the node"; input { uses inv:node-context-ref; } output { - uses node-connector-statistics-and-port-number-map; + uses node-connector-statistics-and-port-number-map; uses tr:transaction-aware; } } - + rpc get-node-connector-statistics { - description "Get statistics for given node connector from the node"; - input { - uses inv:node-context-ref; - leaf node-connector-id { - type inv:node-connector-id; - } - } - output { + description "Get statistics for given node connector from the node"; + input { + uses inv:node-context-ref; + leaf node-connector-id { + type inv:node-connector-id; + } + } + output { uses stat-types:node-connector-statistics; uses tr:transaction-aware; - } + } } - - //Notification for node connector statistics update - grouping node-connector-statistics-and-port-number-map { - description "List of map - node connectors and their statistics"; - list node-connector-statistics-and-port-number-map { - key "node-connector-id"; - leaf node-connector-id { - type inv:node-connector-id; - } - uses stat-types:node-connector-statistics; - } - } - notification node-connector-statistics-update { - leaf moreReplies { - type boolean; + //Notification for node connector statistics update + grouping node-connector-statistics-and-port-number-map { + description "List of map - node connectors and their statistics"; + list node-connector-statistics-and-port-number-map { + key "node-connector-id"; + leaf node-connector-id { + type inv:node-connector-id; + } + uses stat-types:node-connector-statistics; } + } + + notification node-connector-statistics-update { uses inv:node; - uses node-connector-statistics-and-port-number-map; - uses tr:transaction-aware; + uses node-connector-statistics-and-port-number-map; + uses tr:multipart-transaction-aware; } } diff --git a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-queue-statistics.yang b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-queue-statistics.yang index 9c48cfdbe8..caf52aa9ef 100644 --- a/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-queue-statistics.yang +++ b/opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-queue-statistics.yang @@ -2,7 +2,7 @@ module opendaylight-queue-statistics { namespace "urn:opendaylight:queue:statistics"; prefix queuestat; - import flow-capable-transaction {prefix tr;} + import flow-capable-transaction {prefix tr;} import yang-ext {prefix ext; revision-date "2013-07-09";} import opendaylight-inventory {prefix inv;revision-date "2013-08-19";} import flow-node-inventory {prefix flow-node;revision-date "2013-08-19";} @@ -18,35 +18,35 @@ module opendaylight-queue-statistics { } //Augment queue statistics data to the flow-capable-node-connector - augment "/inv:nodes/inv:node/inv:node-connector/flow-node:queue" { + augment "/inv:nodes/inv:node/inv:node-connector/flow-node:queue" { ext:augment-identifier "flow-capable-node-connector-queue-statistics-data"; uses flow-capable-node-connector-queue-statistics; } - - grouping flow-capable-node-connector-queue-statistics { + + grouping flow-capable-node-connector-queue-statistics { container flow-capable-node-connector-queue-statistics { //config "false"; uses stat-types:generic-queue-statistics; } - } - - //RPC calls to fetch queue statistics + } + + //RPC calls to fetch queue statistics grouping queue-id-and-statistics-map { - list queue-id-and-statistics-map { - key "queue-id node-connector-id"; - leaf queue-id { - type queue-types:queue-id; - } - leaf node-connector-id { - type inv:node-connector-id; - } - + list queue-id-and-statistics-map { + key "queue-id node-connector-id"; + leaf queue-id { + type queue-types:queue-id; + } + leaf node-connector-id { + type inv:node-connector-id; + } + uses stat-types:generic-queue-statistics; - } + } } rpc get-all-queues-statistics-from-all-ports { - description "Get statistics for all the queues attached to all the ports from the node"; + description "Get statistics for all the queues attached to all the ports from the node"; input { uses inv:node-context-ref; } @@ -57,44 +57,41 @@ module opendaylight-queue-statistics { } rpc get-all-queues-statistics-from-given-port { - description "Get statistics for all queues for given port of the node"; - input { - uses inv:node-context-ref; - leaf node-connector-id { - type inv:node-connector-id; - } - } - output { + description "Get statistics for all queues for given port of the node"; + input { + uses inv:node-context-ref; + leaf node-connector-id { + type inv:node-connector-id; + } + } + output { uses queue-id-and-statistics-map; uses tr:transaction-aware; - } + } } rpc get-queue-statistics-from-given-port { - description "Get statistics for given queues from given port of the node"; - input { - uses inv:node-context-ref; - leaf node-connector-id { - type inv:node-connector-id; - } - leaf queue-id { - type queue-types:queue-id; - } - } - output { + description "Get statistics for given queues from given port of the node"; + input { + uses inv:node-context-ref; + leaf node-connector-id { + type inv:node-connector-id; + } + leaf queue-id { + type queue-types:queue-id; + } + } + output { uses queue-id-and-statistics-map; uses tr:transaction-aware; - } + } } //Notification for port statistics update - notification queue-statistics-update { - leaf moreReplies { - type boolean; - } + notification queue-statistics-update { uses inv:node; - uses queue-id-and-statistics-map; - uses tr:transaction-aware; + uses queue-id-and-statistics-map; + uses tr:multipart-transaction-aware; } } diff --git a/opendaylight/md-sal/sal-binding-broker/pom.xml b/opendaylight/md-sal/sal-binding-broker/pom.xml index 5367498777..28ffff8b2d 100644 --- a/opendaylight/md-sal/sal-binding-broker/pom.xml +++ b/opendaylight/md-sal/sal-binding-broker/pom.xml @@ -91,7 +91,6 @@ ${project.groupId}.${project.artifactId} - org.opendaylight.controller.sal.binding.osgi.Activator org.opendaylight.controller.sal.binding.spi.*, diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java index 790c1fcd4c..4deef69198 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java @@ -25,7 +25,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; public class SingletonHolder { - public static final ClassPool CLASS_POOL = new ClassPool(); + public static final ClassPool CLASS_POOL = ClassPool.getDefault(); public static final org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator RPC_GENERATOR_IMPL = new org.opendaylight.controller.sal.binding.codegen.impl.RuntimeCodeGenerator( CLASS_POOL); public static final RuntimeCodeGenerator RPC_GENERATOR = RPC_GENERATOR_IMPL; diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index f1d412cdb0..482dcf8e8b 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend @@ -603,10 +603,13 @@ class ControllerContext implements SchemaServiceListener { } override onGlobalContextUpdated(SchemaContext context) { - this.globalSchema = context; - for (operation : context.operations) { - val qname = operation.QName; - qnameToRpc.put(qname, operation); + if (context !== null) { + qnameToRpc.clear + this.globalSchema = context; + for (operation : context.operations) { + val qname = operation.QName; + qnameToRpc.put(qname, operation); + } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index d699d224bb..72d62efe84 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -78,8 +78,8 @@ import org.opendaylight.controller.netconf.util.test.XmlFileLoader; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.test.impl.rev130403.TestIdentity1; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.test.impl.rev130403.TestIdentity2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity2; import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry; import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec; import org.opendaylight.yangtools.yang.model.api.Module; diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java index 95f7353600..b8dc9550c7 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java @@ -26,6 +26,7 @@ import java.lang.management.ManagementFactory; import java.net.InetSocketAddress; import java.util.Dictionary; import java.util.Hashtable; +import java.util.concurrent.TimeUnit; public class NetconfImplActivator implements BundleActivator { @@ -88,7 +89,7 @@ public class NetconfImplActivator implements BundleActivator { logger.info("Shutting down netconf because YangStoreService service was removed"); commitNot.close(); - eventLoopGroup.shutdownGracefully(); + eventLoopGroup.shutdownGracefully(0, 1, TimeUnit.SECONDS); timer.stop(); regMonitoring.unregister(); diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_identities.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_identities.xml index 62c6a20997..8062f52e6a 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_identities.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_identities.xml @@ -15,17 +15,17 @@ id-test - prefix:test-identity1 - prefix:test-identity2 + prefix:test-identity1 + prefix:test-identity2 - prefix:test-identity2 - prefix:test-identity1 + prefix:test-identity2 + prefix:test-identity1 - prefix:test-identity2 + prefix:test-identity2 - prefix:test-identity1 + prefix:test-identity1