From: Ed Warnicke Date: Thu, 1 May 2014 14:53:30 +0000 (+0000) Subject: Merge "Bug 618 - convert xtend to java in md-sal/inventory-manager" X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~149 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=abca01a0016ee55b6cdcb71c81419c4b143bb63a;hp=9b8841d9c7c5dc29eb0a77ead6bbc0ebe3d6875f;p=controller.git Merge "Bug 618 - convert xtend to java in md-sal/inventory-manager" --- diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 4a7a395693..e0891662ea 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -15,25 +15,40 @@ + 1.0.0 + 0.4.2-SNAPSHOT + 0.5.2-SNAPSHOT + + 1.50 2.3.7 0.4.2-SNAPSHOT 2.10 0.5.1-SNAPSHOT 0.4.3-SNAPSHOT 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT + + 1.7 + 1.2.2 0.1.2-SNAPSHOT 2.4 3.1 + 3.0.1 2.3.2 0.5.2-SNAPSHOT 0.2.5-SNAPSHOT + 0.4.3-SNAPSHOT 0.4.3-SNAPSHOT 0.1.2-SNAPSHOT 0.5.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.5.2-SNAPSHOT - + 0.0.2-SNAPSHOT 7.0.42 + 0.4.2-SNAPSHOT + 2.5.0 1.3.1 1.26.2 @@ -42,12 +57,22 @@ 0000.0002.0038.0-SNAPSHOT 2.15 + 3.0.1 + 3.1.0 + 3.1.6 + 4.2.0 + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.5.2-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.6.0-SNAPSHOT 2.2.0.RELEASE + 2.2.4 14.0.1 0.5.2-SNAPSHOT 0.5.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.4.2-SNAPSHOT 2010.09.24.4-SNAPSHOT 2013.10.21.2-SNAPSHOT @@ -61,8 +86,11 @@ 1.17 1.17 + 1.3.3 src/main/yang-gen-config 1.1.4 + 2.0.1 + 1.1.1 4.8.1 1.0.9 0.4.2-SNAPSHOT @@ -75,24 +103,34 @@ 0.2.5-SNAPSHOT 4.0.17.Final 0.0.3-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT http://nexus.opendaylight.org/content 2013.08.27.4-SNAPSHOT + 0.0.2-SNAPSHOT + 5.0.0 5.0.0 UTF-8 UTF-8 2.6 - 1.0-alpha-2 0.5.0-SNAPSHOT - 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 2.3.2 + 0.4.2-SNAPSHOT 0.1.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.0.3-SNAPSHOT 0.8.1-SNAPSHOT src/main/yang-gen-sal 0.5.2-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT dav:http://nexus.opendaylight.org/content/sites/site 3.2 1.7.2 @@ -105,14 +143,25 @@ 1.2.1 3.1.3.RELEASE 3.1.3.RELEASE + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.5.1-SNAPSHOT + 0.4.2-SNAPSHOT 2.15 0.7.1-SNAPSHOT + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT -Xmx1024m -XX:MaxPermSize=256m + 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 0.4.2-SNAPSHOT + 0.4.2-SNAPSHOT 1.5.0 + 0.4.2-SNAPSHOT + 0.0.2-SNAPSHOT 0.4.2-SNAPSHOT 3.6.0.RELEASE + 0.4.2-SNAPSHOT src/main/xtend-gen 2.4.3 2013.09.07.4-SNAPSHOT @@ -142,37 +191,31 @@ logback-core ${logback.version} - com.fasterxml.jackson.core jackson-annotations ${jackson.version} - com.fasterxml.jackson.core jackson-core ${jackson.version} - com.fasterxml.jackson.core jackson-databind ${jackson.version} - com.fasterxml.jackson.jaxrs jackson-jaxrs-base ${jackson.version} - com.fasterxml.jackson.jaxrs jackson-jaxrs-json-provider ${jackson.version} - com.fasterxml.jackson.module jackson-module-jaxb-annotations @@ -181,12 +224,12 @@ com.google.code.findbugs jsr305 - 2.0.1 + ${jsr305.api.version} com.google.code.gson gson - 2.2.4 + ${gson.version} com.google.guava @@ -212,12 +255,12 @@ commons-codec commons-codec - 1.7 + ${commons.codec.version} commons-fileupload commons-fileupload - 1.2.2 + ${commons.fileupload.version} commons-io @@ -227,7 +270,7 @@ commons-net commons-net - 3.0.1 + ${commons.net.version} eclipselink @@ -370,8 +413,7 @@ netty-common ${netty.version} - - + io.netty netty-handler @@ -382,6 +424,11 @@ netty-transport ${netty.version} + + javax.ws.rs + jsr311-api + ${jsr311.api.version} + orbit javax.activation @@ -470,7 +517,7 @@ org.aopalliance com.springsource.org.aopalliance - 1.0.0 + ${aopalliance.version} org.apache.commons @@ -480,46 +527,45 @@ org.apache.felix org.apache.felix.dependencymanager - 3.1.0 + ${felix.dependencymanager.version} org.apache.felix org.apache.felix.dependencymanager.shell - 3.0.1 + ${felix.dependencymanager.shell.version} org.apache.felix org.apache.felix.fileinstall - 3.1.6 + ${felix.fileinstall.version} org.apache.felix org.apache.felix.webconsole - 4.2.0 + ${felix.webconsole.version} all org.bouncycastle bcpkix-jdk15on - 1.50 + ${bouncycastle.version} org.bouncycastle bcprov-jdk15on - 1.50 + ${bouncycastle.version} org.codehaus.enunciate enunciate-core-annotations ${enunciate.version} - org.codehaus.jettison jettison - 1.3.3 + ${jettison.version} @@ -531,17 +577,17 @@ org.eclipse.persistence org.eclipse.persistence.antlr - 2.5.0 + ${eclipse.persistence.version} org.eclipse.persistence org.eclipse.persistence.core - 2.5.0 + ${eclipse.persistence.version} org.eclipse.persistence org.eclipse.persistence.moxy - 2.5.0 + ${eclipse.persistence.version} @@ -568,7 +614,7 @@ org.opendaylight.controller appauth - 0.4.2-SNAPSHOT + ${appauth.version} org.opendaylight.controller @@ -605,7 +651,7 @@ org.opendaylight.controller clustering.test - 0.4.2-SNAPSHOT + ${clustering.test.version} org.opendaylight.controller @@ -617,7 +663,7 @@ org.opendaylight.controller commons.northbound - 0.4.2-SNAPSHOT + ${commmons.northbound.version} org.opendaylight.controller @@ -693,7 +739,7 @@ org.opendaylight.controller configuration.implementation - 0.4.3-SNAPSHOT + ${configuration.implementation.version} org.opendaylight.controller @@ -728,27 +774,27 @@ org.opendaylight.controller containermanager.northbound - 0.4.2-SNAPSHOT + ${containermanager.northbound.version} org.opendaylight.controller controllermanager.northbound - 0.0.2-SNAPSHOT + ${controllermanager.northbound.version} org.opendaylight.controller devices.web - 0.4.2-SNAPSHOT + ${devices.web.version} org.opendaylight.controller flowprogrammer.northbound - 0.4.2-SNAPSHOT + ${flowprogrammer.northbound.version} org.opendaylight.controller flows.web - 0.4.2-SNAPSHOT + ${flows.web.version} org.opendaylight.controller @@ -758,7 +804,7 @@ org.opendaylight.controller forwarding.staticrouting.northbound - 0.4.2-SNAPSHOT + ${forwarding.staticrouting.northbound.version} org.opendaylight.controller @@ -768,7 +814,7 @@ org.opendaylight.controller forwardingrulesmanager.implementation - 0.4.2-SNAPSHOT + ${forwardingrulesmanager.implementation.version} @@ -784,7 +830,7 @@ org.opendaylight.controller hosttracker.northbound - 0.4.2-SNAPSHOT + ${hosttracker.northbound.version} org.opendaylight.controller @@ -897,22 +943,22 @@ org.opendaylight.controller networkconfig.neutron - 0.4.2-SNAPSHOT + ${networkconfig.neutron.version} org.opendaylight.controller networkconfig.neutron.implementation - 0.4.2-SNAPSHOT + ${networkconfig.neutron.implementation.version} org.opendaylight.controller networkconfig.neutron.northbound - 0.4.2-SNAPSHOT + ${networkconfig.neutron.northbound.version} org.opendaylight.controller osgi-brandfragment.web - 0.0.2-SNAPSHOT + ${osgi-brandfragment.web.version} @@ -925,17 +971,17 @@ org.opendaylight.controller protocol_plugins.openflow - 0.4.2-SNAPSHOT + ${protocol_plugins.openflow.version} org.opendaylight.controller protocol_plugins.stub - ${protocol_plugin.stub.version} + ${protocol_plugins.stub.version} org.opendaylight.controller routing.dijkstra_implementation - 0.4.2-SNAPSHOT + ${routing.dijkstra_implementation.version} @@ -1049,7 +1095,7 @@ org.opendaylight.controller sal.implementation - 0.4.2-SNAPSHOT + ${sal.implementation.version} org.opendaylight.controller @@ -1071,12 +1117,12 @@ org.opendaylight.controller samples.loadbalancer.northbound - 0.4.2-SNAPSHOT + ${samples.loadbalancer.northbound.version} org.opendaylight.controller samples.simpleforwarding - 0.4.2-SNAPSHOT + ${samples.simpleforwarding.version} org.opendaylight.controller @@ -1086,7 +1132,7 @@ org.opendaylight.controller security - 0.4.2-SNAPSHOT + ${security.version} @@ -1102,7 +1148,7 @@ org.opendaylight.controller statistics.northbound - 0.4.2-SNAPSHOT + ${statistics.northbound.version} org.opendaylight.controller @@ -1112,12 +1158,12 @@ org.opendaylight.controller statisticsmanager.implementation - 0.4.2-SNAPSHOT + ${statisticsmanager.implementation.version} org.opendaylight.controller subnets.northbound - 0.4.2-SNAPSHOT + ${subnets.northbound.version} org.opendaylight.controller @@ -1127,12 +1173,12 @@ org.opendaylight.controller switchmanager.implementation - 0.4.2-SNAPSHOT + ${switchmanager.implementation.version} org.opendaylight.controller switchmanager.northbound - 0.4.2-SNAPSHOT + ${switchmanager.northbound.version} @@ -1149,12 +1195,12 @@ org.opendaylight.controller topology.northbound - 0.4.2-SNAPSHOT + ${topology.northbound.version} org.opendaylight.controller topology.web - 0.4.2-SNAPSHOT + ${topology.web.version} org.opendaylight.controller @@ -1164,7 +1210,7 @@ org.opendaylight.controller troubleshoot.web - 0.4.2-SNAPSHOT + ${troubleshoot.web.version} org.opendaylight.controller @@ -1174,19 +1220,19 @@ org.opendaylight.controller usermanager.implementation - ${usermanager.version} + ${usermanager.implementation.version} org.opendaylight.controller usermanager.northbound - 0.0.2-SNAPSHOT + ${usermanager.northbound.version} org.opendaylight.controller web - 0.4.2-SNAPSHOT + ${web.version} org.opendaylight.controller @@ -1406,7 +1452,7 @@ org.osgi org.osgi.compendium - ${osgi.core.version} + ${osgi.compendium.version} org.osgi diff --git a/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/NeverReconnectStrategyModuleTest.java b/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/NeverReconnectStrategyModuleTest.java index d77c9aa962..1148c6bebe 100644 --- a/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/NeverReconnectStrategyModuleTest.java +++ b/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/NeverReconnectStrategyModuleTest.java @@ -7,12 +7,6 @@ */ package org.opendaylight.controller.config.yang.protocol.framework; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import javax.management.InstanceAlreadyExistsException; -import javax.management.ObjectName; - import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.api.ConflictingVersionException; @@ -23,6 +17,12 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory; +import javax.management.InstanceAlreadyExistsException; +import javax.management.ObjectName; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + public class NeverReconnectStrategyModuleTest extends AbstractConfigTest { private static final String INSTANCE_NAME = "never-reconect-strategy-factory-impl"; @@ -30,7 +30,7 @@ public class NeverReconnectStrategyModuleTest extends AbstractConfigTest { @Before public void setUp() throws Exception { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, new NeverReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory())); } diff --git a/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/ReconnectImmediatelyStrategyModuleTest.java b/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/ReconnectImmediatelyStrategyModuleTest.java index 24a0e912a3..9beadc4dbb 100644 --- a/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/ReconnectImmediatelyStrategyModuleTest.java +++ b/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/ReconnectImmediatelyStrategyModuleTest.java @@ -29,7 +29,7 @@ public class ReconnectImmediatelyStrategyModuleTest extends AbstractConfigTest { @Before public void setUp() throws Exception { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, new ReconnectImmediatelyStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory())); } diff --git a/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/TimedReconnectStrategyModuleTest.java b/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/TimedReconnectStrategyModuleTest.java index d051a00a12..a8cdff7119 100644 --- a/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/TimedReconnectStrategyModuleTest.java +++ b/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/TimedReconnectStrategyModuleTest.java @@ -7,15 +7,6 @@ */ package org.opendaylight.controller.config.yang.protocol.framework; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.math.BigDecimal; - -import javax.management.InstanceAlreadyExistsException; -import javax.management.ObjectName; - import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.api.ConflictingVersionException; @@ -26,6 +17,14 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory; +import javax.management.InstanceAlreadyExistsException; +import javax.management.ObjectName; +import java.math.BigDecimal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + public class TimedReconnectStrategyModuleTest extends AbstractConfigTest { private static final String INSTANCE_NAME = "timed-reconect-stategy-facotry-impl"; @@ -33,7 +32,7 @@ public class TimedReconnectStrategyModuleTest extends AbstractConfigTest { @Before public void setUp() throws Exception { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, new TimedReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory())); } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java index 8c325079d3..bf010bb3a6 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/CloseableServiceReferenceReadableRegistry.java @@ -9,9 +9,12 @@ package org.opendaylight.controller.config.manager.impl; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; +/** + * Interface exposing some internal state on top of ServiceReferenceReadableRegistry. This will + * not be exposed via JMX. + */ public interface CloseableServiceReferenceReadableRegistry extends AutoCloseable, ServiceReferenceReadableRegistry { - void close(); } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java index e914162671..8f85972d05 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java @@ -11,8 +11,8 @@ import com.google.common.collect.Maps; import org.opendaylight.controller.config.api.ConflictingVersionException; import org.opendaylight.controller.config.api.ModuleIdentifier; import org.opendaylight.controller.config.api.RuntimeBeanRegistratorAwareModule; -import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry; import org.opendaylight.controller.config.api.ValidationException; +import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation; import org.opendaylight.controller.config.api.jmx.CommitStatus; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.manager.impl.dependencyresolver.DestroyedModule; @@ -159,13 +159,24 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe } }; - Map> allCurrentFactories = Collections.unmodifiableMap( + Map> allCurrentFactories = new HashMap<>( resolver.getAllFactories()); + // add all factories that disappeared from SR but are still committed + for (ModuleInternalInfo moduleInternalInfo : currentConfig.getEntries()) { + String name = moduleInternalInfo.getModuleFactory().getImplementationName(); + if (allCurrentFactories.containsKey(name) == false) { + logger.trace("Factory {} not found in SR, using reference from previous commit", name); + allCurrentFactories.put(name, + Maps.immutableEntry(moduleInternalInfo.getModuleFactory(), moduleInternalInfo.getBundleContext())); + } + } + allCurrentFactories = Collections.unmodifiableMap(allCurrentFactories); + // closed by transaction controller ConfigTransactionLookupRegistry txLookupRegistry = new ConfigTransactionLookupRegistry(new TransactionIdentifier( transactionName), factory, allCurrentFactories); - ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry( + SearchableServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry( readableSRRegistry, txLookupRegistry, allCurrentFactories); ConfigTransactionControllerInternal transactionController = new ConfigTransactionControllerImpl( @@ -216,16 +227,14 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe // non recoverable from here: try { return secondPhaseCommit(configTransactionController, commitInfo, configTransactionControllerEntry.getValue()); - } catch (Throwable t) { // some libs throw Errors: e.g. + } catch (Error | RuntimeException t) { // some libs throw Errors: e.g. // javax.xml.ws.spi.FactoryFinder$ConfigurationError isHealthy = false; logger.error("Configuration Transaction failed on 2PC, server is unhealthy", t); if (t instanceof RuntimeException) { throw (RuntimeException) t; - } else if (t instanceof Error) { - throw (Error) t; } else { - throw new RuntimeException(t); + throw (Error) t; } } } @@ -344,24 +353,20 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe // register to JMX try { - newModuleJMXRegistrator.registerMBean(newReadableConfigBean, - primaryReadOnlyON); + newModuleJMXRegistrator.registerMBean(newReadableConfigBean, primaryReadOnlyON); } catch (InstanceAlreadyExistsException e) { - throw new IllegalStateException(e); + throw new IllegalStateException("Possible code error, already registered:" + primaryReadOnlyON,e); } - // register to OSGi + // register services to OSGi + Map annotationMapping = configTransactionController.getWritableRegistry().findServiceInterfaces(moduleIdentifier); + BundleContext bc = configTransactionController.getModuleFactoryBundleContext( + entry.getModuleFactory().getImplementationName()); if (osgiRegistration == null) { - ModuleFactory moduleFactory = entry.getModuleFactory(); - if (moduleFactory != null) { - BundleContext bc = configTransactionController. - getModuleFactoryBundleContext(moduleFactory.getImplementationName()); - osgiRegistration = beanToOsgiServiceManager.registerToOsgi(realModule.getClass(), - newReadableConfigBean.getInstance(), entry.getIdentifier(), bc); - } else { - throw new NullPointerException(entry.getIdentifier().getFactoryName() + " ModuleFactory not found."); - } - + osgiRegistration = beanToOsgiServiceManager.registerToOsgi( + newReadableConfigBean.getInstance(), moduleIdentifier, bc, annotationMapping); + } else { + osgiRegistration.updateRegistrations(annotationMapping, bc, instance); } RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator = runtimeRegistrators @@ -369,7 +374,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe ModuleInternalInfo newInfo = new ModuleInternalInfo( entry.getIdentifier(), newReadableConfigBean, osgiRegistration, runtimeBeanRegistrator, newModuleJMXRegistrator, - orderingIdx, entry.isDefaultBean()); + orderingIdx, entry.isDefaultBean(), entry.getModuleFactory(), entry.getBundleContext()); newConfigEntries.put(realModule, newInfo); orderingIdx++; diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java index bc4de5cc15..3e23120182 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java @@ -7,9 +7,25 @@ */ package org.opendaylight.controller.config.manager.impl; +import static java.lang.String.format; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.Nullable; +import javax.annotation.concurrent.GuardedBy; +import javax.management.DynamicMBean; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanServer; +import javax.management.ObjectName; import org.opendaylight.controller.config.api.DependencyResolver; import org.opendaylight.controller.config.api.ModuleIdentifier; -import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry; import org.opendaylight.controller.config.api.ValidationException; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.manager.impl.dependencyresolver.DependencyResolverManager; @@ -28,25 +44,7 @@ import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nullable; -import javax.annotation.concurrent.GuardedBy; -import javax.management.DynamicMBean; -import javax.management.InstanceAlreadyExistsException; -import javax.management.InstanceNotFoundException; -import javax.management.MBeanServer; -import javax.management.ObjectName; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - import static com.google.common.base.Preconditions.checkNotNull; -import static java.lang.String.format; - /** * This is a JMX bean representing current transaction. It contains * transaction identifier, unique version and parent version for @@ -82,13 +80,13 @@ class ConfigTransactionControllerImpl implements private final boolean blankTransaction; @GuardedBy("this") - private final ServiceReferenceWritableRegistry writableSRRegistry; + private final SearchableServiceReferenceWritableRegistry writableSRRegistry; public ConfigTransactionControllerImpl(ConfigTransactionLookupRegistry txLookupRegistry, long parentVersion, CodecRegistry codecRegistry, long currentVersion, Map> currentlyRegisteredFactories, MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer, - boolean blankTransaction, ServiceReferenceWritableRegistry writableSRRegistry) { + boolean blankTransaction, SearchableServiceReferenceWritableRegistry writableSRRegistry) { this.txLookupRegistry = txLookupRegistry; String transactionName = txLookupRegistry.getTransactionIdentifier().getName(); this.controllerON = ObjectNameUtil.createTransactionControllerON(transactionName); @@ -139,14 +137,16 @@ class ConfigTransactionControllerImpl implements } // add default modules for (ModuleFactory moduleFactory : toBeAdded) { + BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName()); Set defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager, - getModuleFactoryBundleContext(moduleFactory.getImplementationName())); + bundleContext); for (Module module : defaultModules) { // ensure default module to be registered to jmx even if its module factory does not use dependencyResolverFactory DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(module.getIdentifier()); try { boolean defaultBean = true; - putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null, dependencyResolver, defaultBean); + putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null, + dependencyResolver, defaultBean, bundleContext); } catch (InstanceAlreadyExistsException e) { throw new IllegalStateException(e); } @@ -163,21 +163,26 @@ class ConfigTransactionControllerImpl implements } - private synchronized void copyExistingModule( - ModuleInternalInfo oldConfigBeanInfo) - throws InstanceAlreadyExistsException { + private synchronized void copyExistingModule(ModuleInternalInfo oldConfigBeanInfo) throws InstanceAlreadyExistsException { + transactionStatus.checkNotCommitStarted(); transactionStatus.checkNotAborted(); ModuleIdentifier moduleIdentifier = oldConfigBeanInfo.getIdentifier(); dependencyResolverManager.assertNotExists(moduleIdentifier); - ModuleFactory moduleFactory = factoriesHolder - .findByModuleName(moduleIdentifier.getFactoryName()); + ModuleFactory moduleFactory; + BundleContext bc; + try { + moduleFactory = factoriesHolder.findByModuleName(moduleIdentifier.getFactoryName()); + bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName()); + } catch (InstanceNotFoundException e) { + throw new IllegalStateException(e); + } Module module; DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier); try { - BundleContext bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName()); + module = moduleFactory.createModule( moduleIdentifier.getInstanceName(), dependencyResolver, oldConfigBeanInfo.getReadableModule(), bc); @@ -187,7 +192,7 @@ class ConfigTransactionControllerImpl implements oldConfigBeanInfo, moduleFactory), e); } putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo, dependencyResolver, - oldConfigBeanInfo.isDefaultBean()); + oldConfigBeanInfo.isDefaultBean(), bc); } @Override @@ -200,19 +205,26 @@ class ConfigTransactionControllerImpl implements dependencyResolverManager.assertNotExists(moduleIdentifier); // find factory - ModuleFactory moduleFactory = factoriesHolder.findByModuleName(factoryName); + ModuleFactory moduleFactory; + try { + moduleFactory = factoriesHolder.findByModuleName(factoryName); + } catch (InstanceNotFoundException e) { + throw new IllegalArgumentException(e); + } DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier); + BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName()); Module module = moduleFactory.createModule(instanceName, dependencyResolver, - getModuleFactoryBundleContext(moduleFactory.getImplementationName())); + bundleContext); boolean defaultBean = false; return putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, - moduleFactory, null, dependencyResolver, defaultBean); + moduleFactory, null, dependencyResolver, defaultBean, bundleContext); } private synchronized ObjectName putConfigBeanToJMXAndInternalMaps( ModuleIdentifier moduleIdentifier, Module module, ModuleFactory moduleFactory, - @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver, boolean isDefaultBean) + @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver, + boolean isDefaultBean, BundleContext bundleContext) throws InstanceAlreadyExistsException { logger.debug("Adding module {} to transaction {}", moduleIdentifier, this); @@ -237,7 +249,7 @@ class ConfigTransactionControllerImpl implements dependencyResolverManager.put( moduleIdentifier, module, moduleFactory, - maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean); + maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean, bundleContext); return writableON; } @@ -263,14 +275,15 @@ class ConfigTransactionControllerImpl implements logger.debug("Destroying module {} in transaction {}", moduleIdentifier, this); transactionStatus.checkNotAborted(); + ModuleInternalTransactionalInfo found = dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier); if (blankTransaction == false) { - ModuleInternalTransactionalInfo found = - dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier); + if (found.isDefaultBean()) { logger.warn("Warning: removing default bean. This will be forbidden in next version of config-subsystem"); } } // first remove refNames, it checks for objectname existence + try { writableSRRegistry.removeServiceReferences( ObjectNameUtil.createTransactionModuleON(getTransactionName(), moduleIdentifier)); @@ -570,7 +583,7 @@ class ConfigTransactionControllerImpl implements } @Override - public ServiceReferenceWritableRegistry getWritableRegistry() { + public SearchableServiceReferenceWritableRegistry getWritableRegistry() { return writableSRRegistry; } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java index f6164e3256..c9df3409db 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerInternal.java @@ -7,17 +7,15 @@ */ package org.opendaylight.controller.config.manager.impl; -import java.util.Collection; -import java.util.List; - -import javax.management.ObjectName; - import org.opendaylight.controller.config.api.ModuleIdentifier; -import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry; import org.opendaylight.controller.config.api.ValidationException; import org.opendaylight.controller.config.spi.ModuleFactory; import org.osgi.framework.BundleContext; +import javax.management.ObjectName; +import java.util.Collection; +import java.util.List; + /** * Defines contract between {@link ConfigTransactionControllerImpl} (producer) * and {@link ConfigRegistryImpl} (consumer). @@ -73,7 +71,7 @@ interface ConfigTransactionControllerInternal extends BundleContext getModuleFactoryBundleContext(String factoryName); - ServiceReferenceWritableRegistry getWritableRegistry(); + SearchableServiceReferenceWritableRegistry getWritableRegistry(); TransactionIdentifier getTransactionIdentifier(); diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java index ba7ab7fcba..d34a739703 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/DeadlockMonitor.java @@ -6,6 +6,8 @@ import org.slf4j.LoggerFactory; import javax.annotation.Nullable; import javax.annotation.concurrent.GuardedBy; +import java.util.Deque; +import java.util.LinkedList; import java.util.concurrent.TimeUnit; public class DeadlockMonitor implements AutoCloseable { @@ -16,7 +18,9 @@ public class DeadlockMonitor implements AutoCloseable { private final TransactionIdentifier transactionIdentifier; private final DeadlockMonitorRunnable thread; @GuardedBy("this") - private ModuleIdentifierWithNanos moduleIdentifierWithNanos = new ModuleIdentifierWithNanos(); + private final Deque moduleIdentifierWithNanosStack = new LinkedList<>(); + @GuardedBy("this") + private ModuleIdentifierWithNanos top = ModuleIdentifierWithNanos.EMPTY; public DeadlockMonitor(TransactionIdentifier transactionIdentifier) { this.transactionIdentifier = transactionIdentifier; @@ -25,7 +29,21 @@ public class DeadlockMonitor implements AutoCloseable { } public synchronized void setCurrentlyInstantiatedModule(ModuleIdentifier currentlyInstantiatedModule) { - this.moduleIdentifierWithNanos = new ModuleIdentifierWithNanos(currentlyInstantiatedModule); + + boolean popping = currentlyInstantiatedModule == null; + if (popping) { + moduleIdentifierWithNanosStack.pop(); + if (moduleIdentifierWithNanosStack.isEmpty()) { + top = ModuleIdentifierWithNanos.EMPTY; + } else { + top = moduleIdentifierWithNanosStack.peekLast(); + } + } else { + ModuleIdentifierWithNanos current = new ModuleIdentifierWithNanos(currentlyInstantiatedModule); + moduleIdentifierWithNanosStack.push(current); + top = current; + } + logger.trace("setCurrentlyInstantiatedModule {}, top {}", currentlyInstantiatedModule, top); } public boolean isAlive() { @@ -52,11 +70,11 @@ public class DeadlockMonitor implements AutoCloseable { public void run() { ModuleIdentifierWithNanos old = new ModuleIdentifierWithNanos(); // null moduleId while (this.isInterrupted() == false) { - ModuleIdentifierWithNanos copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.moduleIdentifierWithNanos); - if (old.moduleIdentifier == null) { + ModuleIdentifierWithNanos copy = new ModuleIdentifierWithNanos(DeadlockMonitor.this.top); + if (old.moduleIdentifier == null || old.equals(copy) == false) { // started old = copy; - } else if (old.moduleIdentifier != null && old.equals(copy)) { + } else { // is the getInstance() running longer than WARN_AFTER_MILLIS ? long runningTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - copy.nanoTime); if (runningTime > WARN_AFTER_MILLIS) { @@ -78,14 +96,18 @@ public class DeadlockMonitor implements AutoCloseable { } } - private class ModuleIdentifierWithNanos { + + + + private static class ModuleIdentifierWithNanos { + private static ModuleIdentifierWithNanos EMPTY = new ModuleIdentifierWithNanos(); @Nullable private final ModuleIdentifier moduleIdentifier; + private final long nanoTime; private ModuleIdentifierWithNanos() { - moduleIdentifier = null; - nanoTime = System.nanoTime(); + this((ModuleIdentifier)null); } private ModuleIdentifierWithNanos(ModuleIdentifier moduleIdentifier) { @@ -118,5 +140,12 @@ public class DeadlockMonitor implements AutoCloseable { result = 31 * result + (int) (nanoTime ^ (nanoTime >>> 32)); return result; } + + @Override + public String toString() { + return "ModuleIdentifierWithNanos{" + + moduleIdentifier + + '}'; + } } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ModuleInternalInfo.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ModuleInternalInfo.java index fd6262cb8c..76299e67a2 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ModuleInternalInfo.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ModuleInternalInfo.java @@ -15,7 +15,9 @@ import org.opendaylight.controller.config.manager.impl.dynamicmbean.DynamicReada import org.opendaylight.controller.config.manager.impl.jmx.ModuleJMXRegistrator; import org.opendaylight.controller.config.manager.impl.jmx.RootRuntimeBeanRegistratorImpl; import org.opendaylight.controller.config.manager.impl.osgi.BeanToOsgiServiceManager.OsgiRegistration; +import org.opendaylight.controller.config.spi.ModuleFactory; import org.opendaylight.yangtools.concepts.Identifiable; +import org.osgi.framework.BundleContext; /** * Provides metadata about Module from controller to registry. @@ -37,13 +39,15 @@ public class ModuleInternalInfo implements Comparable, private final ModuleJMXRegistrator moduleJMXRegistrator; private final int orderingIdx; private final boolean isDefaultBean; + private final ModuleFactory moduleFactory; + private final BundleContext bundleContext; public ModuleInternalInfo(ModuleIdentifier name, @Nullable DynamicReadableWrapper readableModule, OsgiRegistration osgiRegistration, RootRuntimeBeanRegistratorImpl runtimeBeanRegistrator, ModuleJMXRegistrator moduleJMXRegistrator, int orderingIdx, - boolean isDefaultBean) { + boolean isDefaultBean, ModuleFactory moduleFactory, BundleContext bundleContext) { if (osgiRegistration == null) { throw new IllegalArgumentException( @@ -60,6 +64,8 @@ public class ModuleInternalInfo implements Comparable, this.moduleJMXRegistrator = moduleJMXRegistrator; this.orderingIdx = orderingIdx; this.isDefaultBean = isDefaultBean; + this.moduleFactory = moduleFactory; + this.bundleContext = bundleContext; } public DynamicReadableWrapper getReadableModule() { @@ -120,4 +126,12 @@ public class ModuleInternalInfo implements Comparable, public boolean isDefaultBean() { return isDefaultBean; } + + public ModuleFactory getModuleFactory() { + return moduleFactory; + } + + public BundleContext getBundleContext() { + return bundleContext; + } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/SearchableServiceReferenceWritableRegistry.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/SearchableServiceReferenceWritableRegistry.java new file mode 100644 index 0000000000..7a41a3bfa2 --- /dev/null +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/SearchableServiceReferenceWritableRegistry.java @@ -0,0 +1,26 @@ +/* + * 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; + +import java.util.Map; +import org.opendaylight.controller.config.api.ModuleIdentifier; +import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry; +import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation; + +public interface SearchableServiceReferenceWritableRegistry extends ServiceReferenceWritableRegistry { + /** + * Return mapping between service ref names and service interface annotation for given + * module. + * + * @throws java.lang.IllegalArgumentException if any of service qNames is not found + * @throws java.lang.NullPointerException if parameter is null + */ + Map findServiceInterfaces(ModuleIdentifier moduleIdentifier); + +} diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java index bf35fd1ed8..ceea994154 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java @@ -7,6 +7,17 @@ */ package org.opendaylight.controller.config.manager.impl; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; import org.opendaylight.controller.config.api.LookupRegistry; import org.opendaylight.controller.config.api.ModuleIdentifier; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; @@ -26,17 +37,7 @@ import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.InstanceAlreadyExistsException; -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, ServiceReferenceWritableRegistry { +public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceReadableRegistry, SearchableServiceReferenceWritableRegistry { private static final Logger logger = LoggerFactory.getLogger(ServiceReferenceRegistryImpl.class); private final Map factories; @@ -46,8 +47,11 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe private final ServiceReferenceRegistrator serviceReferenceRegistrator; // helper method for getting QName of SI from namespace + local name private final Map> namespacesToAnnotations; + private final Map serviceQNamesToAnnotations; // all Service Interface qNames for sanity checking private final Set allQNames; + Map> modulesToServiceRef = new HashMap<>(); + // actual reference database private final Map refNames = new HashMap<>(); @@ -124,7 +128,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe /** * Static constructor for transaction controller. Take current state as seen by config registry, allow writing new data. */ - public static ServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry, + public static SearchableServiceReferenceWritableRegistry createSRWritableRegistry(ServiceReferenceReadableRegistry oldReadableRegistry, ConfigTransactionLookupRegistry txLookupRegistry, Map> currentlyRegisteredFactories) { @@ -198,16 +202,15 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe Map> modifiableFactoryNamesToQNames = new HashMap<>(); Set allAnnotations = new HashSet<>(); Set allQNames = new HashSet<>(); + + for (Entry entry : factories.entrySet()) { if (entry.getKey().equals(entry.getValue().getImplementationName()) == false) { logger.error("Possible error in code: Mismatch between supplied and actual name of {}", entry); throw new IllegalArgumentException("Possible error in code: Mismatch between supplied and actual name of " + entry); } Set siAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(entry.getValue()); - Set qNames = new HashSet<>(); - for (ServiceInterfaceAnnotation sia: siAnnotations) { - qNames.add(sia.value()); - } + Set qNames = InterfacesHelper.getQNames(siAnnotations); allAnnotations.addAll(siAnnotations); allQNames.addAll(qNames); modifiableFactoryNamesToQNames.put(entry.getKey(), Collections.unmodifiableSet(qNames)); @@ -217,6 +220,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe // fill namespacesToAnnotations Map> modifiableNamespacesToAnnotations = new HashMap<>(); + Map modifiableServiceQNamesToAnnotations = new HashMap<>(); for (ServiceInterfaceAnnotation sia : allAnnotations) { Map ofNamespace = modifiableNamespacesToAnnotations.get(sia.namespace()); if (ofNamespace == null) { @@ -229,12 +233,21 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe throw new IllegalArgumentException("Conflict between local names in " + sia.namespace() + " : " + sia.localName()); } ofNamespace.put(sia.localName(), sia); + modifiableServiceQNamesToAnnotations.put(sia.value(), sia); } this.namespacesToAnnotations = Collections.unmodifiableMap(modifiableNamespacesToAnnotations); - // copy refNames + this.serviceQNamesToAnnotations = Collections.unmodifiableMap(modifiableServiceQNamesToAnnotations); logger.trace("factoryNamesToQNames:{}", this.factoryNamesToQNames); } + @Override + public Map findServiceInterfaces(ModuleIdentifier moduleIdentifier) { + Map result = modulesToServiceRef.get(moduleIdentifier); + if (result == null) { + return Collections.emptyMap(); + } + return Collections.unmodifiableMap(result); + } @Override public synchronized Set lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException { @@ -271,7 +284,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe public synchronized Map> getServiceMapping() { Map> result = new HashMap<>(); for (Entry entry: refNames.entrySet()) { - String qName = entry.getKey().getServiceInterfaceName(); + String qName = entry.getKey().getServiceInterfaceQName(); Map innerMap = result.get(qName); if (innerMap == null) { innerMap = new HashMap<>(); @@ -379,9 +392,9 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + moduleIdentifier.getFactoryName()); } // supplied serviceInterfaceName must exist in this collection - if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceName()) == false) { - logger.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames); - throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName() + " within factory " + moduleIdentifier.getFactoryName()); + if (serviceInterfaceQNames.contains(serviceReference.getServiceInterfaceQName()) == false) { + logger.error("Cannot find qName {} with factory name {}, found {}", serviceReference.getServiceInterfaceQName(), moduleIdentifier.getFactoryName(), serviceInterfaceQNames); + throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName() + " within factory " + moduleIdentifier.getFactoryName()); } @@ -404,6 +417,15 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe } // save to refNames refNames.put(serviceReference, moduleIdentifier); + Map refNamesToAnnotations = modulesToServiceRef.get(moduleIdentifier); + if (refNamesToAnnotations == null){ + refNamesToAnnotations = new HashMap<>(); + modulesToServiceRef.put(moduleIdentifier, refNamesToAnnotations); + } + + ServiceInterfaceAnnotation annotation = serviceQNamesToAnnotations.get(serviceReference.getServiceInterfaceQName()); + checkNotNull(annotation, "Possible error in code, cannot find annotation for " + serviceReference); + refNamesToAnnotations.put(serviceReference.getRefName(), annotation); return result; } @@ -430,9 +452,9 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe private ObjectName getServiceON(ServiceReference serviceReference) { if (writable) { return ObjectNameUtil.createTransactionServiceON(serviceReferenceRegistrator.getNullableTransactionName(), - serviceReference.getServiceInterfaceName(), serviceReference.getRefName()); + serviceReference.getServiceInterfaceQName(), serviceReference.getRefName()); } else { - return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceName(), serviceReference.getRefName()); + return ObjectNameUtil.createReadOnlyServiceON(serviceReference.getServiceInterfaceQName(), serviceReference.getRefName()); } } @@ -446,13 +468,13 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe logger.debug("Removing service reference {} from {}", serviceReference, this); assertWritable(); // is the qName known? - if (allQNames.contains(serviceReference.getServiceInterfaceName()) == false) { - logger.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceName(), allQNames); - throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceName()); + if (allQNames.contains(serviceReference.getServiceInterfaceQName()) == false) { + logger.error("Cannot find qname {} in {}", serviceReference.getServiceInterfaceQName(), allQNames); + throw new IllegalArgumentException("Cannot find service interface " + serviceReference.getServiceInterfaceQName()); } ModuleIdentifier removed = refNames.remove(serviceReference); if (removed == null){ - throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceName()); + throw new InstanceNotFoundException("Cannot find " + serviceReference.getServiceInterfaceQName()); } Entry entry = mBeans.remove(serviceReference); if (entry == null) { @@ -475,21 +497,28 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe @Override public synchronized boolean removeServiceReferences(ObjectName moduleObjectName) throws InstanceNotFoundException { + lookupRegistry.checkConfigBeanExists(moduleObjectName); + String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName); + // check that service interface name exist + Set serviceInterfaceQNames = factoryNamesToQNames.get(factoryName); + return removeServiceReferences(moduleObjectName, serviceInterfaceQNames); + } + + + private boolean removeServiceReferences(ObjectName moduleObjectName, Set qNames) throws InstanceNotFoundException { + ObjectNameUtil.checkType(moduleObjectName, ObjectNameUtil.TYPE_MODULE); assertWritable(); - Set serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName); + Set serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName, qNames); for (ServiceReference sr : serviceReferencesLinkingTo) { removeServiceReference(sr); } return serviceReferencesLinkingTo.isEmpty() == false; } - private synchronized Set findServiceReferencesLinkingTo(ObjectName moduleObjectName) throws InstanceNotFoundException { - lookupRegistry.checkConfigBeanExists(moduleObjectName); + private Set findServiceReferencesLinkingTo(ObjectName moduleObjectName, Set serviceInterfaceQNames) { String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName); - // check that service interface name exist - Set serviceInterfaceQNames = factoryNamesToQNames.get(factoryName); if (serviceInterfaceQNames == null) { - logger.error("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName); + logger.warn("Possible error in code: cannot find factoryName {} in {}, object name {}", factoryName, factoryNamesToQNames, moduleObjectName); throw new IllegalStateException("Possible error in code: cannot find annotations of existing factory " + factoryName); } String instanceName = ObjectNameUtil.getInstanceName(moduleObjectName); @@ -503,7 +532,6 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe return result; } - @Override public String toString() { return "ServiceReferenceRegistryImpl{" + diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java index b99bf8330e..0c1531728f 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManager.java @@ -7,8 +7,19 @@ */ package org.opendaylight.controller.config.manager.impl.dependencyresolver; +import static com.google.common.base.Preconditions.checkState; + import com.google.common.reflect.AbstractInvocationHandler; import com.google.common.reflect.Reflection; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.concurrent.GuardedBy; +import javax.management.InstanceAlreadyExistsException; import org.opendaylight.controller.config.api.DependencyResolver; import org.opendaylight.controller.config.api.DependencyResolverFactory; import org.opendaylight.controller.config.api.JmxAttribute; @@ -24,18 +35,7 @@ import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXR import org.opendaylight.controller.config.spi.Module; import org.opendaylight.controller.config.spi.ModuleFactory; import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry; - -import javax.annotation.concurrent.GuardedBy; -import javax.management.InstanceAlreadyExistsException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static com.google.common.base.Preconditions.checkState; +import org.osgi.framework.BundleContext; /** * Holds information about modules being created and destroyed within this @@ -117,7 +117,7 @@ public class DependencyResolverManager implements DependencyResolverFactory, Aut ModuleFactory moduleFactory, ModuleInternalInfo maybeOldInternalInfo, TransactionModuleJMXRegistration transactionModuleJMXRegistration, - boolean isDefaultBean) { + boolean isDefaultBean, BundleContext bundleContext) { transactionStatus.checkNotCommitted(); Class moduleClass = Module.class; @@ -159,7 +159,7 @@ public class DependencyResolverManager implements DependencyResolverFactory, Aut ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo( moduleIdentifier, proxiedModule, moduleFactory, - maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module); + maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module, bundleContext); modulesHolder.put(moduleInternalTransactionalInfo); } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/ModuleInternalTransactionalInfo.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/ModuleInternalTransactionalInfo.java index e9f573a05d..13424a60eb 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/ModuleInternalTransactionalInfo.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/ModuleInternalTransactionalInfo.java @@ -16,6 +16,7 @@ import org.opendaylight.controller.config.spi.ModuleFactory; import org.opendaylight.yangtools.concepts.Identifiable; import javax.annotation.Nullable; +import org.osgi.framework.BundleContext; public class ModuleInternalTransactionalInfo implements Identifiable { private final ModuleIdentifier name; @@ -25,12 +26,13 @@ public class ModuleInternalTransactionalInfo implements Identifiable result = moduleNamesToConfigBeanFactories.get(moduleName); if (result == null) { - throw new IllegalArgumentException( + throw new InstanceNotFoundException( "ModuleFactory not found with module name: " + moduleName); } return result.getKey(); @@ -73,7 +72,4 @@ public class HierarchicalConfigMBeanFactoriesHolder { return moduleFactories; } - public Map> getModuleNamesToConfigBeanFactories() { - return moduleNamesToConfigBeanFactories; - } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java index cd74ddf756..3ad35ac5b5 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/jmx/ServiceReference.java @@ -15,7 +15,7 @@ public class ServiceReference { this.refName = refName; } - public String getServiceInterfaceName() { + public String getServiceInterfaceQName() { return serviceInterfaceName; } @@ -50,4 +50,12 @@ public class ServiceReference { result = 31 * result + refName.hashCode(); return result; } + + @Override + public String toString() { + return "ServiceReference{" + + "serviceInterfaceName='" + serviceInterfaceName + '\'' + + ", refName='" + refName + '\'' + + '}'; + } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BeanToOsgiServiceManager.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BeanToOsgiServiceManager.java index 41f577844a..fbc7eb6cbe 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BeanToOsgiServiceManager.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BeanToOsgiServiceManager.java @@ -7,109 +7,108 @@ */ package org.opendaylight.controller.config.manager.impl.osgi; -import org.opendaylight.controller.config.api.ModuleIdentifier; -import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation; -import org.opendaylight.controller.config.manager.impl.util.InterfacesHelper; -import org.opendaylight.controller.config.spi.Module; -import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceRegistration; +import static com.google.common.base.Preconditions.checkState; import java.util.Dictionary; import java.util.HashSet; import java.util.Hashtable; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; +import javax.annotation.concurrent.GuardedBy; +import org.opendaylight.controller.config.api.ModuleIdentifier; +import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Registers instantiated beans as OSGi services and unregisters these services * if beans are destroyed. */ public class BeanToOsgiServiceManager { - // name of properties submitted to osgi - static final String INSTANCE_NAME_OSGI_PROP = "instanceName"; - static final String IMPLEMENTATION_NAME_OSGI_PROP = "implementationName"; + private static final String SERVICE_NAME_OSGI_PROP = "name"; /** * To be called for every created, reconfigured and recreated config bean. * It is expected that before using this method OSGi service registry will * be cleaned from previous registrations. */ - public OsgiRegistration registerToOsgi( - Class configBeanClass, AutoCloseable instance, - ModuleIdentifier moduleIdentifier, BundleContext bundleContext) { - try { - final Set> configuresInterfaces = InterfacesHelper - .getOsgiRegistrationTypes(configBeanClass); - checkInstanceImplementing(instance, configuresInterfaces); - - // bundleContext.registerService blows up with empty 'clazzes' - if (configuresInterfaces.isEmpty() == false) { - final Dictionary propertiesForOsgi = getPropertiesForOsgi(moduleIdentifier); - final ServiceRegistration serviceRegistration = bundleContext - .registerService(classesToNames(configuresInterfaces), instance, propertiesForOsgi); - return new OsgiRegistration(serviceRegistration); - } else { - return new OsgiRegistration(); - } - } catch (IllegalStateException e) { - throw new IllegalStateException( - "Error while registering instance into OSGi Service Registry: " - + moduleIdentifier, e); - } + public OsgiRegistration registerToOsgi(AutoCloseable instance, ModuleIdentifier moduleIdentifier, + BundleContext bundleContext, + Map serviceNamesToAnnotations) { + return new OsgiRegistration(instance, moduleIdentifier, bundleContext, serviceNamesToAnnotations); } - private static String[] classesToNames(Set> cfgs) { - String[] result = new String[cfgs.size()]; - int i = 0; - for (Class cfg : cfgs) { - result[i] = cfg.getName(); - i++; - } + private static Dictionary createProps(String serviceName) { + Hashtable result = new Hashtable<>(); + result.put(SERVICE_NAME_OSGI_PROP, serviceName); return result; } - private void checkInstanceImplementing(AutoCloseable instance, - Set> configures) { - Set> missing = new HashSet<>(); - for (Class requiredIfc : configures) { - if (requiredIfc.isInstance(instance) == false) { - missing.add(requiredIfc); - } - } - if (missing.isEmpty() == false) { - throw new IllegalStateException( - instance.getClass() - + " does not implement following interfaces as announced by " - + ServiceInterfaceAnnotation.class.getName() - + " annotation :" + missing); - } - } - - private static Dictionary getPropertiesForOsgi( - ModuleIdentifier moduleIdentifier) { - Hashtable table = new Hashtable<>(); - table.put(IMPLEMENTATION_NAME_OSGI_PROP, - moduleIdentifier.getFactoryName()); - table.put(INSTANCE_NAME_OSGI_PROP, moduleIdentifier.getInstanceName()); - return table; - } public static class OsgiRegistration implements AutoCloseable { - private final ServiceRegistration serviceRegistration; + private static final Logger logger = LoggerFactory.getLogger(OsgiRegistration.class); - public OsgiRegistration(ServiceRegistration serviceRegistration) { - this.serviceRegistration = serviceRegistration; + @GuardedBy("this") + private AutoCloseable instance; + private final ModuleIdentifier moduleIdentifier; + @GuardedBy("this") + private final Set> serviceRegistrations; + @GuardedBy("this") + private final Map serviceNamesToAnnotations; + + public OsgiRegistration(AutoCloseable instance, ModuleIdentifier moduleIdentifier, + BundleContext bundleContext, + Map serviceNamesToAnnotations) { + this.instance = instance; + this.moduleIdentifier = moduleIdentifier; + this.serviceNamesToAnnotations = serviceNamesToAnnotations; + this.serviceRegistrations = registerToSR(instance, bundleContext, serviceNamesToAnnotations); } - public OsgiRegistration() { - this.serviceRegistration = null; + private static Set> registerToSR(AutoCloseable instance, BundleContext bundleContext, + Map serviceNamesToAnnotations) { + Set> serviceRegistrations = new HashSet<>(); + for (Entry entry : serviceNamesToAnnotations.entrySet()) { + Class requiredInterface = entry.getValue().osgiRegistrationType(); + checkState(requiredInterface.isInstance(instance), instance.getClass().getName() + + " instance should implement " + requiredInterface.getName()); + Dictionary propertiesForOsgi = createProps(entry.getKey()); + ServiceRegistration serviceRegistration = bundleContext + .registerService(requiredInterface.getName(), instance, propertiesForOsgi); + serviceRegistrations.add(serviceRegistration); + } + return serviceRegistrations; } @Override - public void close() { - if (serviceRegistration != null) { - serviceRegistration.unregister(); + public synchronized void close() { + for (ServiceRegistration serviceRegistration : serviceRegistrations) { + try { + serviceRegistration.unregister(); + } catch(IllegalStateException e) { + logger.trace("Cannot unregister {}", serviceRegistration, e); + } } + serviceRegistrations.clear(); } - } + public synchronized void updateRegistrations(Map newAnnotationMapping, + BundleContext bundleContext, AutoCloseable newInstance) { + boolean notEquals = this.instance != newInstance; + notEquals |= newAnnotationMapping.equals(serviceNamesToAnnotations) == false; + if (notEquals) { + // FIXME: changing from old state to new state can be improved by computing the diff + logger.debug("Detected change in service registrations for {}: old: {}, new: {}", moduleIdentifier, + serviceNamesToAnnotations, newAnnotationMapping); + close(); + this.instance = newInstance; + Set> newRegs = registerToSR(instance, bundleContext, newAnnotationMapping); + serviceRegistrations.clear(); + serviceRegistrations.addAll(newRegs); + } + } + } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelper.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelper.java index 033f7222fc..a6e9b1ba96 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelper.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelper.java @@ -120,6 +120,13 @@ public class InterfacesHelper { return result; } + public static Set getQNames(Set siAnnotations) { + Set qNames = new HashSet<>(); + for (ServiceInterfaceAnnotation sia: siAnnotations) { + qNames.add(sia.value()); + } + return Collections.unmodifiableSet(qNames); + } public static Set getServiceInterfaceAnnotations(ModuleFactory factory) { Set> implementedServiceIntefaces = Collections.unmodifiableSet(factory.getImplementedServiceIntefaces()); @@ -136,7 +143,7 @@ public class InterfacesHelper { result.add(annotation); } } - return result; + return Collections.unmodifiableSet(result); } static Set> getAllAbstractServiceInterfaceClasses( diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/ConfigRegistryImplTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/ConfigRegistryImplTest.java index 9178dc40d0..7efd3ee030 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/ConfigRegistryImplTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/ConfigRegistryImplTest.java @@ -7,13 +7,6 @@ */ package org.opendaylight.controller.config.manager; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verifyZeroInteractions; - -import java.lang.management.ManagementFactory; - import org.junit.Test; import org.opendaylight.controller.config.manager.impl.AbstractLockedPlatformMBeanServerTest; import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl; @@ -25,6 +18,13 @@ import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.management.ManagementFactory; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyZeroInteractions; + public class ConfigRegistryImplTest extends AbstractLockedPlatformMBeanServerTest { private static final Logger logger = LoggerFactory @@ -36,7 +36,7 @@ public class ConfigRegistryImplTest extends BundleContext context = mock(BundleContext.class); ConfigRegistryImpl configRegistry = null; try { - ModuleFactoriesResolver resolver = new HardcodedModuleFactoriesResolver( + ModuleFactoriesResolver resolver = new HardcodedModuleFactoriesResolver(mock(BundleContext.class), factory, factory); configRegistry = new ConfigRegistryImpl(resolver, diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java index 001af7525b..63a37de0c3 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/AbstractConfigTest.java @@ -8,9 +8,11 @@ package org.opendaylight.controller.config.manager.impl; import com.google.common.base.Preconditions; -import junit.framework.Assert; import org.junit.After; +import org.junit.Before; import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.opendaylight.controller.config.api.jmx.CommitStatus; @@ -26,24 +28,18 @@ import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.RuntimeMBeanException; -import java.io.Closeable; -import java.io.InputStream; import java.lang.management.ManagementFactory; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Dictionary; +import java.util.LinkedList; import java.util.List; import java.util.Set; @@ -69,29 +65,58 @@ public abstract class AbstractConfigTest extends protected ConfigRegistryJMXClient configRegistryClient; protected BaseJMXRegistrator baseJmxRegistrator; protected InternalJMXRegistrator internalJmxRegistrator; - protected BundleContext mockedContext = mock(BundleContext.class); + @Mock + protected BundleContext mockedContext; + @Mock protected ServiceRegistration mockedServiceRegistration; - private static final Logger logger = LoggerFactory.getLogger(AbstractConfigTest.class); + @Before + public void setUpMocks() { + MockitoAnnotations.initMocks(this); + } + // Default handler for OSGi service registration - private static final BundleContextServiceRegistrationHandler noopServiceRegHandler = new BundleContextServiceRegistrationHandler() { + protected static class RecordingBundleContextServiceRegistrationHandler implements BundleContextServiceRegistrationHandler { + private final List registrations = new LinkedList<>(); @Override - public void handleServiceRegistration(Object serviceInstance) {} - }; + public void handleServiceRegistration(Class clazz, Object serviceInstance, Dictionary props) { + + registrations.add(new RegistrationHolder(clazz, serviceInstance, props)); + } + + public List getRegistrations() { + return registrations; + } + + protected static class RegistrationHolder { + protected final Class clazz; + protected final Object instance; + protected final Dictionary props; + + public RegistrationHolder(Class clazz, Object instance, Dictionary props) { + this.clazz = clazz; + this.instance = instance; + this.props = props; + } + } + + } + + protected BundleContextServiceRegistrationHandler currentBundleContextServiceRegistrationHandler; protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(Class serviceType) { - return noopServiceRegHandler; + return currentBundleContextServiceRegistrationHandler; } // this method should be called in @Before protected void initConfigTransactionManagerImpl( ModuleFactoriesResolver resolver) { + final MBeanServer platformMBeanServer = ManagementFactory .getPlatformMBeanServer(); - configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator( - platformMBeanServer); + configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(platformMBeanServer); initBundleContext(); internalJmxRegistrator = new InternalJMXRegistrator(platformMBeanServer); @@ -106,35 +131,14 @@ public abstract class AbstractConfigTest extends throw new RuntimeException(e); } configRegistryClient = new ConfigRegistryJMXClient(platformMBeanServer); + currentBundleContextServiceRegistrationHandler = new RecordingBundleContextServiceRegistrationHandler(); } private void initBundleContext() { - this.mockedServiceRegistration = mock(ServiceRegistration.class); doNothing().when(mockedServiceRegistration).unregister(); - RegisterServiceAnswer answer = new RegisterServiceAnswer(); - - doAnswer(answer).when(mockedContext).registerService(Matchers.any(String[].class), - any(Closeable.class), Matchers.>any()); - doAnswer(answer).when(mockedContext).registerService(Matchers.>any(), any(Closeable.class), - Matchers.>any()); - } - - - public Collection getFilesAsInputStreams(List paths) { - final Collection resources = new ArrayList<>(); - List failedToFind = new ArrayList<>(); - for (String path : paths) { - InputStream resourceAsStream = getClass().getResourceAsStream(path); - if (resourceAsStream == null) { - failedToFind.add(path); - } else { - resources.add(resourceAsStream); - } - } - Assert.assertEquals("Some files were not found", Collections.emptyList(), failedToFind); - - return resources; + doAnswer(answer).when(mockedContext).registerService(Matchers.any(), any(), Matchers.>any()); + doAnswer(answer).when(mockedContext).registerService(Matchers.any(), any(), Matchers.>any()); } @After @@ -161,13 +165,6 @@ public abstract class AbstractConfigTest extends transaction.commit(); } - protected void assertSame(ObjectName oN1, ObjectName oN2) { - assertEquals(oN1.getKeyProperty("instanceName"), - oN2.getKeyProperty("instanceName")); - assertEquals(oN1.getKeyProperty("interfaceName"), - oN2.getKeyProperty("interfaceName")); - } - protected void assertStatus(CommitStatus status, int expectedNewInstances, int expectedRecreatedInstances, int expectedReusedInstances) { assertEquals("New instances mismatch in " + status, expectedNewInstances, status.getNewInstances().size()); @@ -177,25 +174,12 @@ public abstract class AbstractConfigTest extends .size()); } - protected ObjectName createTestConfigBean( - ConfigTransactionJMXClient transaction, String implementationName, - String name) throws InstanceAlreadyExistsException { - return transaction.createModule(implementationName, - name); - } protected void assertBeanCount(int i, String configMXBeanName) { assertEquals(i, configRegistry.lookupConfigBeans(configMXBeanName) .size()); } - protected void assertBeanExists(int count, String moduleName, - String instanceName) { - assertEquals(1, - configRegistry.lookupConfigBeans(moduleName, instanceName) - .size()); - } - /** * * @param configBeanClass @@ -215,7 +199,7 @@ public abstract class AbstractConfigTest extends public static interface BundleContextServiceRegistrationHandler { - void handleServiceRegistration(Object serviceInstance); + void handleServiceRegistration(Class clazz, Object serviceInstance, Dictionary props); } @@ -229,32 +213,40 @@ public abstract class AbstractConfigTest extends Object serviceTypeRaw = args[0]; Object serviceInstance = args[1]; + Dictionary props = (Dictionary) args[2]; if (serviceTypeRaw instanceof Class) { Class serviceType = (Class) serviceTypeRaw; - invokeServiceHandler(serviceInstance, serviceType); + invokeServiceHandler(serviceInstance, serviceType, props); } else if(serviceTypeRaw instanceof String[]) { for (String className : (String[]) serviceTypeRaw) { - try { - Class serviceType = Class.forName(className); - invokeServiceHandler(serviceInstance, serviceType); - } catch (ClassNotFoundException e) { - logger.warn("Not handling service registration of type {} ", className, e); - } + invokeServiceHandler(serviceInstance, className, props); } + } else if (serviceTypeRaw instanceof String) { + invokeServiceHandler(serviceInstance, (String) serviceTypeRaw, props); + } else { + throw new IllegalStateException("Not handling service registration of type, Unknown type" + serviceTypeRaw); + } - } else - logger.debug("Not handling service registration of type {}, Unknown type", serviceTypeRaw); return mockedServiceRegistration; } - private void invokeServiceHandler(Object serviceInstance, Class serviceType) { + public void invokeServiceHandler(Object serviceInstance, String className, Dictionary props) { + try { + Class serviceType = Class.forName(className); + invokeServiceHandler(serviceInstance, serviceType, props); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Not handling service registration of type " + className, e); + } + } + + private void invokeServiceHandler(Object serviceInstance, Class serviceType, Dictionary props) { BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandler(serviceType); if (serviceRegistrationHandler != null) { - serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance)); + serviceRegistrationHandler.handleServiceRegistration(serviceType, serviceInstance, props); } } } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java index 09aea0895f..5a3747ee14 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImplTest.java @@ -11,7 +11,6 @@ import com.google.common.collect.Sets; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.opendaylight.controller.config.api.ServiceReferenceWritableRegistry; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.manager.impl.jmx.BaseJMXRegistrator; import org.opendaylight.controller.config.manager.impl.jmx.TransactionJMXRegistrator; @@ -70,7 +69,7 @@ public class ConfigTransactionControllerImplTest extends } }, currentlyRegisteredFactories); - ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry( + SearchableServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry( ServiceReferenceRegistryImpl.createInitialSRLookupRegistry(), txLookupRegistry, currentlyRegisteredFactories); diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionManagerImplTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionManagerImplTest.java index bbb3784b33..9595e60ff6 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionManagerImplTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionManagerImplTest.java @@ -23,7 +23,7 @@ public class ConfigTransactionManagerImplTest extends @Before public void setUp() { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver()); + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext)); } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImplTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImplTest.java index 6d0b340cd3..3e7b65e1bd 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImplTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImplTest.java @@ -11,6 +11,7 @@ import com.google.common.collect.ImmutableMap; import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.config.manager.impl.AbstractConfigTest.RecordingBundleContextServiceRegistrationHandler.RegistrationHolder; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; import org.opendaylight.controller.config.manager.impl.jmx.ServiceReferenceMXBean; import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory; @@ -18,6 +19,7 @@ import org.opendaylight.controller.config.manager.testingservices.parallelapsp.t import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolModuleFactory; import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingThreadPoolServiceInterface; import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory; +import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingThreadPoolIfc; import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; import javax.management.Attribute; @@ -27,7 +29,7 @@ import javax.management.JMX; import javax.management.MBeanException; import javax.management.ObjectName; import javax.management.ReflectionException; - +import java.util.List; import java.util.Map; import java.util.Set; @@ -41,6 +43,7 @@ public class ServiceReferenceRegistryImplTest extends AbstractParallelAPSPTest { @Before public void setUp() { super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver( + mockedContext, new TestingFixedThreadPoolModuleFactory(), new TestingParallelAPSPModuleFactory(), new TestingScheduledThreadPoolModuleFactory())); @@ -71,11 +74,19 @@ public class ServiceReferenceRegistryImplTest extends AbstractParallelAPSPTest { // create apsp-parallel createParallelAPSP(transaction1, serviceReference); transaction1.commit(); + // check fixed1 is used ServiceReferenceMXBean serviceReferenceMXBean = JMX.newMXBeanProxy(platformMBeanServer, withoutTransactionName(serviceReference), ServiceReferenceMXBean.class); assertEquals(withoutTransactionName(fixedTPTransactionON), serviceReferenceMXBean.getCurrentImplementation()); checkApspThreadCount(fixedNrOfThreads); + // check OSGi SR + List registrations = + ((RecordingBundleContextServiceRegistrationHandler) currentBundleContextServiceRegistrationHandler).getRegistrations(); + assertEquals(1, registrations.size()); + RegistrationHolder record = registrations.get(0); + assertEquals(TestingThreadPoolIfc.class, record.clazz); + assertEquals(ImmutableMap.of("name","ref"), (Map) record.props); // switch reference to scheduled ConfigTransactionJMXClient transaction2 = configRegistryClient.createTransaction(); diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java index 123e52f675..d5d3823ef0 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/dependencyresolver/DependencyResolverManagerTest.java @@ -7,6 +7,14 @@ */ package org.opendaylight.controller.config.manager.impl.dependencyresolver; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; + +import java.util.Arrays; +import java.util.List; import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.api.JmxAttribute; @@ -19,15 +27,7 @@ import org.opendaylight.controller.config.manager.impl.TransactionStatus; import org.opendaylight.controller.config.manager.impl.jmx.TransactionModuleJMXRegistrator.TransactionModuleJMXRegistration; import org.opendaylight.controller.config.spi.Module; import org.opendaylight.controller.config.spi.ModuleFactory; - -import java.util.Arrays; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; +import org.osgi.framework.BundleContext; public class DependencyResolverManagerTest { @@ -101,7 +101,7 @@ public class DependencyResolverManagerTest { moduleFactory, maybeOldInternalInfo, transactionModuleJMXRegistration, - isDefaultBean); + isDefaultBean, mock(BundleContext.class)); } private static Module mockedModule() { diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/factoriesresolver/HardcodedModuleFactoriesResolver.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/factoriesresolver/HardcodedModuleFactoriesResolver.java index 3c2230735e..dd6588f3f6 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/factoriesresolver/HardcodedModuleFactoriesResolver.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/factoriesresolver/HardcodedModuleFactoriesResolver.java @@ -60,10 +60,6 @@ public class HardcodedModuleFactoriesResolver implements ModuleFactoriesResolver } } - public HardcodedModuleFactoriesResolver(ModuleFactory... list) { - this(mockBundleContext(),list); - } - private static BundleContext mockBundleContext() { BundleContext bundleContext = Mockito.mock(BundleContext.class); ServiceRegistration serviceRegistration = mock(ServiceRegistration.class); diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java index 978d375cd2..f42b9559c4 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/DependentWiringTest.java @@ -37,7 +37,7 @@ public class DependentWiringTest extends AbstractParallelAPSPTest { @Before public void setUp() { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, new TestingFixedThreadPoolModuleFactory(), new TestingParallelAPSPModuleFactory())); } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/MockedDependenciesTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/MockedDependenciesTest.java index 642f526efd..0d4fc91a51 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/MockedDependenciesTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/parallelapsp/test/MockedDependenciesTest.java @@ -7,12 +7,6 @@ */ package org.opendaylight.controller.config.manager.testingservices.parallelapsp.test; -import java.io.Closeable; -import java.io.IOException; -import java.util.concurrent.Executor; - -import javax.management.ObjectName; - import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.api.DynamicMBeanWithInstance; @@ -27,6 +21,11 @@ import org.opendaylight.controller.config.manager.testingservices.threadpool.Tes import org.opendaylight.controller.config.spi.Module; import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; +import javax.management.ObjectName; +import java.io.Closeable; +import java.io.IOException; +import java.util.concurrent.Executor; + public class MockedDependenciesTest extends AbstractParallelAPSPTest { private final String threadPoolImplementationName = "mockedthreadpool"; @@ -36,7 +35,7 @@ public class MockedDependenciesTest extends AbstractParallelAPSPTest { ClassBasedModuleFactory mockedThreadPoolConfigFactory = new ClassBasedModuleFactory( threadPoolImplementationName, MockedThreadPoolModule.class); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, new TestingParallelAPSPModuleFactory(), mockedThreadPoolConfigFactory)); } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/test/AbstractScheduledTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/test/AbstractScheduledTest.java index 28fea454fe..340e194801 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/test/AbstractScheduledTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/scheduledthreadpool/test/AbstractScheduledTest.java @@ -7,18 +7,17 @@ */ package org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.test; -import static org.junit.Assert.assertEquals; - import org.junit.After; import org.junit.Before; import org.opendaylight.controller.config.manager.impl.AbstractConfigTest; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; import org.opendaylight.controller.config.manager.testingservices.parallelapsp.TestingParallelAPSPModuleFactory; import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolImpl; -import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool - .TestingScheduledThreadPoolModuleFactory; +import org.opendaylight.controller.config.manager.testingservices.scheduledthreadpool.TestingScheduledThreadPoolModuleFactory; import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory; +import static org.junit.Assert.assertEquals; + public abstract class AbstractScheduledTest extends AbstractConfigTest { protected static final String scheduled1 = "scheduled1"; @@ -26,7 +25,7 @@ public abstract class AbstractScheduledTest extends AbstractConfigTest { public final void setUp() { assertEquals(0, TestingScheduledThreadPoolImpl.getNumberOfCloseMethodCalls()); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, new TestingScheduledThreadPoolModuleFactory(), new TestingFixedThreadPoolModuleFactory(), new TestingParallelAPSPModuleFactory())); diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPool.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPool.java index d5434d2ed5..25125fcd82 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPool.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/TestingFixedThreadPool.java @@ -53,6 +53,7 @@ public class TestingFixedThreadPool implements TestingThreadPoolIfc, Closeable, @Override public void close() throws IOException { executorService.shutdown(); + allExecutors.remove(executorService); } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/ShutdownTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/ShutdownTest.java new file mode 100644 index 0000000000..e047a1ecca --- /dev/null +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/ShutdownTest.java @@ -0,0 +1,63 @@ +/* + * 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.manager.testingservices.threadpool.test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doReturn; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import java.util.Collections; +import java.util.Map; +import java.util.Map.Entry; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.controller.config.manager.impl.AbstractConfigTest; +import org.opendaylight.controller.config.manager.impl.factoriesresolver.ModuleFactoriesResolver; +import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPool; +import org.opendaylight.controller.config.manager.testingservices.threadpool.TestingFixedThreadPoolModuleFactory; +import org.opendaylight.controller.config.spi.ModuleFactory; +import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; +import org.osgi.framework.BundleContext; + +public class ShutdownTest extends AbstractConfigTest { + private final TestingFixedThreadPoolModuleFactory testingFixedThreadPoolModuleFactory = new TestingFixedThreadPoolModuleFactory(); + + @Mock + ModuleFactoriesResolver mockedResolver; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + Map> allFactories = ImmutableMap.of( + testingFixedThreadPoolModuleFactory.getImplementationName(), + Maps.immutableEntry(testingFixedThreadPoolModuleFactory, mockedContext)); + doReturn(allFactories).when(mockedResolver).getAllFactories(); + super.initConfigTransactionManagerImpl(mockedResolver); + } + + + @Test + public void testCreateAndDestroyBeanInSameTransaction() throws Exception { + { + ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); + SimpleConfigurationTest.createFixedThreadPool(transaction); + transaction.commit(); + } + assertEquals(1, TestingFixedThreadPool.allExecutors.size()); + doReturn(Collections.emptyMap()).when(mockedResolver).getAllFactories(); + { + ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); + transaction.commit(); + } + assertEquals(1, TestingFixedThreadPool.allExecutors.size()); + } +} diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java index 9852a45853..97d1c63ed2 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java @@ -56,7 +56,7 @@ import static org.junit.Assert.fail; * dependencies. */ public class SimpleConfigurationTest extends AbstractConfigTest { - private final int numberOfThreads = 5; + private static final int numberOfThreads = 5; private final int numberOfThreads2 = 10; private static final String fixed1 = "fixed1"; private static final List emptyONs = Collections @@ -68,7 +68,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest { @Before public void setUp() { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, new TestingFixedThreadPoolModuleFactory())); } @@ -96,7 +96,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest { return fixed1names; } - private ObjectName createFixedThreadPool( + static ObjectName createFixedThreadPool( ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException, InstanceNotFoundException { transaction.assertVersion(0, 1); @@ -246,8 +246,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest { // 4, check assertEquals(2, configRegistryClient.getVersion()); - assertEquals(1, TestingFixedThreadPool.allExecutors.size()); - assertTrue(TestingFixedThreadPool.allExecutors.get(0).isShutdown()); + assertEquals(0, TestingFixedThreadPool.allExecutors.size()); // dynamic config should be removed from platform try { @@ -278,7 +277,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest { // commit transaction.commit(); // check that first threadpool is closed - checkThreadPools(2, numberOfThreads2); + checkThreadPools(1, numberOfThreads2); } private void checkThreadPools(int expectedTotalNumberOfExecutors, @@ -308,7 +307,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest { // commit CommitStatus commitStatus = transaction.commit(); // check that new threadpool is created and old one is closed - checkThreadPools(2, numberOfThreads); + checkThreadPools(1, numberOfThreads); CommitStatus expected = new CommitStatus(emptyONs, emptyONs, fixed1List); assertEquals(expected, commitStatus); } @@ -337,6 +336,7 @@ public class SimpleConfigurationTest extends AbstractConfigTest { platformMBeanServer.getMBeanInfo(transaction.getObjectName()); fail(); }catch(InstanceNotFoundException e){ + assertEquals("org.opendaylight.controller:TransactionName=ConfigTransaction-0-1,type=ConfigTransaction", e.getMessage()); } } diff --git a/opendaylight/config/config-persister-api/src/main/java/org/opendaylight/controller/config/persist/api/PropertiesProvider.java b/opendaylight/config/config-persister-api/src/main/java/org/opendaylight/controller/config/persist/api/PropertiesProvider.java index 1d4139f885..156fa580ce 100644 --- a/opendaylight/config/config-persister-api/src/main/java/org/opendaylight/controller/config/persist/api/PropertiesProvider.java +++ b/opendaylight/config/config-persister-api/src/main/java/org/opendaylight/controller/config/persist/api/PropertiesProvider.java @@ -18,4 +18,7 @@ public interface PropertiesProvider { * @return prefix + key as used in getProperty method. */ String getFullKeyForReporting(String key); + + String getPrefix(); + String getPropertyWithoutPrefix(String fullKey); } diff --git a/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java b/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java index 2df07b114c..3d4757b926 100644 --- a/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java +++ b/opendaylight/config/config-persister-api/src/test/java/org/opendaylight/controller/config/persist/test/PropertiesProviderTest.java @@ -26,4 +26,14 @@ public class PropertiesProviderTest implements PropertiesProvider { public String getFullKeyForReporting(String key) { return null; } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getPropertyWithoutPrefix(String fullKey) { + return null; + } } diff --git a/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java b/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java index 296ce79f6e..d9c9dada62 100644 --- a/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java +++ b/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java @@ -35,7 +35,7 @@ public class LogbackModuleTest extends AbstractConfigTest { public void setUp() throws Exception { factory = new LogbackModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory)); + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory)); } @Test diff --git a/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleWithInitialConfigurationTest.java b/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleWithInitialConfigurationTest.java index e543f752e1..37bfb6d957 100644 --- a/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleWithInitialConfigurationTest.java +++ b/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleWithInitialConfigurationTest.java @@ -49,7 +49,7 @@ public class LogbackModuleWithInitialConfigurationTest extends AbstractConfigTes public void setUp() throws IOException, ClassNotFoundException { factory = new LogbackModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory)); + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory)); } /** diff --git a/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackWithXmlConfigModuleTest.java b/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackWithXmlConfigModuleTest.java index 8149659812..3c21e57f6e 100644 --- a/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackWithXmlConfigModuleTest.java +++ b/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackWithXmlConfigModuleTest.java @@ -42,7 +42,7 @@ public class LogbackWithXmlConfigModuleTest extends AbstractConfigTest { public void setUp() throws JoranException, IOException { factory = new LogbackModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory)); + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory)); lc = (LoggerContext) LoggerFactory.getILoggerFactory(); JoranConfigurator configurator = new JoranConfigurator(); 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 f29895c6d0..e89d82a28f 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 @@ -31,7 +31,7 @@ public class GlobalEventExecutorModuleTest extends AbstractConfigTest { @Before public void setUp() { factory = new GlobalEventExecutorModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory)); + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory)); } @Test diff --git a/opendaylight/config/netty-threadgroup-config/src/test/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleTest.java b/opendaylight/config/netty-threadgroup-config/src/test/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleTest.java index 590bd9185e..76134b025c 100644 --- a/opendaylight/config/netty-threadgroup-config/src/test/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleTest.java +++ b/opendaylight/config/netty-threadgroup-config/src/test/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleTest.java @@ -28,7 +28,7 @@ public class NettyThreadgroupModuleTest extends AbstractConfigTest { @Before public void setUp() { factory = new NettyThreadgroupModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory)); + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory)); } @Test 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 f9622192fe..4abbd3b36f 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,7 +82,6 @@ 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) { @@ -95,13 +94,6 @@ 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) { @@ -110,16 +102,6 @@ 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 d4a3160b89..358586f634 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 @@ -7,6 +7,17 @@ */ package org.opendaylight.controller.config.yang.shutdown.impl; +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.verify; +import static org.opendaylight.controller.config.yang.shutdown.impl.ShutdownModuleFactory.NAME; + +import java.util.Collections; +import javax.management.InstanceNotFoundException; +import javax.management.JMX; +import javax.management.ObjectName; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -20,22 +31,10 @@ 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; - -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.verify; -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, mockedConfigManager; + private Bundle mockedSysBundle; @Before @@ -46,11 +45,10 @@ 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(new Bundle[]{mockedSysBundle}).when(mockedContext).getBundles(); doReturn("system bundle").when(mockedSysBundle).getSymbolicName(); - doReturn(StopSystemBundleThread.CONFIG_MANAGER_SYMBOLIC_NAME).when(mockedConfigManager).getSymbolicName(); + ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction(); @@ -129,7 +127,6 @@ public class ShutdownTest extends AbstractConfigTest { private void assertStopped() throws Exception { Thread.sleep(3000); // happens on another thread - verify(mockedConfigManager).stop(); verify(mockedSysBundle).stop(); } } diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/async/AsyncEventBusConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/async/AsyncEventBusConfigBeanTest.java index 177adc1588..0b339fc600 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/async/AsyncEventBusConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/async/AsyncEventBusConfigBeanTest.java @@ -40,7 +40,7 @@ public class AsyncEventBusConfigBeanTest extends AbstractConfigTest { TestingScheduledThreadPoolModule.class, poolImplName); factory = new AsyncEventBusModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory, + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory, scheduledThreadPoolConfigFactory)); } diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/SyncEventBusConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/SyncEventBusConfigBeanTest.java index bc5e98bcb3..aeb6d6b959 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/SyncEventBusConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/eventbus/SyncEventBusConfigBeanTest.java @@ -7,14 +7,6 @@ */ package org.opendaylight.controller.config.threadpool.eventbus; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; -import static org.junit.matchers.JUnitMatchers.containsString; - -import javax.management.InstanceAlreadyExistsException; -import javax.management.ObjectName; - import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.api.ConflictingVersionException; @@ -25,6 +17,14 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod import org.opendaylight.controller.config.util.ConfigTransactionJMXClient; import org.opendaylight.controller.config.yang.threadpool.impl.EventBusModuleFactory; +import javax.management.InstanceAlreadyExistsException; +import javax.management.ObjectName; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.junit.matchers.JUnitMatchers.containsString; + public class SyncEventBusConfigBeanTest extends AbstractConfigTest { private EventBusModuleFactory factory; @@ -34,7 +34,7 @@ public class SyncEventBusConfigBeanTest extends AbstractConfigTest { public void setUp() { factory = new EventBusModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory)); + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory)); } @Test diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java index 781215da43..c95661d9c9 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java @@ -36,7 +36,7 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest { @Before public void setUp() { factory = new FixedThreadPoolModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory, + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory, new NamingThreadFactoryModuleFactory())); } diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/flexible/FlexibleThreadPoolConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/flexible/FlexibleThreadPoolConfigBeanTest.java index f0e8a108e7..a1d1c40655 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/flexible/FlexibleThreadPoolConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/flexible/FlexibleThreadPoolConfigBeanTest.java @@ -38,7 +38,7 @@ public class FlexibleThreadPoolConfigBeanTest extends AbstractConfigTest { public void setUp() { flexibleFactory = new FlexibleThreadPoolModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(flexibleFactory, + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,flexibleFactory, new NamingThreadFactoryModuleFactory())); } diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/NamingThreadPoolFactoryConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/NamingThreadPoolFactoryConfigBeanTest.java index 6dea96e21f..499beced5f 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/NamingThreadPoolFactoryConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/naming/NamingThreadPoolFactoryConfigBeanTest.java @@ -16,7 +16,6 @@ import static org.junit.matchers.JUnitMatchers.containsString; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; - import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.api.ConflictingVersionException; @@ -38,7 +37,7 @@ public class NamingThreadPoolFactoryConfigBeanTest extends AbstractConfigTest { public void setUp() { factory = new NamingThreadFactoryModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory)); + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory)); } @Test diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java index 538d43726b..ef06e43d2f 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java @@ -39,7 +39,7 @@ public class ScheduledThreadPoolConfigBeanTest extends AbstractConfigTest { public void setUp() { factory = new ScheduledThreadPoolModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory, + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory, new NamingThreadFactoryModuleFactory())); } diff --git a/opendaylight/config/yang-jmx-generator-it/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/it/ITTest.java b/opendaylight/config/yang-jmx-generator-it/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/it/ITTest.java index 598b6b3d5b..7505fcf485 100644 --- a/opendaylight/config/yang-jmx-generator-it/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/it/ITTest.java +++ b/opendaylight/config/yang-jmx-generator-it/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/it/ITTest.java @@ -7,11 +7,6 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.it; -import static org.junit.Assert.fail; - -import javax.management.InstanceAlreadyExistsException; -import javax.management.ObjectName; - import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -26,6 +21,11 @@ import org.opendaylight.controller.config.yang.test.impl.DtoB; import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory; import org.opendaylight.controller.config.yang.test.impl.TestImplModuleMXBean; +import javax.management.InstanceAlreadyExistsException; +import javax.management.ObjectName; + +import static org.junit.Assert.fail; + @Ignore // ietf beans are not JMX compliant beans: // Do not know how to make a @@ -42,7 +42,7 @@ public class ITTest extends AbstractConfigTest { public void setUp() { factory = new TestImplModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory)); } diff --git a/opendaylight/config/yang-jmx-generator-plugin/pom.xml b/opendaylight/config/yang-jmx-generator-plugin/pom.xml index 2d49ed7fab..b8831f6979 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/pom.xml +++ b/opendaylight/config/yang-jmx-generator-plugin/pom.xml @@ -126,30 +126,4 @@ - - - - maven-compiler-plugin - 3.1 - - groovy-eclipse-compiler - false - - - - - org.codehaus.groovy - groovy-eclipse-batch - 2.1.8-01 - - - org.codehaus.groovy - groovy-eclipse-compiler - 2.8.0-01 - - - - - - diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.groovy b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.groovy deleted file mode 100644 index baff88c8f3..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.groovy +++ /dev/null @@ -1,168 +0,0 @@ -/* - * 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.yangjmxgenerator.plugin.gofactory -import com.google.common.base.Optional -import org.opendaylight.controller.config.api.DependencyResolver -import org.opendaylight.controller.config.api.DynamicMBeanWithInstance -import org.opendaylight.controller.config.api.ModuleIdentifier -import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface -import org.opendaylight.controller.config.api.annotations.Description -import org.opendaylight.controller.config.spi.Module -import org.opendaylight.controller.config.spi.ModuleFactory -import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractFactoryTemplate -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field -import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.* -import org.opendaylight.yangtools.yang.common.QName -import org.osgi.framework.BundleContext - -public class AbsFactoryGeneratedObjectFactory { - - public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional copyright) { - FullyQualifiedName absFactoryFQN = new FullyQualifiedName(mbe.packageName, mbe.abstractFactoryName) - FullyQualifiedName moduleFQN = new FullyQualifiedName(mbe.packageName, mbe.stubModuleName) - Optional classJavaDoc = Optional.fromNullable(mbe.getNullableDescription()) - - AbstractFactoryTemplate abstractFactoryTemplate = TemplateFactory.abstractFactoryTemplateFromMbe(mbe) - Optional header = abstractFactoryTemplate.headerString; - List providedServices = mbe.providedServices.keySet().collect { - FullyQualifiedName.fromString(it) - } - - - return toGeneratedObject(absFactoryFQN, copyright, - header, classJavaDoc, mbe.yangModuleQName, - mbe.globallyUniqueName, - providedServices, - moduleFQN, - abstractFactoryTemplate.fields) - } - - public GeneratedObject toGeneratedObject(FullyQualifiedName absFactoryFQN, Optional copyright, - Optional header, Optional classJavaDoc, QName yangModuleQName, - String globallyUniqueName, - List providedServices, - FullyQualifiedName moduleFQN, - List moduleFields) { - JavaFileInputBuilder b = new JavaFileInputBuilder() - Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName) - b.addClassAnnotation(moduleQNameAnnotation) - - b.setFqn(absFactoryFQN) - b.setTypeName(TypeName.absClassType) - - b.setCopyright(copyright); - b.setHeader(header); - b.setClassJavaDoc(classJavaDoc); - b.addImplementsFQN(new FullyQualifiedName(ModuleFactory)) - if (classJavaDoc.isPresent()) { - b.addClassAnnotation("@${Description.canonicalName}(value=\"${classJavaDoc.get()}\")") - } - - b.addToBody("public static final java.lang.String NAME = \"${globallyUniqueName}\";") - b.addToBody("private static final java.util.Set> serviceIfcs;") - - b.addToBody("@Override\n public final String getImplementationName() { \n return NAME; \n}") - - b.addToBody(getServiceIfcsInitialization(providedServices)) - - // createModule - b.addToBody(""" - @Override - public ${Module.canonicalName} createModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${BundleContext.canonicalName} bundleContext) { - return instantiateModule(instanceName, dependencyResolver, bundleContext); - } - """) - - b.addToBody(getCreateModule(moduleFQN, moduleFields)) - - b.addToBody(""" - public ${moduleFQN} instantiateModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${moduleFQN} oldModule, ${AutoCloseable.canonicalName} oldInstance, ${BundleContext.canonicalName} bundleContext) { - return new ${moduleFQN}(new ${ModuleIdentifier.canonicalName}(NAME, instanceName), dependencyResolver, oldModule, oldInstance); - } - """) - - b.addToBody(""" - public ${moduleFQN} instantiateModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${BundleContext.canonicalName} bundleContext) { - return new ${moduleFQN}(new ${ModuleIdentifier.canonicalName}(NAME, instanceName), dependencyResolver); - } - """) - - b.addToBody(""" - public ${moduleFQN} handleChangedClass(${DynamicMBeanWithInstance.canonicalName} old) throws Exception { - throw new UnsupportedOperationException("Class reloading is not supported"); - } - """) - - b.addToBody(""" - @Override - public java.util.Set<${moduleFQN}> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory, ${BundleContext.canonicalName} bundleContext) { - return new java.util.HashSet<${moduleFQN}>(); - } - """) - - return new GeneratedObjectBuilder(b.build()).toGeneratedObject() - } - - private static String getCreateModule(FullyQualifiedName moduleFQN, List moduleFields) { - String result = """ - @Override - public ${Module.canonicalName} createModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${DynamicMBeanWithInstance.canonicalName} old, ${BundleContext.canonicalName} bundleContext) throws Exception { - ${moduleFQN} oldModule = null; - try { - oldModule = (${moduleFQN}) old.getModule(); - } catch(Exception e) { - return handleChangedClass(old); - } - ${moduleFQN} module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext); - """ - result += moduleFields.collect{"module.set${it.name}(oldModule.get${it.name}());"}.join("\n") - result += """ - return module; - } - """ - return result - } - - private static String getServiceIfcsInitialization(List providedServices) { - String generic = "Class" - - String result = """static { - java.util.Set<${generic}> serviceIfcs2 = new java.util.HashSet<${generic}>(); - """ - result += providedServices.collect{"serviceIfcs2.add(${it}.class);"}.join("\n") - result += """serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2); - } - """ - - // add isModuleImplementingServiceInterface and getImplementedServiceIntefaces methods - - result += """ - @Override - public final boolean isModuleImplementingServiceInterface(Class serviceInterface) { - for (Class ifc: serviceIfcs) { - if (serviceInterface.isAssignableFrom(ifc)){ - return true; - } - } - return false; - } - - @Override - public java.util.Set> getImplementedServiceIntefaces() { - return serviceIfcs; - } - """ - - return result - } - -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.java new file mode 100644 index 0000000000..48a6c15706 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.java @@ -0,0 +1,183 @@ +/* + * 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.yangjmxgenerator.plugin.gofactory; + +import static java.lang.String.format; + +import com.google.common.base.Optional; +import java.util.ArrayList; +import java.util.List; +import org.opendaylight.controller.config.api.DependencyResolver; +import org.opendaylight.controller.config.api.DynamicMBeanWithInstance; +import org.opendaylight.controller.config.api.ModuleIdentifier; +import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface; +import org.opendaylight.controller.config.api.annotations.Description; +import org.opendaylight.controller.config.spi.Module; +import org.opendaylight.controller.config.spi.ModuleFactory; +import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractFactoryTemplate; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.TypeName; +import org.opendaylight.yangtools.yang.common.QName; +import org.osgi.framework.BundleContext; + +public class AbsFactoryGeneratedObjectFactory { + + public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional copyright) { + FullyQualifiedName absFactoryFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractFactoryName()); + FullyQualifiedName moduleFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getStubModuleName()); + Optional classJavaDoc = Optional.fromNullable(mbe.getNullableDescription()); + + AbstractFactoryTemplate abstractFactoryTemplate = TemplateFactory.abstractFactoryTemplateFromMbe(mbe); + Optional header = abstractFactoryTemplate.getHeaderString(); + + List providedServices = new ArrayList<>(); + for(String providedService: mbe.getProvidedServices().keySet()) { + providedServices.add(FullyQualifiedName.fromString(providedService)); + } + + return toGeneratedObject(absFactoryFQN, copyright, + header, classJavaDoc, mbe.getYangModuleQName(), + mbe.getGloballyUniqueName(), + providedServices, + moduleFQN, + abstractFactoryTemplate.getFields()); + } + + public GeneratedObject toGeneratedObject(FullyQualifiedName absFactoryFQN, Optional copyright, + Optional header, Optional classJavaDoc, QName yangModuleQName, + String globallyUniqueName, + List providedServices, + FullyQualifiedName moduleFQN, + List moduleFields) { + JavaFileInputBuilder b = new JavaFileInputBuilder(); + Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName); + b.addClassAnnotation(moduleQNameAnnotation); + + b.setFqn(absFactoryFQN); + b.setTypeName(TypeName.absClassType); + + b.setCopyright(copyright); + b.setHeader(header); + b.setClassJavaDoc(classJavaDoc); + b.addImplementsFQN(new FullyQualifiedName(ModuleFactory.class)); + if (classJavaDoc.isPresent()) { + b.addClassAnnotation(format("@%s(value=\"%s\")", Description.class.getCanonicalName(), classJavaDoc.get())); + } + + b.addToBody(format("public static final java.lang.String NAME = \"%s\";", globallyUniqueName)); + b.addToBody(format("private static final java.util.Set> serviceIfcs;", + AbstractServiceInterface.class.getCanonicalName())); + + b.addToBody("@Override\n public final String getImplementationName() { \n return NAME; \n}"); + + b.addToBody(getServiceIfcsInitialization(providedServices)); + + // createModule + b.addToBody(format("\n"+ + "@Override\n"+ + "public %s createModule(String instanceName, %s dependencyResolver, %s bundleContext) {\n"+ + "return instantiateModule(instanceName, dependencyResolver, bundleContext);\n"+ + "}\n", + Module.class.getCanonicalName(), DependencyResolver.class.getCanonicalName(), BundleContext.class.getCanonicalName())); + + b.addToBody(getCreateModule(moduleFQN, moduleFields)); + + b.addToBody(format("\n"+ + "public %s instantiateModule(String instanceName, %s dependencyResolver, %s oldModule, %s oldInstance, %s bundleContext) {\n"+ + "return new %s(new %s(NAME, instanceName), dependencyResolver, oldModule, oldInstance);\n"+ + "}\n", + moduleFQN, DependencyResolver.class.getCanonicalName(), moduleFQN, AutoCloseable.class.getCanonicalName(), + BundleContext.class.getCanonicalName(), moduleFQN, ModuleIdentifier.class.getCanonicalName())); + + b.addToBody(format("\n"+ + "public %s instantiateModule(String instanceName, %s dependencyResolver, %s bundleContext) {\n"+ + "return new %s(new %s(NAME, instanceName), dependencyResolver);\n"+ + "}\n", moduleFQN, DependencyResolver.class.getCanonicalName(), BundleContext.class.getCanonicalName(), + moduleFQN, ModuleIdentifier.class.getCanonicalName() + )); + + b.addToBody(format("\n"+ + "public %s handleChangedClass(%s old) throws Exception {\n"+ + "throw new UnsupportedOperationException(\"Class reloading is not supported\");\n"+ + "}\n", moduleFQN, DynamicMBeanWithInstance.class.getCanonicalName())); + + b.addToBody(format("\n"+ + "@Override\n"+ + "public java.util.Set<%s> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory, %s bundleContext) {\n"+ + "return new java.util.HashSet<%s>();\n"+ + "}\n", moduleFQN, BundleContext.class.getCanonicalName(), moduleFQN)); + + return new GeneratedObjectBuilder(b.build()).toGeneratedObject(); + } + + private static String getCreateModule(FullyQualifiedName moduleFQN, List moduleFields) { + String result = "\n"+ + "@Override\n"+ + format("public %s createModule(String instanceName, %s dependencyResolver, %s old, %s bundleContext) throws Exception {\n", + Module.class.getCanonicalName(),DependencyResolver.class.getCanonicalName(), + DynamicMBeanWithInstance.class.getCanonicalName(),BundleContext.class.getCanonicalName())+ + format("%s oldModule = null;\n",moduleFQN)+ + "try {\n"+ + format("oldModule = (%s) old.getModule();\n",moduleFQN)+ + "} catch(Exception e) {\n"+ + "return handleChangedClass(old);\n"+ + "}\n"+ + format("%s module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext);\n", moduleFQN); + + for(Field field: moduleFields) { + result += format("module.set%s(oldModule.get%1$s());\n", field.getName()); + } + + result += "\n"+ + "return module;\n"+ + "}\n"; + return result; + } + + private static String getServiceIfcsInitialization(List providedServices) { + String generic = format("Class", AbstractServiceInterface.class.getCanonicalName()); + + String result = format("static {\n"+ + "java.util.Set<%1$s> serviceIfcs2 = new java.util.HashSet<%1$s>();\n", generic); + + for(FullyQualifiedName fqn: providedServices) { + result += format("serviceIfcs2.add(%s.class);\n", fqn); + } + result += "serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2);\n"+ + "}\n"; + + // add isModuleImplementingServiceInterface and getImplementedServiceIntefaces methods + + result += format("\n"+ + "@Override\n"+ + "public final boolean isModuleImplementingServiceInterface(Class serviceInterface) {\n"+ + "for (Class ifc: serviceIfcs) {\n"+ + "if (serviceInterface.isAssignableFrom(ifc)){\n"+ + "return true;\n"+ + "}\n"+ + "}\n"+ + "return false;\n"+ + "}\n"+ + "\n"+ + "@Override\n"+ + "public java.util.Set> getImplementedServiceIntefaces() {\n"+ + "return serviceIfcs;\n"+ + "}\n", AbstractServiceInterface.class.getCanonicalName()); + + return result; + } + +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.groovy b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.groovy deleted file mode 100644 index 930acff7bc..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.groovy +++ /dev/null @@ -1,400 +0,0 @@ -/* - * 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.yangjmxgenerator.plugin.gofactory -import com.google.common.base.Optional -import org.opendaylight.controller.config.api.DependencyResolver -import org.opendaylight.controller.config.api.ModuleIdentifier -import org.opendaylight.controller.config.api.annotations.Description -import org.opendaylight.controller.config.api.runtime.RootRuntimeBeanRegistrator -import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractModuleTemplate -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.IdentityRefModuleField -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Method -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField -import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.* -import org.opendaylight.yangtools.yang.common.QName -import org.slf4j.Logger -import org.slf4j.LoggerFactory - -public class AbsModuleGeneratedObjectFactory { - - public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional copyright) { - FullyQualifiedName abstractFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractModuleName()) - Optional classJavaDoc = Optional.fromNullable(mbe.getNullableDescription()) - AbstractModuleTemplate abstractModuleTemplate = TemplateFactory.abstractModuleTemplateFromMbe(mbe) - Optional header = abstractModuleTemplate.headerString; - List implementedInterfaces = abstractModuleTemplate.getTypeDeclaration().getImplemented().collect { - FullyQualifiedName.fromString(it) - } - Optional maybeRegistratorType - if (abstractModuleTemplate.isRuntime()) { - maybeRegistratorType = Optional.of(FullyQualifiedName.fromString(abstractModuleTemplate.getRegistratorType())) - } else { - maybeRegistratorType = Optional.absent() - } - - return toGeneratedObject(abstractFQN, copyright, header, classJavaDoc, implementedInterfaces, - abstractModuleTemplate.getModuleFields(), maybeRegistratorType, abstractModuleTemplate.getMethods(), - mbe.yangModuleQName - ) - } - - public GeneratedObject toGeneratedObject(FullyQualifiedName abstractFQN, - Optional copyright, - Optional header, - Optional classJavaDoc, - List implementedInterfaces, - List moduleFields, - Optional maybeRegistratorType, - List methods, - QName yangModuleQName) { - JavaFileInputBuilder b = new JavaFileInputBuilder() - - Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName) - b.addClassAnnotation(moduleQNameAnnotation) - - b.setFqn(abstractFQN) - b.setTypeName(TypeName.absClassType) - - b.setCopyright(copyright); - b.setHeader(header); - b.setClassJavaDoc(classJavaDoc); - implementedInterfaces.each { b.addImplementsFQN(it) } - if (classJavaDoc.isPresent()) { - b.addClassAnnotation("@${Description.canonicalName}(value=\"${classJavaDoc.get()}\")") - } - - // add logger: - b.addToBody(getLogger(abstractFQN)); - - b.addToBody("//attributes start"); - - b.addToBody(moduleFields.collect { it.toString() }.join("\n")) - - b.addToBody("//attributes end"); - - - b.addToBody(getCommonFields(abstractFQN)); - - - b.addToBody(getNewConstructor(abstractFQN)) - b.addToBody(getCopyFromOldConstructor(abstractFQN)) - - b.addToBody(getRuntimeRegistratorCode(maybeRegistratorType)) - b.addToBody(getValidationMethods(moduleFields)) - - b.addToBody(getCachesOfResolvedDependencies(moduleFields)) - b.addToBody(getCachesOfResolvedIdentityRefs(moduleFields)) - b.addToBody(getGetInstance(moduleFields)) - b.addToBody(getReuseLogic(moduleFields, abstractFQN)) - b.addToBody(getEqualsAndHashCode(abstractFQN)) - - b.addToBody(getMethods(methods)) - - return new GeneratedObjectBuilder(b.build()).toGeneratedObject() - } - - private static String getMethods(List methods) { - String result = """ - // getters and setters - """ - result += methods.collect{it.toString()}.join("\n") - return result - } - - private static String getEqualsAndHashCode(FullyQualifiedName abstractFQN) { - return """ - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ${abstractFQN.typeName} that = (${abstractFQN.typeName}) o; - return identifier.equals(that.identifier); - } - - @Override - public int hashCode() { - return identifier.hashCode(); - } - """ - } - - private static String getReuseLogic(List moduleFields, FullyQualifiedName abstractFQN) { - String result = """ - public boolean canReuseInstance(${abstractFQN.typeName} oldModule){ - // allow reusing of old instance if no parameters was changed - return isSame(oldModule); - } - - public ${AutoCloseable.canonicalName} reuseInstance(${AutoCloseable.canonicalName} oldInstance){ - // implement if instance reuse should be supported. Override canReuseInstance to change the criteria. - return oldInstance; - } - """ - // isSame method that detects changed fields - result += """ - public boolean isSame(${abstractFQN.typeName} other) { - if (other == null) { - throw new IllegalArgumentException("Parameter 'other' is null"); - } - """ - // loop through fields, do deep equals on each field - result += moduleFields.collect { field -> - if (field.isListOfDependencies()) { - return """ - if (${field.name}Dependency.equals(other.${field.name}Dependency) == false) { - return false; - } - for (int idx = 0; idx < ${field.name}Dependency.size(); idx++) { - if (${field.name}Dependency.get(idx) != other.${field.name}Dependency.get(idx)) { - return false; - } - } - """ - } else if (field.isDependent()) { - return """ - if (${field.name}Dependency != other.${field.name}Dependency) { // reference to dependency must be same - return false; - } - """ - } else { - return """ - if (java.util.Objects.deepEquals(${field.name}, other.${field.name}) == false) { - return false; - } - """ - } - }.join("\n") - - - result += """ - return true; - } - """ - - return result - } - - private static String getGetInstance(List moduleFields) { - String result = """ - @Override - public final ${AutoCloseable.canonicalName} getInstance() { - if(instance==null) { - """ - // create instance start - - // loop through dependent fields, use dependency resolver to instantiate dependencies. Do it in loop in case field represents list of dependencies. - Map resolveDependenciesMap = moduleFields.findAll { - it.isDependent() - }.collectEntries { ModuleField field -> - [field, field.isList() ? - """ - ${field.name}Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>(); - for(javax.management.ObjectName dep : ${field.name}) { - ${field.name}Dependency.add(dependencyResolver.resolveInstance(${ - field.dependency.sie.exportedOsgiClassName - }.class, dep, ${field.name}JmxAttribute)); - } - """ - : - """ - ${field.name}Dependency = dependencyResolver.resolveInstance(${ - field.dependency.sie.exportedOsgiClassName - }.class, ${field.name}, ${field.name}JmxAttribute); - """ - ] - } - // wrap each field resolvation statement with if !=null when dependency is not mandatory - def wrapWithNullCheckClosure = {Map map, predicate -> map.collect { ModuleField key, String value -> - predicate(key) ? """ - if(${key.name}!=null) { - ${value} - } - """ : value - }.join("\n") - } - - result += wrapWithNullCheckClosure(resolveDependenciesMap, {ModuleField key -> - key.getDependency().isMandatory() == false} ) - - // add code to inject dependency resolver to fields that support it - Map injectDepsMap = moduleFields.findAll { it.needsDepResolver }.collectEntries { field -> - if (field.isList()) { - return [field,""" - for(${field.genericInnerType} candidate : ${field.name}) { - candidate.injectDependencyResolver(dependencyResolver); - } - """] - } else { - return [field, "${field.name}.injectDependencyResolver(dependencyResolver);"] - } - } - - result += wrapWithNullCheckClosure(injectDepsMap, {true}) - - // identity refs need to be injected with dependencyResolver and base class - Map resolveIdentityMap = moduleFields.findAll { it.isIdentityRef() }.collectEntries { IdentityRefModuleField field -> - [field, - "set${field.attributeName}(${field.name}.resolveIdentity(dependencyResolver, ${field.identityBaseClass}.class));"] - } - - result += wrapWithNullCheckClosure(resolveIdentityMap, {true}) - - // create instance end: reuse and recreate logic - result += """ - if(oldInstance!=null && canReuseInstance(oldModule)) { - instance = reuseInstance(oldInstance); - } else { - if(oldInstance!=null) { - try { - oldInstance.close(); - } catch(Exception e) { - logger.error("An error occurred while closing old instance " + oldInstance, e); - } - } - instance = createInstance(); - if (instance == null) { - throw new IllegalStateException("Error in createInstance - null is not allowed as return value"); - } - } - } - return instance; - } - public abstract ${AutoCloseable.canonicalName} createInstance(); - """ - return result - } - - private static String getCommonFields(FullyQualifiedName abstractFQN) { - return """ - private final ${abstractFQN.typeName} oldModule; - private final ${AutoCloseable.canonicalName} oldInstance; - private ${AutoCloseable.canonicalName} instance; - private final ${DependencyResolver.canonicalName} dependencyResolver; - private final ${ModuleIdentifier.canonicalName} identifier; - @Override - public ${ModuleIdentifier.canonicalName} getIdentifier() { - return identifier; - } - """ - } - - private static String getCachesOfResolvedIdentityRefs(List moduleFields) { - return moduleFields.findAll { it.isIdentityRef() }.collect { IdentityRefModuleField field -> - "private ${field.identityClassType} ${field.identityClassName};" - }.join("\n") - } - - private static String getCachesOfResolvedDependencies(List moduleFields) { - return moduleFields.findAll { it.dependent }.collect { field -> - if (field.isList()) { - return """ - private java.util.List<${field.dependency.sie.exportedOsgiClassName}> ${ - field.name - }Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>(); - protected final java.util.List<${field.dependency.sie.exportedOsgiClassName}> get${ - field.attributeName - }Dependency(){ - return ${field.name}Dependency; - } - """ - } else { - return """ - private ${field.dependency.sie.exportedOsgiClassName} ${field.name}Dependency; - protected final ${field.dependency.sie.exportedOsgiClassName} get${field.attributeName}Dependency(){ - return ${field.name}Dependency; - } - """ - } - }.join("\n") - } - - private static String getRuntimeRegistratorCode(Optional maybeRegistratorType) { - if (maybeRegistratorType.isPresent()) { - String registratorType = maybeRegistratorType.get() - - return """ - private ${registratorType} rootRuntimeBeanRegistratorWrapper; - - public ${registratorType} getRootRuntimeBeanRegistratorWrapper(){ - return rootRuntimeBeanRegistratorWrapper; - } - - @Override - public void setRuntimeBeanRegistrator(${RootRuntimeBeanRegistrator.canonicalName} rootRuntimeRegistrator){ - this.rootRuntimeBeanRegistratorWrapper = new ${registratorType}(rootRuntimeRegistrator); - } - """ - } else { - return "" - } - } - - private static String getValidationMethods(List moduleFields) { - String result = """ - @Override - public void validate() { - """ - // validate each mandatory dependency - List lines = moduleFields.findAll{(it.dependent && it.dependency.mandatory)}.collect { field -> - if (field.isList()) { - return "" + - "for(javax.management.ObjectName dep : ${field.name}) {\n" + - " dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, dep, ${field.name}JmxAttribute);\n" + - "}\n" - } else { - return "dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, ${field.name}, ${field.name}JmxAttribute);" - } - } - result += lines.findAll { it.isEmpty() == false }.join("\n") - result += """ - customValidation(); - } - - protected void customValidation(){ - } - """ - return result - } - - private static String getLogger(FullyQualifiedName fqn) { - return "private static final ${Logger.canonicalName} logger = ${LoggerFactory.canonicalName}.getLogger(${fqn.toString()}.class);" - } - - // assumes that each parameter name corresponds to an field in this class, constructs lines setting this.field = field; - private static String getConstructorStart(FullyQualifiedName fqn, - LinkedHashMap parameters, String after) { - return "public ${fqn.typeName}(" + - parameters.collect { it.key + " " + it.value }.join(",") + - ") {\n" + - parameters.values().collect { "this.${it}=${it};\n" }.join() + - after + - "}\n" - } - - private static String getNewConstructor(FullyQualifiedName abstractFQN) { - LinkedHashMap parameters = [ - (ModuleIdentifier.canonicalName): "identifier", - (DependencyResolver.canonicalName): "dependencyResolver" - ] - String setToNulls = ["oldInstance", "oldModule"].collect { "this.${it}=null;\n" }.join() - return getConstructorStart(abstractFQN, parameters, setToNulls) - } - - private static String getCopyFromOldConstructor(FullyQualifiedName abstractFQN) { - LinkedHashMap parameters = [ - (ModuleIdentifier.canonicalName): "identifier", - (DependencyResolver.canonicalName): "dependencyResolver", - (abstractFQN.typeName): "oldModule", - (AutoCloseable.canonicalName): "oldInstance" - ] - return getConstructorStart(abstractFQN, parameters, "") - } -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.java new file mode 100644 index 0000000000..aa06cb97d7 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.java @@ -0,0 +1,417 @@ +/* + * 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.yangjmxgenerator.plugin.gofactory; + +import static java.lang.String.format; + +import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.opendaylight.controller.config.api.DependencyResolver; +import org.opendaylight.controller.config.api.ModuleIdentifier; +import org.opendaylight.controller.config.api.annotations.Description; +import org.opendaylight.controller.config.api.runtime.RootRuntimeBeanRegistrator; +import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractModuleTemplate; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.IdentityRefModuleField; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Method; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.TypeName; +import org.opendaylight.yangtools.yang.common.QName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AbsModuleGeneratedObjectFactory { + + public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional copyright) { + FullyQualifiedName abstractFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractModuleName()); + Optional classJavaDoc = Optional.fromNullable(mbe.getNullableDescription()); + AbstractModuleTemplate abstractModuleTemplate = TemplateFactory.abstractModuleTemplateFromMbe(mbe); + Optional header = abstractModuleTemplate.getHeaderString(); + + List implementedInterfaces = new ArrayList<>(); + for(String implemented: abstractModuleTemplate.getTypeDeclaration().getImplemented()) { + implementedInterfaces.add(FullyQualifiedName.fromString(implemented)); + } + Optional maybeRegistratorType; + if (abstractModuleTemplate.isRuntime()) { + maybeRegistratorType = Optional.of(FullyQualifiedName.fromString(abstractModuleTemplate.getRegistratorType())); + } else { + maybeRegistratorType = Optional.absent(); + } + + return toGeneratedObject(abstractFQN, copyright, header, classJavaDoc, implementedInterfaces, + abstractModuleTemplate.getModuleFields(), maybeRegistratorType, abstractModuleTemplate.getMethods(), + mbe.getYangModuleQName()); + } + + public GeneratedObject toGeneratedObject(FullyQualifiedName abstractFQN, + Optional copyright, + Optional header, + Optional classJavaDoc, + List implementedInterfaces, + List moduleFields, + Optional maybeRegistratorType, + List methods, + QName yangModuleQName) { + JavaFileInputBuilder b = new JavaFileInputBuilder(); + + Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName); + b.addClassAnnotation(moduleQNameAnnotation); + + b.setFqn(abstractFQN); + b.setTypeName(TypeName.absClassType); + + b.setCopyright(copyright); + b.setHeader(header); + b.setClassJavaDoc(classJavaDoc); + for(FullyQualifiedName implemented: implementedInterfaces) { + b.addImplementsFQN(implemented); + } + if (classJavaDoc.isPresent()) { + b.addClassAnnotation(format("@%s(value=\"%s\")", Description.class.getCanonicalName(), classJavaDoc.get())); + } + + // add logger: + b.addToBody(getLogger(abstractFQN)); + + b.addToBody("//attributes start"); + for(ModuleField moduleField: moduleFields) { + b.addToBody(moduleField.toString() +"\n"); + } + + b.addToBody("//attributes end"); + + + b.addToBody(getCommonFields(abstractFQN)); + + + b.addToBody(getNewConstructor(abstractFQN)); + b.addToBody(getCopyFromOldConstructor(abstractFQN)); + + b.addToBody(getRuntimeRegistratorCode(maybeRegistratorType)); + b.addToBody(getValidationMethods(moduleFields)); + + b.addToBody(getCachesOfResolvedDependencies(moduleFields)); + b.addToBody(getCachesOfResolvedIdentityRefs(moduleFields)); + b.addToBody(getGetInstance(moduleFields)); + b.addToBody(getReuseLogic(moduleFields, abstractFQN)); + b.addToBody(getEqualsAndHashCode(abstractFQN)); + + b.addToBody(getMethods(methods)); + + return new GeneratedObjectBuilder(b.build()).toGeneratedObject(); + } + + private static String getMethods(List methods) { + String result = "\n// getters and setters\n"; + for(Method method: methods) { + result += method.toString()+"\n"; + } + return result; + } + + private static String getEqualsAndHashCode(FullyQualifiedName abstractFQN) { + return "\n"+ + "@Override\n"+ + "public boolean equals(Object o) {\n"+ + "if (this == o) return true;\n"+ + "if (o == null || getClass() != o.getClass()) return false;\n"+ + format("%s that = (%1$s) o;\n", abstractFQN.getTypeName())+ + "return identifier.equals(that.identifier);\n"+ + "}\n"+ + "\n"+ + "@Override\n"+ + "public int hashCode() {\n"+ + "return identifier.hashCode();\n"+ + "}\n"; + } + + private static String getReuseLogic(List moduleFields, FullyQualifiedName abstractFQN) { + String result = "\n"+ + format("public boolean canReuseInstance(%s oldModule){\n", abstractFQN.getTypeName())+ + "// allow reusing of old instance if no parameters was changed\n"+ + "return isSame(oldModule);\n"+ + "}\n"+ + "\n"+ + format("public %s reuseInstance(%1$s oldInstance){\n", AutoCloseable.class.getCanonicalName())+ + "// implement if instance reuse should be supported. Override canReuseInstance to change the criteria.\n"+ + "return oldInstance;\n"+ + "}\n"; + // isSame method that detects changed fields + result += "\n"+ + format("public boolean isSame(%s other) {\n", abstractFQN.getTypeName())+ + "if (other == null) {\n"+ + "throw new IllegalArgumentException(\"Parameter 'other' is null\");\n"+ + "}\n"; + // loop through fields, do deep equals on each field + + for (ModuleField moduleField : moduleFields) { + if (moduleField.isListOfDependencies()) { + result += format( + "if (%1$sDependency.equals(other.%1$sDependency) == false) {\n"+ + "return false;\n"+ + "}\n"+ + "for (int idx = 0; idx < %1$sDependency.size(); idx++) {\n"+ + "if (%1$sDependency.get(idx) != other.%1$sDependency.get(idx)) {\n"+ + "return false;\n"+ + "}\n"+ + "}\n" ,moduleField.getName()); + } else if (moduleField.isDependent()) { + result += format( + "if (%sDependency != other.%1$sDependency) { // reference to dependency must be same\n"+ + "return false;\n"+ + "}\n",moduleField.getName()); + } else { + result += format( + "if (java.util.Objects.deepEquals(%s, other.%1$s) == false) {\n"+ + "return false;\n"+ + "}\n", moduleField.getName()); + } + } + result += "\n"+ + "return true;\n"+ + "}\n"; + + return result; + } + + private static String getGetInstance(List moduleFields) { + String result = "\n"+ + "@Override\n"+ + format("public final %s getInstance() {\n", AutoCloseable.class.getCanonicalName())+ + "if(instance==null) {\n"; + // create instance start + + // loop through dependent fields, use dependency resolver to instantiate dependencies. Do it in loop in case field represents list of dependencies. + Map resolveDependenciesMap = new HashMap<>(); + for(ModuleField moduleField: moduleFields) { + if (moduleField.isDependent()) { + String str; + String osgi = moduleField.getDependency().getSie().getExportedOsgiClassName(); + if (moduleField.isList()) { + str = format( + "%sDependency = new java.util.ArrayList<%s>();\n"+ + "for(javax.management.ObjectName dep : %1$s) {\n"+ + "%1$sDependency.add(dependencyResolver.resolveInstance(%2$s.class, dep, %1$sJmxAttribute));\n"+ + "}\n", moduleField.getName(), osgi); + } else { + str = format( + "%1$sDependency = dependencyResolver.resolveInstance(%2$s.class, %1$s, %1$sJmxAttribute);", + moduleField.getName(), osgi); + } + resolveDependenciesMap.put(moduleField, str); + } + } + + // wrap each field resolvation statement with if !=null when dependency is not mandatory + for (Map.Entry entry : resolveDependenciesMap.entrySet()) { + if (entry.getKey().getDependency().isMandatory() == false) { + result += format("if (%s!=null) {\n%s;\n}", entry.getKey().getName(), entry.getValue()); + } else { + result += entry.getValue(); + } + } + + // add code to inject dependency resolver to fields that support it + for(ModuleField moduleField: moduleFields) { + if (moduleField.isNeedsDepResolver()) { + result += format("if (%s!=null){\n", moduleField.getName()); + if (moduleField.isList()) { + result += format( + "for(%s candidate : %s) {\n"+ + "candidate.injectDependencyResolver(dependencyResolver);\n"+ + "}\n", moduleField.getGenericInnerType(), moduleField.getName()); + } else { + result += format("%s.injectDependencyResolver(dependencyResolver);\n", moduleField.getName()); + } + result += "}\n"; + } + } + + // identity refs need to be injected with dependencyResolver and base class + for (ModuleField moduleField : moduleFields) { + if (moduleField.isIdentityRef()) { + result += format("if (%s!=null) {", moduleField.getName()); + result += format("set%s(%s.resolveIdentity(dependencyResolver, %s.class));", + moduleField.getAttributeName(), moduleField.getName(), + ((IdentityRefModuleField)moduleField).getIdentityBaseClass()); + result += "}\n"; + } + } + + // create instance end: reuse and recreate logic + result += "if(oldInstance!=null && canReuseInstance(oldModule)) {\n"+ + "instance = reuseInstance(oldInstance);\n"+ + "} else {\n"+ + "if(oldInstance!=null) {\n"+ + "try {\n"+ + "oldInstance.close();\n"+ + "} catch(Exception e) {\n"+ + "logger.error(\"An error occurred while closing old instance \" + oldInstance, e);\n"+ + "}\n"+ + "}\n"+ + "instance = createInstance();\n"+ + "if (instance == null) {\n"+ + "throw new IllegalStateException(\"Error in createInstance - null is not allowed as return value\");\n"+ + "}\n"+ + "}\n"+ + "}\n"+ + "return instance;\n"+ + "}\n"+ + format("public abstract %s createInstance();\n", AutoCloseable.class.getCanonicalName()); + + return result; + } + + private static String getCommonFields(FullyQualifiedName abstractFQN) { + return "\n"+ + format("private final %s oldModule;\n", abstractFQN.getTypeName())+ + format("private final %s oldInstance;\n", AutoCloseable.class.getCanonicalName())+ + format("private %s instance;\n", AutoCloseable.class.getCanonicalName())+ + format("private final %s dependencyResolver;\n", DependencyResolver.class.getCanonicalName())+ + format("private final %s identifier;\n", ModuleIdentifier.class.getCanonicalName())+ + "@Override\n"+ + format("public %s getIdentifier() {\n", ModuleIdentifier.class.getCanonicalName())+ + "return identifier;\n"+ + "}\n"; + } + + private static String getCachesOfResolvedIdentityRefs(List moduleFields) { + StringBuilder result = new StringBuilder(); + for (ModuleField moduleField : moduleFields) { + if (moduleField.isIdentityRef()) { + IdentityRefModuleField field = (IdentityRefModuleField) moduleField; + result.append(format("private %s %s;\n", field.getIdentityClassType(), field.getIdentityClassName())); + } + } + return result.toString(); + } + + private static String getCachesOfResolvedDependencies(List moduleFields) { + StringBuilder result = new StringBuilder(); + for (ModuleField moduleField: moduleFields) { + if (moduleField.isDependent()) { + String osgi = moduleField.getDependency().getSie().getExportedOsgiClassName(); + if (moduleField.isList()) { + result + .append(format("private java.util.List<%s> %sDependency = new java.util.ArrayList<%s>();", osgi, moduleField.getName(), osgi)) + .append(format("protected final java.util.List<%s> get%sDependency(){\n", osgi, moduleField.getAttributeName())) + .append(format("return %sDependency;\n", moduleField.getName())) + .append("}\n"); + } else { + result.append(format( + "private %s %sDependency;\n"+ + "protected final %s get%sDependency(){\n"+ + "return %sDependency;\n"+ + "}", + osgi, moduleField.getName(), osgi, moduleField.getAttributeName(), moduleField.getName())); + } + } + } + return result.toString(); + } + + private static String getRuntimeRegistratorCode(Optional maybeRegistratorType) { + if (maybeRegistratorType.isPresent()) { + String registratorType = maybeRegistratorType.get().toString(); + + return "\n"+ + format("private %s rootRuntimeBeanRegistratorWrapper;\n", registratorType)+ + "\n"+ + format("public %s getRootRuntimeBeanRegistratorWrapper(){\n", registratorType)+ + "return rootRuntimeBeanRegistratorWrapper;\n"+ + "}\n"+ + "\n"+ + "@Override\n"+ + format("public void setRuntimeBeanRegistrator(%s rootRuntimeRegistrator){\n", RootRuntimeBeanRegistrator.class.getCanonicalName())+ + format("this.rootRuntimeBeanRegistratorWrapper = new %s(rootRuntimeRegistrator);\n", registratorType)+ + "}\n"; + } else { + return ""; + } + } + + private static String getValidationMethods(List moduleFields) { + String result = "\n"+ + "@Override\n"+ + "public void validate() {\n"; + // validate each mandatory dependency + for(ModuleField moduleField: moduleFields) { + if (moduleField.isDependent() && moduleField.getDependency().isMandatory()) { + if (moduleField.isList()) { + result += "" + + format("for(javax.management.ObjectName dep : %s) {\n", moduleField.getName()) + + format(" dependencyResolver.validateDependency(%s.class, dep, %sJmxAttribute);\n", + moduleField.getDependency().getSie().getFullyQualifiedName(), moduleField.getName()) + + "}\n"; + } else { + result += format("dependencyResolver.validateDependency(%s.class, %s, %sJmxAttribute);", + moduleField.getDependency().getSie().getFullyQualifiedName(), moduleField.getName(), moduleField.getName()); + } + } + } + result += "\n"+ + "customValidation();\n"+ + "}\n"+ + "\n"+ + "protected void customValidation() {\n"+ + "}\n"; + return result; + } + + private static String getLogger(FullyQualifiedName fqn) { + return format("private static final %s logger = %s.getLogger(%s.class);", + Logger.class.getCanonicalName(), LoggerFactory.class.getCanonicalName(), fqn); + } + + // assumes that each parameter name corresponds to an field in this class, constructs lines setting this.field = field; + private static String getConstructorStart(FullyQualifiedName fqn, + LinkedHashMap parameters, String after) { + String paramString = Joiner.on(",").withKeyValueSeparator(" ").join(parameters); + String setters = ""; + for (String paramName : parameters.values()) { + setters += format("this.%s = %1$s;\n", paramName); + } + return format("public %s(", fqn.getTypeName()) + + paramString + + ") {\n" + + setters + + after + + "}\n"; + } + + private static String getNewConstructor(FullyQualifiedName abstractFQN) { + LinkedHashMap parameters = new LinkedHashMap<>(); + parameters.put(ModuleIdentifier.class.getCanonicalName(), "identifier"); + parameters.put(DependencyResolver.class.getCanonicalName(), "dependencyResolver"); + + String setToNulls = "this.oldInstance=null;\n;" + + "this.oldModule=null;\n"; + return getConstructorStart(abstractFQN, parameters, setToNulls); + } + + private static String getCopyFromOldConstructor(FullyQualifiedName abstractFQN) { + LinkedHashMap parameters = new LinkedHashMap<>(); + parameters.put(ModuleIdentifier.class.getCanonicalName(), "identifier"); + parameters.put(DependencyResolver.class.getCanonicalName(), "dependencyResolver"); + parameters.put(abstractFQN.getTypeName(), "oldModule"); + parameters.put(AutoCloseable.class.getCanonicalName(), "oldInstance"); + return getConstructorStart(abstractFQN, parameters, ""); + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.groovy b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.groovy deleted file mode 100644 index 6504aac7d4..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.groovy +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.yangjmxgenerator.plugin.gofactory - -import com.google.common.base.Optional -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate -import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName -import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject -import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder -import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder - -public class GenericGeneratedObjectFactory { - - public GeneratedObject toGeneratedObject(FtlTemplate template, Optional copyright) { - JavaFileInputBuilder b = new JavaFileInputBuilder(); - b.setHeader(template.headerString) - b.setFqn(new FullyQualifiedName(template.packageName, template.typeDeclaration.name)) - b.setClassJavaDoc(template.maybeJavadoc) - template.annotations.each { b.addClassAnnotation(it) } - // type declaration - template.typeDeclaration.extended.each { b.addExtendsFQN(FullyQualifiedName.fromString(it)) } - template.typeDeclaration.implemented.each { b.addImplementsFQN(FullyQualifiedName.fromString(it)) } - b.setCopyright(copyright); - b.setTypeName(template.typeDeclaration.toTypeName()) - // fields - template.fields.each { b.addToBody(it.toString()) } - // constructors - template.constructors.each { b.addToBody(it.toString()) } - // methods - template.methods.each { b.addToBody(it.toString()) } - - return new GeneratedObjectBuilder(b.build()).toGeneratedObject(); - } -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.java new file mode 100644 index 0000000000..11bb6774ae --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.java @@ -0,0 +1,55 @@ +/* + * 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.yangjmxgenerator.plugin.gofactory; + +import com.google.common.base.Optional; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Constructor; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Method; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder; + +public class GenericGeneratedObjectFactory { + + public GeneratedObject toGeneratedObject(FtlTemplate template, Optional copyright) { + JavaFileInputBuilder b = new JavaFileInputBuilder(); + b.setHeader(template.getHeaderString()); + b.setFqn(new FullyQualifiedName(template.getPackageName(), template.getTypeDeclaration().getName())); + b.setClassJavaDoc(template.getMaybeJavadoc()); + for (Annotation annotation : template.getAnnotations()) { + b.addClassAnnotation(annotation); + } + // type declaration + for (String extended : template.getTypeDeclaration().getExtended()) { + b.addExtendsFQN(FullyQualifiedName.fromString(extended)); + } + for (String implemented : template.getTypeDeclaration().getImplemented()) { + b.addImplementsFQN(FullyQualifiedName.fromString(implemented)); + } + b.setCopyright(copyright); + b.setTypeName(template.getTypeDeclaration().toTypeName()); + // fields + for (Field field : template.getFields()) { + b.addToBody(field.toString()); + } + // constructors + for (Constructor constructor : template.getConstructors()) { + b.addToBody(constructor.toString()); + } + // methods + for (Method method : template.getMethods()) { + b.addToBody(method.toString()); + } + return new GeneratedObjectBuilder(b.build()).toGeneratedObject(); + } +} diff --git a/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java b/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java index f2a56f2b1b..7a20f22440 100644 --- a/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java +++ b/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java @@ -44,22 +44,53 @@ public class ProcessSources extends AbstractMojo{ File[] sourceFiles = sourceDirectory.listFiles(); for (File sourceFile: sourceFiles) { - if(sourceFile.getName().endsWith("Module.java") || sourceFile.getName().endsWith("ModuleFactory.java")) { - File stubFile = new File(sourceFile.getPath().replace(".java", "Stub.txt")); - if (stubFile.exists()) { - try { - rewrite(sourceFile, FileUtils.readFileToString(stubFile)); - } catch (IOException e) { - getLog().error("Error while reading/writing to files.", e); + if (sourceFile.getName().endsWith(".java")) { + String sourceContent; + try { + sourceContent = FileUtils.readFileToString(sourceFile); + } catch (IOException e) { + getLog().error("Cannot read " + sourceFile.getAbsolutePath(), e); + continue; + } + if (sourceFile.getName().endsWith("Module.java") || sourceFile.getName().endsWith("ModuleFactory.java")) { + File stubFile = new File(sourceFile.getPath().replace(".java", "Stub.txt")); + if (stubFile.exists()) { + String stubContent = null; + try { + stubContent = FileUtils.readFileToString(stubFile); + } catch (IOException e) { + getLog().error("Cannot read " + stubFile.getAbsolutePath(), e); + } + if (stubContent != null) { + sourceContent = rewriteStub(sourceContent, stubContent); + } } } + // remove copyright headers as they can contain timestamp + sourceContent = removeCopyrights(sourceContent); + + // replace the file content + try { + FileUtils.write(sourceFile, sourceContent); + } catch (IOException e) { + getLog().error("Cannot write " + sourceFile.getAbsolutePath(), e); + } } + } } - private static void rewrite(File sourceFile, String replaceTODOWith) throws IOException { - String source = FileUtils.readFileToString(sourceFile); - String target = Pattern.compile("^.*TODO.*\n.*throw new java.lang.UnsupportedOperationException.*$", Pattern.MULTILINE).matcher(source).replaceFirst(replaceTODOWith); - FileUtils.write(sourceFile, target); + private static Pattern MULTILINE_COMMENT_PATTERN = Pattern.compile("/\\*.*\\*/", Pattern.MULTILINE | Pattern.DOTALL); + private static String removeCopyrights(String source) { + String target = MULTILINE_COMMENT_PATTERN.matcher(source).replaceAll("\n"); + //FileUtils.write(sourceFile, target); + return target; + } + + private static Pattern UNSUPPORTED_OP_PATTERN = Pattern.compile("^.*TODO.*\n.*throw new java.lang.UnsupportedOperationException.*$", Pattern.MULTILINE); + + private static String rewriteStub(String source, String replaceTODOWith) { + String target = UNSUPPORTED_OP_PATTERN.matcher(source).replaceFirst(replaceTODOWith); + return target; } } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java index 07d7438a00..78ac362e59 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java @@ -1,10 +1,5 @@ -/* -* 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.test.impl; public class DepTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModule { public DepTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java index 330f804e0e..026dd9aca2 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java @@ -1,19 +1,5 @@ -/* -* 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 -*/ -/* -* Generated file -* -* Generated from: yang module name: config-test-impl yang module local name: impl-dep -* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Fri Apr 25 09:12:08 CEST 2014 -* -* Do not modify this file unless it is present under src/main directory -*/ + + package org.opendaylight.controller.config.yang.test.impl; public class DepTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModuleFactory { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java index a5b7f55df3..ddf72f39b4 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java @@ -1,10 +1,5 @@ -/* -* 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.test.impl; public class IdentityTestModule extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModule { public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java index b57d1dc1d4..3a4348d376 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java @@ -1,19 +1,5 @@ -/* -* 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 -*/ -/* -* Generated file -* -* Generated from: yang module name: config-test-impl yang module local name: impl-identity-test -* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Fri Apr 25 09:12:08 CEST 2014 -* -* Do not modify this file unless it is present under src/main directory -*/ + + package org.opendaylight.controller.config.yang.test.impl; public class IdentityTestModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModuleFactory { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java index ecbf4aba33..943fe3b0d7 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java @@ -1,10 +1,5 @@ -/* -* 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.test.impl; public class NetconfTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModule { public NetconfTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java index 74a05496df..587089b10f 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java @@ -1,19 +1,5 @@ -/* -* 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 -*/ -/* -* Generated file -* -* Generated from: yang module name: config-test-impl yang module local name: impl-netconf -* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Fri Apr 25 09:12:08 CEST 2014 -* -* Do not modify this file unless it is present under src/main directory -*/ + + package org.opendaylight.controller.config.yang.test.impl; public class NetconfTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModuleFactory { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java index 4de9804337..1d5cda036f 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleUtil.java @@ -1,10 +1,5 @@ -/* - * 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.test.impl; import com.google.common.collect.Lists; diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java index 9132407356..7b049e7b57 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java @@ -1,10 +1,5 @@ -/* -* 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.test.impl; public class TestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModule { public TestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java index 9680bffd6b..de9ac2fef3 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java @@ -1,19 +1,5 @@ -/* -* 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 -*/ -/* -* Generated file -* -* Generated from: yang module name: config-test-impl yang module local name: impl -* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator -* Generated at: Fri Apr 25 09:12:08 CEST 2014 -* -* Do not modify this file unless it is present under src/main directory -*/ + + package org.opendaylight.controller.config.yang.test.impl; public class TestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModuleFactory { 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 281c1aade5..13a31f5976 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 @@ -48,7 +48,7 @@ public class NetconfTestImplModuleTest extends AbstractConfigTest { public void setUp() { factory = new NetconfTestImplModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory, + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory, new DepTestImplModuleFactory(), new IdentityTestModuleFactory())); } diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini index 9d0d6c1888..234e0feb45 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini @@ -22,6 +22,8 @@ netconf.tcp.client.port=8383 netconf.ssh.address=0.0.0.0 netconf.ssh.port=1830 netconf.ssh.pk.path = ./configuration/RSA.pk +netconf.ssh.default.user = netconf +netconf.ssh.default.password = netconf netconf.config.persister.active=1,2 diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml index 619ab06d8d..d872bfd47b 100644 --- a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml +++ b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml @@ -15,48 +15,13 @@ prefix:schema-service-singleton yang-schema-service - - - - prefix:hash-map-data-store - hash-map-data-store - - - - - - prefix:dom-broker-impl - dom-broker - - - dom:dom-data-store - - hash-map-data-store - - - - - - + prefix:binding-notification-broker + binding-notification-broker prefix:binding-broker-impl @@ -70,33 +35,30 @@ binding-data-broker + + - prefix:runtime-generated-mapping - runtime-mapping-singleton - - - prefix:binding-notification-broker - binding-notification-broker + prefix:dom-inmemory-data-broker + inmemory-data-broker + + dom:schema-service + yang-schema-service + - - prefix:binding-data-broker - binding-data-broker - - dom:dom-broker-osgi-registry - dom-broker - - - binding:binding-dom-mapping-service - runtime-mapping-singleton - + prefix:dom-broker-impl + inmemory-dom-broker + + dom:dom-async-data-broker + inmemory-data-broker + - - - - - - dom:schema-service - - yang-schema-service - /modules/module[type='schema-service-singleton'][name='yang-schema-service'] - - - - binding:binding-notification-service - - binding-notification-broker - /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] - - - - - dom:dom-data-store - - hash-map-data-store - /modules/module[type='hash-map-data-store'][name='hash-map-data-store'] - - - - - - - - binding:binding-broker-osgi-registry - - binding-osgi-broker - /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] - - - - binding:binding-rpc-registry - - binding-rpc-broker - /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] - - - - binding-impl:binding-dom-mapping-service - - runtime-mapping-singleton - /modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton'] - - - - dom:dom-broker-osgi-registry - - dom-broker - /modules/module[type='dom-broker-impl'][name='dom-broker'] - - + + dom:schema-service + + yang-schema-service + /modules/module[type='schema-service-singleton'][name='yang-schema-service'] + + + + binding-impl:binding-dom-mapping-service + + runtime-mapping-singleton + /modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton'] + + + + binding:binding-notification-service + + binding-notification-broker + /modules/module[type='binding-notification-broker'][name='binding-notification-broker'] + + + + binding:binding-broker-osgi-registry + + binding-osgi-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + + + binding:binding-rpc-registry + + binding-rpc-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + - - binding:binding-data-broker - - binding-data-broker - - /modules/module[type='binding-data-broker'][name='binding-data-broker'] - - - - - - + + dom:dom-broker-osgi-registry + + dom-broker + /modules/module[type='dom-broker-impl'][name='inmemory-dom-broker'] + + + + binding:binding-data-broker + + binding-data-broker + /modules/module[type='binding-data-compatible-broker'][name='inmemory-binding-data-broker'] + + + + + dom:dom-async-data-broker + + inmemory-data-broker + /modules/module[type='dom-inmemory-data-broker'][name='inmemory-data-broker'] + + diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml b/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml index 93ce0dd4f7..7770c15349 100644 --- a/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml +++ b/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml @@ -14,10 +14,6 @@ com.google.guava guava - - org.eclipse.xtend - org.eclipse.xtend.lib - org.opendaylight.controller forwardingrulesmanager @@ -67,10 +63,6 @@ - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/ConfigurationReader.java b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/ConfigurationReader.java new file mode 100644 index 0000000000..411af282bd --- /dev/null +++ b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/ConfigurationReader.java @@ -0,0 +1,62 @@ +/** + * 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.md.frm.compatibility; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import org.opendaylight.controller.forwardingrulesmanager.FlowConfig; +import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager; +import org.opendaylight.controller.sal.compatibility.NodeMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.FlowsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ConfigurationReader implements FlowManagementReader { + + private final static Logger LOG = LoggerFactory.getLogger(ConfigurationReader.class); + + private IForwardingRulesManager manager; + + @Override + public Flows readAllFlows() { + List staticFlows = this.manager.getStaticFlows(); + List flowMap = new ArrayList(staticFlows.size()); + + for (FlowConfig conf : staticFlows) { + flowMap.add(FlowConfigMapping.toConfigurationFlow(conf)); + } + final FlowsBuilder flowsBuilder = new FlowsBuilder(); + return (flowsBuilder.setFlow(flowMap)).build(); + } + + @Override + public Flow readFlow(final FlowKey key) { + try { + final FlowConfig flowConf = + this.manager.getStaticFlow(String.valueOf(key.getId()), NodeMapping.toADNode(key.getNode())); + return FlowConfigMapping.toConfigurationFlow(flowConf); + } catch (Exception e) { + String errMsg = MessageFormat.format("readFlow by key {} fail", key); + LOG.error(errMsg, e); + throw new RuntimeException(errMsg, e); + } + } + + public IForwardingRulesManager getManager() { + return this.manager; + } + + public void setManager(final IForwardingRulesManager manager) { + this.manager = manager; + } +} diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.java b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.java new file mode 100644 index 0000000000..be3add1042 --- /dev/null +++ b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.java @@ -0,0 +1,122 @@ +/** + * 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.md.frm.compatibility; + +import java.util.Collections; + +import org.opendaylight.controller.forwardingrulesmanager.FlowConfig; +import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager; +import org.opendaylight.controller.md.sal.common.api.data.DataChangeListener; +import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler; +import org.opendaylight.controller.md.sal.common.api.data.DataModification; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider; +import org.opendaylight.controller.sal.common.util.Arguments; +import org.opendaylight.controller.sal.common.util.Rpcs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Identifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; + +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; + +public class FRMRuntimeDataProvider implements RuntimeDataProvider, DataCommitHandler,DataObject> { + + private final static InstanceIdentifier FLOWS_PATH = InstanceIdentifier. builder(Flows.class).toInstance(); + + private final FlowManagementReader configuration = new ConfigurationReader(); + private DataChangeListener, DataObject> changeListener; + private DataProviderService dataService; + private IForwardingRulesManager manager; + + public Registration, DataObject>> init() { + return this.dataService.registerCommitHandler(FRMRuntimeDataProvider.FLOWS_PATH, this); + } + + @Override + public DataObject readConfigurationData(final InstanceIdentifier path) { + return this.readFrom(this.configuration, path); + } + + @Override + public DataObject readOperationalData(final InstanceIdentifier path) { + return this.readFrom(this.configuration, path); + } + + public DataObject readFrom(final FlowManagementReader store, final InstanceIdentifier path) { + if (Objects.equal(FRMRuntimeDataProvider.FLOWS_PATH, path)) { + return store.readAllFlows(); + } + if (FRMRuntimeDataProvider.FLOWS_PATH.contains(path)) { + return store.readFlow(this.toFlowKey(path)); + } + return null; + } + + @Override + public FlowCommitTransaction requestCommit(final DataModification, DataObject> modification) { + return new FlowCommitTransaction(this, modification); + } + + public FlowKey toFlowKey(final InstanceIdentifier identifier) { + Preconditions.> checkNotNull(identifier); + + Iterable path = identifier.getPathArguments(); + PathArgument get = path.iterator().next(); + final Identifier itemKey = Arguments. checkInstanceOf(get, IdentifiableItem.class).getKey(); + return Arguments. checkInstanceOf(itemKey, FlowKey.class); + } + + public RpcResult finish(final FlowCommitTransaction transaction) { + Iterable toRemove = transaction.getToRemove(); + for (final FlowConfig flow : toRemove) { + this.manager.removeStaticFlow(flow.getName(), flow.getNode()); + } + Iterable toUpdate = transaction.getToUpdate(); + for (final FlowConfig flow : toUpdate) { + this.manager.removeStaticFlow(flow.getName(), flow.getNode()); + this.manager.addStaticFlow(flow); + } + return Rpcs. getRpcResult(true, null, Collections. emptySet()); + } + + public RpcResult rollback(final FlowCommitTransaction transaction) { + return null; + } + + public DataProviderService getDataService() { + return this.dataService; + } + + public void setDataService(final DataProviderService dataService) { + this.dataService = dataService; + } + + public DataChangeListener, DataObject> getChangeListener() { + return this.changeListener; + } + + public void setChangeListener(final DataChangeListener, DataObject> changeListener) { + this.changeListener = changeListener; + } + + public IForwardingRulesManager getManager() { + return this.manager; + } + + public void setManager(final IForwardingRulesManager manager) { + this.manager = manager; + } +} diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend deleted file mode 100644 index 2d4e7d2c60..0000000000 --- a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FRMRuntimeDataProvider.xtend +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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.md.frm.compatibility - -import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows -import org.opendaylight.controller.md.sal.common.api.data.DataChangeListener -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.FlowsBuilder -import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager -import static com.google.common.base.Preconditions.*; -import static extension org.opendaylight.controller.md.frm.compatibility.FlowConfigMapping.*; -import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.*; -import org.opendaylight.controller.sal.common.util.Arguments -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem -import org.opendaylight.yangtools.yang.common.RpcResult -import org.opendaylight.controller.forwardingrulesmanager.FlowConfig -import java.util.HashSet -import org.opendaylight.controller.sal.common.util.Rpcs -import java.util.Collections -import org.opendaylight.yangtools.yang.common.RpcError - -class FRMRuntimeDataProvider implements RuntimeDataProvider, DataCommitHandler, DataObject> { - - static val FLOWS_PATH = InstanceIdentifier.builder(Flows).toInstance; - - @Property - var DataProviderService dataService; - - @Property - var DataChangeListener changeListener; - - @Property - var IForwardingRulesManager manager; - - FlowManagementReader configuration = new ConfigurationReader(); - - def init() { - //dataService.registerDataChangeListener(FLOWS_PATH, changeListener); - dataService.registerCommitHandler(FLOWS_PATH, this); - } - - override readConfigurationData(InstanceIdentifier path) { - return readFrom(configuration, path); - } - - override DataObject readOperationalData(InstanceIdentifier path) { - return readFrom(configuration, path); - } - - def DataObject readFrom(FlowManagementReader store, InstanceIdentifier path) { - if (FLOWS_PATH == path) { - return store.readAllFlows(); - } - if (FLOWS_PATH.contains(path)) { - return store.readFlow(path.toFlowKey()); - } - return null; - } - - override FlowCommitTransaction requestCommit( - DataModification modification) { - return new FlowCommitTransaction(this,modification); - } - - def toFlowKey(InstanceIdentifier identifier) { - checkNotNull(identifier) - val item = Arguments.checkInstanceOf(identifier.path.get(1),IdentifiableItem); - val key = Arguments.checkInstanceOf(item.key,FlowKey) - return key; - } - - def RpcResult finish(FlowCommitTransaction transaction) { - for(flw: transaction.toRemove) { - manager.removeStaticFlow(flw.name,flw.node) - } - - for(flw: transaction.toUpdate) { - manager.removeStaticFlow(flw.name,flw.node); - manager.addStaticFlow(flw); - } - - return Rpcs.getRpcResult(true,null,Collections.emptySet()) - } - - def RpcResult rollback(FlowCommitTransaction transaction) { - // NOOP: We did not changed any state. - } - -} - -class ConfigurationReader implements FlowManagementReader { - - @Property - var IForwardingRulesManager manager; - - override Flows readAllFlows() { - val it = new FlowsBuilder(); - flow = manager.staticFlows.map[ - toConfigurationFlow(); - ] - return it.build(); - } - - override readFlow(FlowKey key) { - val flowCfg = manager.getStaticFlow(String.valueOf(key.id), key.node.toADNode()); - return flowCfg.toConfigurationFlow; - } -} - -public static class FlowCommitTransaction implements DataCommitTransaction, DataObject> { - - @Property - val DataModification, DataObject> modification; - - @Property - val FRMRuntimeDataProvider flowManager; - - @Property - val toAdd = new HashSet(); - - @Property - var Iterable toUpdate - - @Property - var Iterable toRemove - - - new(FRMRuntimeDataProvider flowManager,DataModification, DataObject> modification) { - super(); - _flowManager = flowManager; - _modification = modification; - processModification(); - } - - override finish() throws IllegalStateException { - return flowManager.finish(this); - } - - override rollback() throws IllegalStateException -{ - return flowManager.rollback(this); - } - - def processModification() { - val updated = modification.updatedConfigurationData.entrySet; - - val _toUpdate = updated.filter[key.isFlowPath].map[ - return (value as Flow).toFlowConfig - ] - toUpdate = _toUpdate as Iterable - - - val _toRemove = modification.removedConfigurationData.filter[isFlowPath].map[ - toFlowConfig - ] - toRemove = _toRemove as Iterable - - } -} diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowCommitTransaction.java b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowCommitTransaction.java new file mode 100644 index 0000000000..bf0050d6c0 --- /dev/null +++ b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowCommitTransaction.java @@ -0,0 +1,99 @@ +/** + * 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.md.frm.compatibility; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; + +import org.opendaylight.controller.forwardingrulesmanager.FlowConfig; +import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction; +import org.opendaylight.controller.md.sal.common.api.data.DataModification; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; + +public class FlowCommitTransaction implements DataCommitTransaction, DataObject> { + + private final DataModification, DataObject> modification; + private final HashSet toAdd = new HashSet(); + private final FRMRuntimeDataProvider flowManager; + private Iterable toUpdate; + private Iterable toRemove; + + public FlowCommitTransaction( + final FRMRuntimeDataProvider flowManager, + final DataModification, DataObject> modification) { + this.flowManager = flowManager; + this.modification = modification; + this.processModification(); + } + + @Override + public RpcResult finish() throws IllegalStateException { + return this.flowManager.finish(this); + } + + @Override + public RpcResult rollback() throws IllegalStateException { + return this.flowManager.rollback(this); + } + + public void processModification() { + final Set, DataObject>> updated = + this.modification.getUpdatedConfigurationData().entrySet(); + final List forUpdate = new ArrayList(updated.size()); + + if (updated != null && !(updated.isEmpty())) { + for (Entry, DataObject> entry : updated) { + if (FlowConfigMapping.isFlowPath(entry.getKey())) { + forUpdate.add(FlowConfigMapping.toFlowConfig((Flow) entry.getValue())); + } + } + } + this.toUpdate = Collections.unmodifiableCollection(forUpdate); + + final Set> removedConfigurationData = + this.modification.getRemovedConfigurationData(); + final List forRemove = new ArrayList(removedConfigurationData.size()); + + if (removedConfigurationData != null && !(removedConfigurationData.isEmpty())) { + for (InstanceIdentifier data : removedConfigurationData) { + if (FlowConfigMapping.isFlowPath(data)) { + forRemove.add(FlowConfigMapping.toFlowConfig(data)); + } + } + } + this.toRemove = Collections.unmodifiableCollection(forRemove); + } + + @Override + public DataModification, DataObject> getModification() { + return this.modification; + } + + public FRMRuntimeDataProvider getFlowManager() { + return this.flowManager; + } + + public HashSet getToAdd() { + return this.toAdd; + } + + public Iterable getToUpdate() { + return this.toUpdate; + } + + public Iterable getToRemove() { + return this.toRemove; + } +} diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.java b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.java new file mode 100644 index 0000000000..58c60ec1c5 --- /dev/null +++ b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.java @@ -0,0 +1,109 @@ +/** + * 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.md.frm.compatibility; + +import java.text.MessageFormat; +import java.util.Iterator; + +import org.opendaylight.controller.forwardingrulesmanager.FlowConfig; +import org.opendaylight.controller.sal.compatibility.MDFlowMapping; +import org.opendaylight.controller.sal.compatibility.NodeMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded; +import org.opendaylight.yangtools.yang.binding.Identifiable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FlowConfigMapping { + + private final static Logger LOG = LoggerFactory.getLogger(FlowConfigMapping.class); + + /* nodes/node/flow -> 0 / 1 / 2 */ + private static final int FLOW_KEY_IDENTIFIER_DEEP = 2; + + public static Flow toConfigurationFlow(final FlowConfig sourceCfg) { + final FlowAdded source = MDFlowMapping.flowAdded(sourceCfg.getFlow()); + final FlowBuilder flowBuilder = new FlowBuilder(); + flowBuilder.setInstructions(source.getInstructions()); + flowBuilder.setCookie(source.getCookie()); + flowBuilder.setHardTimeout(source.getHardTimeout()); + flowBuilder.setIdleTimeout(source.getIdleTimeout()); + flowBuilder.setMatch(source.getMatch()); + flowBuilder.setNode(source.getNode()); + + FlowKey flowKey = + new FlowKey(Long.valueOf(sourceCfg.getName()), flowBuilder.getNode()); + flowBuilder.setKey(flowKey); + return flowBuilder.build(); + } + + public static FlowConfig toFlowConfig(final Flow sourceCfg) { + try { + final FlowConfig flowConfig = new FlowConfig(); + flowConfig.setName(String.valueOf(sourceCfg.getId())); + flowConfig.setNode(NodeMapping.toADNode(sourceCfg.getNode())); + return flowConfig; + } catch (Exception e) { + String errMsg = MessageFormat.format("Convert from Flow {} to FlowConfig fail", sourceCfg); + LOG.error(errMsg, e); + throw new RuntimeException(errMsg, e); + } + } + + public static FlowConfig toFlowConfig(final InstanceIdentifier identifier) { + try { + PathArgument pathArg = FlowConfigMapping.getSecondPathArgumentFromPath(identifier); + if (pathArg != null) { + final FlowConfig flowConfig = new FlowConfig(); + FlowKey key = ((IdentifiableItem) pathArg).getKey(); + flowConfig.setName(String.valueOf(key.getId())); + flowConfig.setNode(NodeMapping.toADNode(key.getNode())); + return flowConfig; + } + return null; + } catch (Exception e) { + String errMsg = MessageFormat.format("Convert from InstanceIdentifier {} to FlowConfig fail", identifier); + LOG.error(errMsg, e); + throw new RuntimeException(errMsg, e); + } + } + + public static boolean isFlowPath(final InstanceIdentifier path) { + PathArgument pathArg = FlowConfigMapping.getSecondPathArgumentFromPath(path); + if (pathArg == null) { + return false; + } + if (pathArg instanceof IdentifiableItem) { + final Identifiable key = ((IdentifiableItem>) pathArg).getKey(); + if ((key instanceof FlowKey)) { + return true; + } + } + return false; + } + + private static PathArgument getSecondPathArgumentFromPath(final InstanceIdentifier path) { + if (path != null && path.getPathArguments() != null) { + Iterator iterator = path.getPathArguments().iterator(); + int deep = 0; + while (iterator.hasNext()) { + PathArgument pathArg = iterator.next(); + if (deep == FlowConfigMapping.FLOW_KEY_IDENTIFIER_DEEP) { + return pathArg; + } + deep++; + } + } + return null; + } +} diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend deleted file mode 100644 index e15b3c6c85..0000000000 --- a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowConfigMapping.xtend +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.md.frm.compatibility - -import org.opendaylight.controller.forwardingrulesmanager.FlowConfig -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowBuilder - -import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.* -import static org.opendaylight.controller.sal.compatibility.MDFlowMapping.* -import static org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.* - -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem -import org.opendaylight.yangtools.yang.binding.Identifiable - -class FlowConfigMapping { - - static def toConfigurationFlow(FlowConfig sourceCfg) { - val source = flowAdded(sourceCfg.flow); - val it = new FlowBuilder(); - instructions = source.instructions; - cookie = source.cookie; - hardTimeout = source.hardTimeout - idleTimeout = source.idleTimeout - match = source.match - node = source.node - key = new FlowKey(Long.parseLong(sourceCfg.name),node); - return it.build(); - } - - static def toFlowConfig(Flow sourceCfg) { - val it = new FlowConfig; - name = String.valueOf(sourceCfg.id); - node = sourceCfg.node.toADNode(); - - return it - } - - static def toFlowConfig(InstanceIdentifier identifier) { - val it = new FlowConfig() - val FlowKey key = ((identifier.path.get(2) as IdentifiableItem).key) - name = String.valueOf(key.id); - node = key.node.toADNode(); - - return it; - } - - static def boolean isFlowPath(InstanceIdentifier path) { - if(path.path.size < 2) return false; - if (path.path.get(2) instanceof IdentifiableItem) { - val IdentifiableItem> item = path.path.get(2) as IdentifiableItem>; - val Identifiable key = item.key; - if (key instanceof FlowKey) { - return true; - } - } - return false; - } -} diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java index 017263e264..cb61c8a095 100644 --- a/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java +++ b/opendaylight/md-sal/compatibility/flow-management-compatibility/src/main/java/org/opendaylight/controller/md/frm/compatibility/FlowManagementReader.java @@ -1,4 +1,4 @@ -/* +/** * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.java new file mode 100644 index 0000000000..a35c3ed98c --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.java @@ -0,0 +1,93 @@ +/* + * 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.sal.compatibility.topology; + +import static org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.toAdEdge; +import static org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.toTopoEdgeUpdate; + +import java.util.Map.Entry; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader; +import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; +import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.controller.sal.core.UpdateType; +import org.opendaylight.controller.sal.topology.IPluginOutTopologyService; +import org.opendaylight.controller.sal.topology.TopoEdgeUpdate; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TopologyCommitHandler implements DataChangeListener { + private static final Logger LOG = LoggerFactory.getLogger(TopologyCommitHandler.class); + + private IPluginOutTopologyService topologyPublisher; + + private final DataProviderService dataService; + + public TopologyCommitHandler(final DataProviderService dataService, final IPluginOutTopologyService topologyPub) { + this.topologyPublisher = topologyPub; + this.dataService = dataService; + } + + @Override + public void onDataChanged(final DataChangeEvent, DataObject> modification) { + CopyOnWriteArrayList msg = new CopyOnWriteArrayList(); + try { + TypeSafeDataReader reader = TypeSafeDataReader.forReader(dataService); + InstanceIdentifier topologyPath = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(new TopologyId("flow:1"))).build(); + Topology topology = reader.readOperationalData(topologyPath); + + for (Entry, DataObject> entry : modification + .getCreatedOperationalData().entrySet()) { + if (entry.getValue() instanceof Link + && modification.getCreatedOperationalData().containsKey(entry.getKey())) { + msg.add(toTopoEdgeUpdate(toAdEdge((Link) entry.getValue(), topology), UpdateType.ADDED, reader)); + } + } + + for (Entry, DataObject> entry : modification + .getUpdatedOperationalData().entrySet()) { + if (entry.getValue() instanceof Link) { + msg.add(toTopoEdgeUpdate(toAdEdge((Link) entry.getValue(), topology), UpdateType.CHANGED, reader)); + } + } + for (InstanceIdentifier path : modification.getRemovedOperationalData()) { + if (path.getTargetType() == Link.class) { + Link link = (Link) modification.getOriginalOperationalData().get(path); + msg.add(toTopoEdgeUpdate(toAdEdge(link, topology), UpdateType.CHANGED, reader)); + } + + } + + if (topologyPublisher != null && msg != null && !msg.isEmpty()) { + topologyPublisher.edgeUpdate(msg); + } + + } catch (Exception e) { + LOG.error("Exception caught", e); + } + } + + protected IPluginOutTopologyService getTopologyPublisher() { + return topologyPublisher; + } + + protected void setTopologyPublisher(final IPluginOutTopologyService topologyPublisher) { + this.topologyPublisher = topologyPublisher; + } + +} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend deleted file mode 100644 index fcf86f236a..0000000000 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyCommitHandler.xtend +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.sal.compatibility.topology - -import com.google.common.collect.FluentIterable -import java.util.concurrent.CopyOnWriteArrayList -import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.controller.sal.core.UpdateType -import org.opendaylight.controller.sal.topology.IPluginOutTopologyService -import org.opendaylight.controller.sal.topology.TopoEdgeUpdate -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.* -import org.slf4j.LoggerFactory - -class TopologyCommitHandler implements DataCommitHandler, DataObject> { - static val LOG = LoggerFactory.getLogger(TopologyCommitHandler); - @Property - IPluginOutTopologyService topologyPublisher; - - @Property - DataProviderService dataService; - - new(DataProviderService dataService) { - _topologyPublisher = topologyPublisher - _dataService = dataService - } - - override requestCommit(DataModification, DataObject> modification) { - val msg = new CopyOnWriteArrayList() - try { - val reader = TypeSafeDataReader.forReader(dataService) - val topologyPath = InstanceIdentifier.builder(NetworkTopology).child(Topology, new TopologyKey(new TopologyId("flow:1"))).toInstance - val topology = reader.readOperationalData(topologyPath) - val adds = FluentIterable.from(modification.createdOperationalData.entrySet) - .filter[value instanceof Link] - .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)] - .toList - val updates = FluentIterable.from(modification.updatedOperationalData.entrySet) - .filter[!modification.createdOperationalData.containsKey(key) && (value instanceof Link)] - .transform[(value as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.ADDED,reader)] // Evidently the ADSAL does not expect edge 'CHANGED" - .toList - val removes = FluentIterable.from(modification.removedOperationalData) - .transform[reader.readOperationalData(it as InstanceIdentifier)] - .filter[it instanceof Link] - .transform[(it as Link).toAdEdge(topology).toTopoEdgeUpdate(UpdateType.REMOVED,reader)] - .toList - msg.addAll(adds) - msg.addAll(updates) - msg.addAll(removes) - } catch (Exception e) { - LOG.error("Exception caught",e) - } - return new TopologyTransaction(modification,topologyPublisher,dataService,msg) - } -} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend index 4aef75d991..21f2b35f40 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend @@ -15,10 +15,10 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey import org.opendaylight.yangtools.yang.binding.DataObject import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yangtools.concepts.Registration -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link import org.slf4j.LoggerFactory +import org.opendaylight.yangtools.concepts.ListenerRegistration +import org.opendaylight.controller.sal.binding.api.data.DataChangeListener class TopologyProvider implements AutoCloseable{ static val LOG = LoggerFactory.getLogger(TopologyProvider); @@ -30,8 +30,9 @@ class TopologyProvider implements AutoCloseable{ @Property DataProviderService dataService; - Registration,DataObject>> commitHandlerRegistration; - + ListenerRegistration listenerRegistration + + def void start() { } @@ -40,18 +41,17 @@ class TopologyProvider implements AutoCloseable{ LOG.error("dataService not set"); return; } - commitHandler = new TopologyCommitHandler(dataService) - commitHandler.setTopologyPublisher(topologyPublisher) + commitHandler = new TopologyCommitHandler(dataService,topologyPublisher); val InstanceIdentifier path = InstanceIdentifier.builder(NetworkTopology) .child(Topology,new TopologyKey(new TopologyId("flow:1"))) .child(Link) .toInstance(); - commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler); + listenerRegistration = dataService.registerDataChangeListener(path,commitHandler); LOG.info("TopologyProvider started") } override close() throws Exception { - commitHandlerRegistration.close + listenerRegistration.close } def setTopologyPublisher(IPluginOutTopologyService topologyPublisher) { diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend deleted file mode 100644 index 4de78cab0d..0000000000 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyTransaction.xtend +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.sal.compatibility.topology - -import java.util.Collections -import java.util.List -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.controller.sal.topology.IPluginOutTopologyService -import org.opendaylight.controller.sal.topology.TopoEdgeUpdate -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yangtools.yang.common.RpcResult -import org.slf4j.LoggerFactory - -class TopologyTransaction implements DataCommitTransaction, DataObject> { - static val LOG = LoggerFactory.getLogger(TopologyTransaction); - @Property - val DataModification, DataObject> modification; - - @Property - IPluginOutTopologyService topologyPublisher; - - @Property - DataProviderService dataService; - @Property - List edgeUpdates; - - new(DataModification, DataObject> modification,IPluginOutTopologyService topologyPublisher, - DataProviderService dataService,List edgeUpdates) { - _modification = modification; - _topologyPublisher = topologyPublisher - _dataService = dataService - _edgeUpdates = edgeUpdates - } - override finish() throws IllegalStateException { - - if(topologyPublisher != null && _edgeUpdates != null && !edgeUpdates.empty) { - topologyPublisher.edgeUpdate(edgeUpdates) - } - - return new RpcResultTo() - } - - override getModification() { - return _modification; - } - - override rollback() throws IllegalStateException { - // NOOP - } -} -class RpcResultTo implements RpcResult { - - override getErrors() { - return Collections.emptySet - } - - override getResult() { - return null; - } - - override isSuccessful() { - return true; - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/pom.xml b/opendaylight/md-sal/forwardingrules-manager/pom.xml index 919a53c364..9bd63d3c3b 100644 --- a/opendaylight/md-sal/forwardingrules-manager/pom.xml +++ b/opendaylight/md-sal/forwardingrules-manager/pom.xml @@ -54,10 +54,6 @@ - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java new file mode 100644 index 0000000000..426f4ba2d5 --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractChangeListener.java @@ -0,0 +1,94 @@ +/** + * 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.frm; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicLong; + +import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; +import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * + * @author Vaclav Demcak + * + */ +public abstract class AbstractChangeListener implements DataChangeListener { + + private final AtomicLong txNum = new AtomicLong(); + private String transactionId; + + @Override + public void onDataChanged(DataChangeEvent, DataObject> changeEvent) { + this.transactionId = this.newTransactionIdentifier().toString(); + + final Set, DataObject>> createdEntries = + changeEvent.getCreatedConfigurationData().entrySet(); + final Set, DataObject>> updatedEntries = + new HashSet, DataObject>>(); + + Set, DataObject>> updateConfigEntrySet = + changeEvent.getUpdatedConfigurationData().entrySet(); + updatedEntries.addAll(updateConfigEntrySet); + updatedEntries.removeAll(createdEntries); + + final Set> removeEntriesInstanceIdentifiers = + changeEvent.getRemovedConfigurationData(); + + for (final Entry, DataObject> createdEntry : createdEntries) { + InstanceIdentifier c_key = createdEntry.getKey(); + DataObject c_value = createdEntry.getValue(); + this.add(c_key, c_value); + } + + for (final Entry, DataObject> updatedEntrie : updatedEntries) { + Map, DataObject> origConfigData = + changeEvent.getOriginalConfigurationData(); + + InstanceIdentifier u_key = updatedEntrie.getKey(); + final DataObject originalFlow = origConfigData.get(u_key); + final DataObject updatedFlow = updatedEntrie.getValue(); + this.update(u_key, originalFlow, updatedFlow); + } + + for (final InstanceIdentifier instanceId : removeEntriesInstanceIdentifiers) { + Map, DataObject> origConfigData = + changeEvent.getOriginalConfigurationData(); + + final DataObject removeValue = origConfigData.get(instanceId); + this.remove(instanceId, removeValue); + } + } + + public String getTransactionId() { + return this.transactionId; + } + + private Object newTransactionIdentifier() { + return "DOM-" + txNum.getAndIncrement(); + } + + protected abstract void validate() throws IllegalStateException; + + protected abstract void remove( + final InstanceIdentifier identifier, + final DataObject remove); + + protected abstract void update( + final InstanceIdentifier identifier, + final DataObject original, final DataObject update); + + protected abstract void add( + final InstanceIdentifier identifier, + final DataObject add); +} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend deleted file mode 100644 index cb1e90d6ba..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/AbstractTransaction.xtend +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.frm - -import java.util.Collections -import java.util.HashSet -import java.util.Map.Entry -import java.util.Set -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.controller.sal.common.util.Rpcs -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yangtools.yang.common.RpcError - -abstract class AbstractTransaction implements DataCommitTransaction, DataObject> { - - @Property - val DataModification, DataObject> modification; - - new(DataModification, DataObject> modification) { - _modification = modification; - } - - def void validate() throws IllegalStateException - - override finish() throws IllegalStateException { - validate() - callRpcs(); - return Rpcs.getRpcResult(true, null, Collections.emptySet()); - } - - override getModification() { - return _modification; - } - - override rollback() throws IllegalStateException { - rollbackRpcs(); - return Rpcs.getRpcResult(true, null, Collections.emptySet()); - } - - def private callRpcs() { - val Set, DataObject>> createdEntries = _modification.getCreatedConfigurationData().entrySet(); - - /* - * This little dance is because updatedEntries contains both created and modified entries - * The reason I created a new HashSet is because the collections we are returned are immutable. - */ - val Set, DataObject>> updatedEntries = new HashSet, DataObject>>(); - updatedEntries.addAll(_modification.getUpdatedConfigurationData().entrySet()); - updatedEntries.removeAll(createdEntries); - - val Set> removeEntriesInstanceIdentifiers = _modification.getRemovedConfigurationData(); - for (Entry, DataObject> entry : createdEntries) { - add(entry.key,entry.value); - } - for (Entry, DataObject> entry : updatedEntries) { - val originalFlow = _modification.originalConfigurationData.get(entry.key); - val updatedFlow = entry.value - update(entry.key, originalFlow ,updatedFlow); - } - - for (InstanceIdentifier instanceId : removeEntriesInstanceIdentifiers ) { - val removeValue = _modification.getOriginalConfigurationData.get(instanceId); - remove(instanceId,removeValue); - } - } - - def void remove(InstanceIdentifier identifier, DataObject remove) - - def void update(InstanceIdentifier identifier, DataObject original, DataObject update) - - def void add(InstanceIdentifier identifier, DataObject add) - - def private rollbackRpcs() { - val Set, DataObject>> createdEntries = _modification.getCreatedConfigurationData().entrySet(); - - /* - * This little dance is because updatedEntries contains both created and modified entries - * The reason I created a new HashSet is because the collections we are returned are immutable. - */ - val Set, DataObject>> updatedEntries = new HashSet, DataObject>>(); - updatedEntries.addAll(_modification.getUpdatedConfigurationData().entrySet()); - updatedEntries.removeAll(createdEntries); - - val Set> removeEntriesInstanceIdentifiers = _modification.getRemovedConfigurationData(); - for (Entry, DataObject> entry : createdEntries) { - remove(entry.key,entry.value); // because we are rolling back, remove what we would have added. - } - for (Entry, DataObject> entry : updatedEntries) { - val originalFlow = _modification.originalConfigurationData.get(entry.key); - val updatedFlow = entry.value - update(entry.key, updatedFlow ,originalFlow);// because we are rolling back, replace the updated with the original - } - - for (InstanceIdentifier instanceId : removeEntriesInstanceIdentifiers ) { - val removeValue = _modification.getOriginalConfigurationData.get(instanceId); - add(instanceId,removeValue);// because we are rolling back, add what we would have removed. - } - } -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java new file mode 100644 index 0000000000..929c489eaf --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.java @@ -0,0 +1,61 @@ +/** + * 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.frm; + +import org.opendaylight.controller.frm.flow.FlowProvider; +import org.opendaylight.controller.frm.group.GroupProvider; +import org.opendaylight.controller.frm.meter.MeterProvider; +import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FRMActivator extends AbstractBindingAwareProvider { + + private final static Logger LOG = LoggerFactory.getLogger(FRMActivator.class); + + private static FlowProvider flowProvider = new FlowProvider(); + private static GroupProvider groupProvider = new GroupProvider(); + private static MeterProvider meterProvider = new MeterProvider(); + + @Override + public void onSessionInitiated(final ProviderContext session) { + DataProviderService flowSalService = session.getSALService(DataProviderService.class); + FRMActivator.flowProvider.setDataService(flowSalService); + SalFlowService rpcFlowSalService = session.getRpcService(SalFlowService.class); + FRMActivator.flowProvider.setSalFlowService(rpcFlowSalService); + FRMActivator.flowProvider.start(); + DataProviderService groupSalService = session.getSALService(DataProviderService.class); + FRMActivator.groupProvider.setDataService(groupSalService); + SalGroupService rpcGroupSalService = session.getRpcService(SalGroupService.class); + FRMActivator.groupProvider.setSalGroupService(rpcGroupSalService); + FRMActivator.groupProvider.start(); + DataProviderService meterSalService = session.getSALService(DataProviderService.class); + FRMActivator.meterProvider.setDataService(meterSalService); + SalMeterService rpcMeterSalService = session.getRpcService(SalMeterService.class); + FRMActivator.meterProvider.setSalMeterService(rpcMeterSalService); + FRMActivator.meterProvider.start(); + } + + @Override + protected void stopImpl(final BundleContext context) { + try { + FRMActivator.flowProvider.close(); + FRMActivator.groupProvider.close(); + FRMActivator.meterProvider.close(); + } catch (Throwable e) { + LOG.error("Unexpected error by stopping FRMActivator", e); + throw new RuntimeException(e); + } + } + } \ No newline at end of file diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend deleted file mode 100644 index 8ec9d79bfc..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/FRMActivator.xtend +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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.frm - -import org.opendaylight.controller.frm.flow.FlowProvider -import org.opendaylight.controller.frm.group.GroupProvider -import org.opendaylight.controller.frm.meter.MeterProvider -import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService -import org.osgi.framework.BundleContext -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService - -class FRMActivator extends AbstractBindingAwareProvider { - - static var FlowProvider provider = new FlowProvider(); - static var GroupProvider groupProvider = new GroupProvider(); - static var MeterProvider meterProvider = new MeterProvider(); - - override onSessionInitiated(ProviderContext session) { - provider.dataService = session.getSALService(DataProviderService) - provider.salFlowService = session.getRpcService(SalFlowService); - provider.start(); - - groupProvider.dataService = session.getSALService(DataProviderService) - groupProvider.salGroupService = session.getRpcService(SalGroupService) - groupProvider.start(); - - meterProvider.dataService = session.getSALService(DataProviderService) - meterProvider.salMeterService = session.getRpcService(SalMeterService) - meterProvider.start(); - } - - override protected stopImpl(BundleContext context) { - provider.close(); - groupProvider.close(); - meterProvider.close(); - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java new file mode 100644 index 0000000000..df086c7acc --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowChangeListener.java @@ -0,0 +1,120 @@ +/** + * 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.frm.flow; + +import org.opendaylight.controller.frm.AbstractChangeListener; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Vaclav Demcak + * + */ +public class FlowChangeListener extends AbstractChangeListener { + + private final static Logger LOG = LoggerFactory.getLogger(FlowChangeListener.class); + + private final SalFlowService salFlowService; + + public SalFlowService getSalFlowService() { + return this.salFlowService; + } + + public FlowChangeListener(final SalFlowService manager) { + this.salFlowService = manager; + } + + @Override + protected void validate() throws IllegalStateException { + FlowTransactionValidator.validate(this); + } + + @Override + protected void remove(InstanceIdentifier identifier, DataObject removeDataObj) { + if ((removeDataObj instanceof Flow)) { + + final Flow flow = ((Flow) removeDataObj); + final InstanceIdentifier tableInstanceId = identifier.
firstIdentifierOf(Table.class); + final InstanceIdentifier nodeInstanceId = identifier. firstIdentifierOf(Node.class); + final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(flow); + + builder.setFlowRef(new FlowRef(identifier)); + builder.setNode(new NodeRef(nodeInstanceId)); + builder.setFlowTable(new FlowTableRef(tableInstanceId)); + + Uri uri = new Uri(this.getTransactionId()); + builder.setTransactionUri(uri); + this.salFlowService.removeFlow((RemoveFlowInput) builder.build()); + LOG.debug("Transaction {} - Removed Flow has removed flow: {}", new Object[]{uri, removeDataObj}); + } + } + + @Override + protected void update(InstanceIdentifier identifier, DataObject original, DataObject update) { + if (original instanceof Flow && update instanceof Flow) { + + final Flow originalFlow = ((Flow) original); + final Flow updatedFlow = ((Flow) update); + final InstanceIdentifier nodeInstanceId = identifier.firstIdentifierOf(Node.class); + final UpdateFlowInputBuilder builder = new UpdateFlowInputBuilder(); + + builder.setNode(new NodeRef(nodeInstanceId)); + builder.setFlowRef(new FlowRef(identifier)); + + Uri uri = new Uri(this.getTransactionId()); + builder.setTransactionUri(uri); + + builder.setUpdatedFlow((UpdatedFlow) (new UpdatedFlowBuilder(updatedFlow)).build()); + builder.setOriginalFlow((OriginalFlow) (new OriginalFlowBuilder(originalFlow)).build()); + + this.salFlowService.updateFlow((UpdateFlowInput) builder.build()); + LOG.debug("Transaction {} - Update Flow has updated flow {} with {}", new Object[]{uri, original, update}); + } + } + + @Override + protected void add(InstanceIdentifier identifier, DataObject addDataObj) { + if ((addDataObj instanceof Flow)) { + + final Flow flow = ((Flow) addDataObj); + final InstanceIdentifier
tableInstanceId = identifier.
firstIdentifierOf(Table.class); + final InstanceIdentifier nodeInstanceId = identifier. firstIdentifierOf(Node.class); + final AddFlowInputBuilder builder = new AddFlowInputBuilder(flow); + + builder.setNode(new NodeRef(nodeInstanceId)); + builder.setFlowRef(new FlowRef(identifier)); + builder.setFlowTable(new FlowTableRef(tableInstanceId)); + + Uri uri = new Uri(this.getTransactionId()); + builder.setTransactionUri(uri); + this.salFlowService.addFlow((AddFlowInput) builder.build()); + LOG.debug("Transaction {} - Add Flow has added flow: {}", new Object[]{uri, addDataObj}); + } + } +} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend deleted file mode 100644 index 188bfcd3ef..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowCommitHandler.xtend +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.frm.flow - -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService - -class FlowCommitHandler implements DataCommitHandler, DataObject> { - - @Property - val SalFlowService salFlowService; - - new(SalFlowService manager) { - _salFlowService = manager; - } - - override requestCommit(DataModification, DataObject> modification) { - return new FlowTransaction(modification,salFlowService); - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java new file mode 100644 index 0000000000..afdd628bbb --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.java @@ -0,0 +1,70 @@ +/** + * 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.frm.flow; + +import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FlowProvider implements AutoCloseable { + + private final static Logger LOG = LoggerFactory.getLogger(FlowProvider.class); + + private SalFlowService salFlowService; + private DataProviderService dataService; + + /* DataChangeListener */ + private FlowChangeListener flowDataChangeListener; + ListenerRegistration flowDataChangeListenerRegistration; + + public void start() { + /* Build Path */ + InstanceIdentifierBuilder nodesBuilder = InstanceIdentifier. builder(Nodes.class); + InstanceIdentifierBuilder nodeChild = nodesBuilder. child(Node.class); + InstanceIdentifierBuilder augmentFlowCapNode = nodeChild. augmentation(FlowCapableNode.class); + InstanceIdentifierBuilder
tableChild = augmentFlowCapNode.
child(Table.class); + InstanceIdentifierBuilder flowChild = tableChild. child(Flow.class); + final InstanceIdentifier flowDataObjectPath = flowChild.toInstance(); + + /* DataChangeListener registration */ + this.flowDataChangeListener = new FlowChangeListener(this.salFlowService); + this.flowDataChangeListenerRegistration = this.dataService.registerDataChangeListener(flowDataObjectPath, flowDataChangeListener); + LOG.info("Flow Config Provider started."); + } + + protected DataModificationTransaction startChange() { + return this.dataService.beginTransaction(); + } + + @Override + public void close() throws Exception { + if(flowDataChangeListenerRegistration != null){ + flowDataChangeListenerRegistration.close(); + } + } + + public void setDataService(final DataProviderService dataService) { + this.dataService = dataService; + } + + public void setSalFlowService(final SalFlowService salFlowService) { + this.salFlowService = salFlowService; + } +} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend deleted file mode 100644 index d2ed5410ed..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowProvider.xtend +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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.frm.flow - -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node -import org.opendaylight.yangtools.concepts.Registration -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.slf4j.LoggerFactory - -class FlowProvider implements AutoCloseable { - - @Property - DataProviderService dataService; - - @Property - SalFlowService salFlowService; - - FlowCommitHandler commitHandler - - Registration,DataObject>> commitHandlerRegistration; - - static val LOG = LoggerFactory.getLogger(FlowProvider); - - def void start() { - commitHandler = new FlowCommitHandler(salFlowService) - val InstanceIdentifier path = InstanceIdentifier.builder(Nodes) - .child(Node) - .augmentation(FlowCapableNode) - .child(Table) - .child(Flow) - .toInstance(); - commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler); - LOG.info("Flow Config Provider started."); - } - - protected def startChange() { - return dataService.beginTransaction; - } - - override close() throws Exception { - throw new UnsupportedOperationException("TODO: auto-generated method stub") - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend deleted file mode 100644 index 26846ad493..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransaction.xtend +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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.frm.flow - -import org.opendaylight.controller.frm.AbstractTransaction -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri - -class FlowTransaction extends AbstractTransaction { - - @Property - val SalFlowService salFlowService; - - - new(DataModification, DataObject> modification,SalFlowService salFlowService) { - super(modification) - _salFlowService = salFlowService; - } - - override remove(InstanceIdentifier instanceId, DataObject obj) { - if(obj instanceof Flow) { - val flow = (obj as Flow) - val tableInstanceId = instanceId.firstIdentifierOf(Table); - val nodeInstanceId = instanceId.firstIdentifierOf(Node); - val builder = new RemoveFlowInputBuilder(flow); - builder.setFlowRef(new FlowRef(instanceId)); - builder.setNode(new NodeRef(nodeInstanceId)); - builder.setFlowTable(new FlowTableRef(tableInstanceId)); - builder.setTransactionUri(new Uri(modification.getIdentifier() as String)); - _salFlowService.removeFlow(builder.build()); - } - } - - override update(InstanceIdentifier instanceId, DataObject originalObj, DataObject updatedObj) { - if(originalObj instanceof Flow && updatedObj instanceof Flow) { - val originalFlow = (originalObj as Flow) - val updatedFlow = (updatedObj as Flow) - val nodeInstanceId = instanceId.firstIdentifierOf(Node); - val builder = new UpdateFlowInputBuilder(); - builder.setNode(new NodeRef(nodeInstanceId)); - builder.setFlowRef(new FlowRef(instanceId)); - val ufb = new UpdatedFlowBuilder(updatedFlow); - builder.setUpdatedFlow((ufb.build())); - builder.setTransactionUri(new Uri(modification.getIdentifier() as String)); - val ofb = new OriginalFlowBuilder(originalFlow); - builder.setOriginalFlow(ofb.build()); - _salFlowService.updateFlow(builder.build()); - - } - } - - override add(InstanceIdentifier instanceId, DataObject obj) { - if(obj instanceof Flow) { - val flow = (obj as Flow) - val tableInstanceId = instanceId.firstIdentifierOf(Table); - val nodeInstanceId = instanceId.firstIdentifierOf(Node); - val builder = new AddFlowInputBuilder(flow); - builder.setNode(new NodeRef(nodeInstanceId)); - builder.setTransactionUri(new Uri(modification.getIdentifier() as String)); - builder.setFlowRef(new FlowRef(instanceId)); - builder.setFlowTable(new FlowTableRef(tableInstanceId)); - _salFlowService.addFlow(builder.build()); - } - } - - override validate() throws IllegalStateException { - FlowTransactionValidator.validate(this) - } -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransactionValidator.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransactionValidator.java index 7c6f1ff1cb..4ef93a55e9 100644 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransactionValidator.java +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/flow/FlowTransactionValidator.java @@ -1,6 +1,6 @@ -/* +/** * 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 @@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.flow; public class FlowTransactionValidator { - public static void validate(FlowTransaction transaction) throws IllegalStateException { + public static void validate(FlowChangeListener transaction) throws IllegalStateException { // NOOP } - } diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java new file mode 100644 index 0000000000..1260f0ec53 --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupChangeListener.java @@ -0,0 +1,113 @@ +/** + * 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.frm.group; + +import org.opendaylight.controller.frm.AbstractChangeListener; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroup; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroup; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Vaclav Demcak + * + */ +public class GroupChangeListener extends AbstractChangeListener { + + private final static Logger LOG = LoggerFactory.getLogger(GroupChangeListener.class); + + private final SalGroupService salGroupService; + + public SalGroupService getSalGroupService() { + return this.salGroupService; + } + + public GroupChangeListener(final SalGroupService manager) { + this.salGroupService = manager; + } + + @Override + protected void validate() throws IllegalStateException { + GroupTransactionValidator.validate(this); + } + + @Override + protected void remove(InstanceIdentifier identifier, DataObject removeDataObj) { + if ((removeDataObj instanceof Group)) { + + final Group group = ((Group) removeDataObj); + final InstanceIdentifier nodeInstanceId = identifier. firstIdentifierOf(Node.class); + final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group); + + builder.setNode(new NodeRef(nodeInstanceId)); + builder.setGroupRef(new GroupRef(identifier)); + + Uri uri = new Uri(this.getTransactionId()); + builder.setTransactionUri(uri); + this.salGroupService.removeGroup((RemoveGroupInput) builder.build()); + LOG.debug("Transaction {} - Remove Group has removed group: {}", new Object[]{uri, removeDataObj}); + } + } + + @Override + protected void update(InstanceIdentifier identifier, DataObject original, DataObject update) { + if (original instanceof Group && update instanceof Group) { + + final Group originalGroup = ((Group) original); + final Group updatedGroup = ((Group) update); + final InstanceIdentifier nodeInstanceId = identifier. firstIdentifierOf(Node.class); + final UpdateGroupInputBuilder builder = new UpdateGroupInputBuilder(); + + builder.setNode(new NodeRef(nodeInstanceId)); + builder.setGroupRef(new GroupRef(identifier)); + + Uri uri = new Uri(this.getTransactionId()); + builder.setTransactionUri(uri); + + builder.setUpdatedGroup((UpdatedGroup) (new UpdatedGroupBuilder(updatedGroup)).build()); + builder.setOriginalGroup((OriginalGroup) (new OriginalGroupBuilder(originalGroup)).build()); + + this.salGroupService.updateGroup((UpdateGroupInput) builder.build()); + LOG.debug("Transaction {} - Update Group has updated group {} with group {}", new Object[]{uri, original, update}); + } + } + + @Override + protected void add(InstanceIdentifier identifier, DataObject addDataObj) { + if ((addDataObj instanceof Group)) { + final Group group = ((Group) addDataObj); + final InstanceIdentifier nodeInstanceId = identifier. firstIdentifierOf(Node.class); + final AddGroupInputBuilder builder = new AddGroupInputBuilder(group); + + builder.setNode(new NodeRef(nodeInstanceId)); + builder.setGroupRef(new GroupRef(identifier)); + + Uri uri = new Uri(this.getTransactionId()); + builder.setTransactionUri(uri); + this.salGroupService.addGroup((AddGroupInput) builder.build()); + LOG.debug("Transaction {} - Add Group has added group: {}", new Object[]{uri, addDataObj}); + } + } +} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend deleted file mode 100644 index b6d385126f..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupCommitHandler.xtend +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.frm.group - -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier - -class GroupCommitHandler implements DataCommitHandler, DataObject> { - - @Property - val SalGroupService groupService; - - new(SalGroupService groupService) { - _groupService = groupService; - } - - override requestCommit(DataModification, DataObject> modification) { - return new GroupTransaction(modification,groupService); - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java new file mode 100644 index 0000000000..14b1b6f2fd --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.java @@ -0,0 +1,67 @@ +/** + * 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.frm.group; + +import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GroupProvider implements AutoCloseable { + + private final static Logger LOG = LoggerFactory.getLogger(GroupProvider.class); + + private SalGroupService salGroupService; + private DataProviderService dataService; + + /* DataChangeListener */ + private GroupChangeListener groupDataChangeListener; + ListenerRegistration groupDataChangeListenerRegistration; + + public void start() { + /* Build Path */ + InstanceIdentifierBuilder nodesBuilder = InstanceIdentifier. builder(Nodes.class); + InstanceIdentifierBuilder nodeChild = nodesBuilder. child(Node.class); + InstanceIdentifierBuilder augmentFlowCapNode = nodeChild. augmentation(FlowCapableNode.class); + InstanceIdentifierBuilder groupChild = augmentFlowCapNode. child(Group.class); + final InstanceIdentifier groupDataObjectPath = groupChild.toInstance(); + + /* DataChangeListener registration */ + this.groupDataChangeListener = new GroupChangeListener(this.salGroupService); + this.groupDataChangeListenerRegistration = this.dataService.registerDataChangeListener(groupDataObjectPath, groupDataChangeListener); + LOG.info("Group Config Provider started."); + } + + protected DataModificationTransaction startChange() { + return this.dataService.beginTransaction(); + } + + public void close() throws Exception { + if(groupDataChangeListenerRegistration != null){ + groupDataChangeListenerRegistration.close(); + } + } + + public void setDataService(final DataProviderService dataService) { + this.dataService = dataService; + } + + public void setSalGroupService(final SalGroupService salGroupService) { + this.salGroupService = salGroupService; + } +} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend deleted file mode 100644 index 4ded8b6151..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupProvider.xtend +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.frm.group - -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node -import org.opendaylight.yangtools.concepts.Registration -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.slf4j.LoggerFactory - -class GroupProvider implements AutoCloseable { - - @Property - DataProviderService dataService; - - @Property - SalGroupService salGroupService; - - GroupCommitHandler commitHandler - - Registration,DataObject>> commitHandlerRegistration; - - static val LOG = LoggerFactory.getLogger(GroupProvider); - - def void start() { - commitHandler = new GroupCommitHandler(salGroupService) - val InstanceIdentifier path = InstanceIdentifier.builder(Nodes) - .child(Node) - .augmentation(FlowCapableNode) - .child(Group) - .toInstance(); - commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler); - LOG.info("Group Config Provider started."); - } - - protected def startChange() { - return dataService.beginTransaction; - } - - override close() throws Exception { - throw new UnsupportedOperationException("TODO: auto-generated method stub") - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend deleted file mode 100644 index e8d9982bdc..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransaction.xtend +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.frm.group - -import org.opendaylight.controller.frm.AbstractTransaction -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef -import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri - -class GroupTransaction extends AbstractTransaction { - - @Property - val SalGroupService groupService; - - new(DataModification, DataObject> modification,SalGroupService groupService) { - super(modification) - _groupService = groupService; - } - - override remove(InstanceIdentifier instanceId, DataObject obj) { - if(obj instanceof Group) { - val group = (obj as Group) - val nodeInstanceId = instanceId.firstIdentifierOf(Node); - val builder = new RemoveGroupInputBuilder(group); - builder.setNode(new NodeRef(nodeInstanceId)); - builder.setTransactionUri(new Uri(modification.getIdentifier() as String)); - builder.setGroupRef(new GroupRef(instanceId)); - _groupService.removeGroup(builder.build()); - } - } - - override update(InstanceIdentifier instanceId, DataObject originalObj, DataObject updatedObj) { - if(originalObj instanceof Group && updatedObj instanceof Group) { - val originalGroup = (originalObj as Group) - val updatedGroup = (updatedObj as Group) - val nodeInstanceId = instanceId.firstIdentifierOf(Node); - val builder = new UpdateGroupInputBuilder(); - builder.setNode(new NodeRef(nodeInstanceId)); - builder.setGroupRef(new GroupRef(instanceId)); - val ufb = new UpdatedGroupBuilder(updatedGroup); - builder.setUpdatedGroup((ufb.build())); - builder.setTransactionUri(new Uri(modification.getIdentifier() as String)); - val ofb = new OriginalGroupBuilder(originalGroup); - builder.setOriginalGroup(ofb.build()); - _groupService.updateGroup(builder.build()); - - } - } - - override add(InstanceIdentifier instanceId, DataObject obj) { - if(obj instanceof Group) { - val group = (obj as Group) - val nodeInstanceId = instanceId.firstIdentifierOf(Node); - val builder = new AddGroupInputBuilder(group); - builder.setNode(new NodeRef(nodeInstanceId)); - builder.setGroupRef(new GroupRef(instanceId)); - builder.setTransactionUri(new Uri(modification.getIdentifier() as String)); - _groupService.addGroup(builder.build()); - } - } - - override validate() throws IllegalStateException { - GroupTransactionValidator.validate(this) - } -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransactionValidator.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransactionValidator.java index 92baf7bdf0..88eea0db34 100644 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransactionValidator.java +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/group/GroupTransactionValidator.java @@ -1,4 +1,4 @@ -/* +/** * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.group; public class GroupTransactionValidator { - public static void validate(GroupTransaction transaction) throws IllegalStateException { + public static void validate(GroupChangeListener transaction) throws IllegalStateException { // NOOP } - } diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java new file mode 100644 index 0000000000..839e556fbc --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterChangeListener.java @@ -0,0 +1,114 @@ +/** + * 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.frm.meter; + +import org.opendaylight.controller.frm.AbstractChangeListener; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author Vaclav Demcak + * + */ +public class MeterChangeListener extends AbstractChangeListener { + + private final static Logger LOG = LoggerFactory.getLogger(MeterChangeListener.class); + + private final SalMeterService salMeterService; + + public SalMeterService getSalMeterService() { + return this.salMeterService; + } + + public MeterChangeListener(final SalMeterService manager) { + this.salMeterService = manager; + } + + @Override + protected void validate() throws IllegalStateException { + MeterTransactionValidator.validate(this); + } + + @Override + protected void remove(InstanceIdentifier identifier, DataObject removeDataObj) { + if ((removeDataObj instanceof Meter)) { + + final Meter meter = ((Meter) removeDataObj); + final InstanceIdentifier nodeInstanceId = identifier. firstIdentifierOf(Node.class); + final RemoveMeterInputBuilder builder = new RemoveMeterInputBuilder(meter); + + builder.setNode(new NodeRef(nodeInstanceId)); + builder.setMeterRef(new MeterRef(identifier)); + + Uri uri = new Uri(this.getTransactionId()); + builder.setTransactionUri(uri); + this.salMeterService.removeMeter((RemoveMeterInput) builder.build()); + LOG.debug("Transaction {} - Remove Meter has removed meter: {}", new Object[]{uri, removeDataObj}); + } + } + + @Override + protected void update(InstanceIdentifier identifier, DataObject original, DataObject update) { + if (original instanceof Meter && update instanceof Meter) { + + final Meter originalMeter = ((Meter) original); + final Meter updatedMeter = ((Meter) update); + final InstanceIdentifier nodeInstanceId = identifier. firstIdentifierOf(Node.class); + final UpdateMeterInputBuilder builder = new UpdateMeterInputBuilder(); + + builder.setNode(new NodeRef(nodeInstanceId)); + builder.setMeterRef(new MeterRef(identifier)); + + Uri uri = new Uri(this.getTransactionId()); + builder.setTransactionUri(uri); + + builder.setUpdatedMeter((UpdatedMeter) (new UpdatedMeterBuilder(updatedMeter)).build()); + builder.setOriginalMeter((OriginalMeter) (new OriginalMeterBuilder(originalMeter)).build()); + + this.salMeterService.updateMeter((UpdateMeterInput) builder.build()); + LOG.debug("Transaction {} - Update Meter has updated meter {} with {}", new Object[]{uri, original, update}); + } + } + + @Override + protected void add(InstanceIdentifier identifier, DataObject addDataObj) { + if ((addDataObj instanceof Meter)) { + + final Meter meter = ((Meter) addDataObj); + final InstanceIdentifier nodeInstanceId = identifier. firstIdentifierOf(Node.class); + final AddMeterInputBuilder builder = new AddMeterInputBuilder(meter); + + builder.setNode(new NodeRef(nodeInstanceId)); + builder.setMeterRef(new MeterRef(identifier)); + + Uri uri = new Uri(this.getTransactionId()); + builder.setTransactionUri(uri); + this.salMeterService.addMeter((AddMeterInput) builder.build()); + LOG.debug("Transaction {} - Add Meter has added meter: {}", new Object[]{uri, addDataObj}); + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend deleted file mode 100644 index d5292f0f8b..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterCommitHandler.xtend +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.frm.meter - -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier - -class FlowCommitHandler implements DataCommitHandler, DataObject> { - - @Property - val SalMeterService salMeterService; - - new(SalMeterService manager) { - _salMeterService = manager; - } - - override requestCommit(DataModification, DataObject> modification) { - return new MeterTransaction(modification,salMeterService); - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java new file mode 100644 index 0000000000..620801fba5 --- /dev/null +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.java @@ -0,0 +1,67 @@ +/** + * 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.frm.meter; + +import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MeterProvider implements AutoCloseable { + + private final static Logger LOG = LoggerFactory.getLogger(MeterProvider.class); + + private DataProviderService dataService; + private SalMeterService salMeterService; + + /* DataChangeListener */ + private MeterChangeListener meterDataChangeListener; + ListenerRegistration meterDataChangeListenerRegistration; + + public void start() { + /* Build Path */ + InstanceIdentifierBuilder nodesBuilder = InstanceIdentifier. builder(Nodes.class); + InstanceIdentifierBuilder nodeChild = nodesBuilder. child(Node.class); + InstanceIdentifierBuilder augmentFlowCapNode = nodeChild. augmentation(FlowCapableNode.class); + InstanceIdentifierBuilder meterChild = augmentFlowCapNode. child(Meter.class); + final InstanceIdentifier meterDataObjectPath = meterChild.toInstance(); + + /* DataChangeListener registration */ + this.meterDataChangeListener = new MeterChangeListener(this.salMeterService); + this.meterDataChangeListenerRegistration = this.dataService.registerDataChangeListener(meterDataObjectPath, meterDataChangeListener); + LOG.info("Meter Config Provider started."); + } + + protected DataModificationTransaction startChange() { + return this.dataService.beginTransaction(); + } + + public void close() throws Exception { + if(meterDataChangeListenerRegistration != null){ + meterDataChangeListenerRegistration.close(); + } + } + + public void setDataService(final DataProviderService dataService) { + this.dataService = dataService; + } + + public void setSalMeterService(final SalMeterService salMeterService) { + this.salMeterService = salMeterService; + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend deleted file mode 100644 index 323da57075..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterProvider.xtend +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.frm.meter - -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService -import org.opendaylight.yangtools.concepts.Registration -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.slf4j.LoggerFactory - -class MeterProvider implements AutoCloseable { - - @Property - DataProviderService dataService; - - @Property - SalMeterService salMeterService; - - FlowCommitHandler commitHandler - - Registration,DataObject>> commitHandlerRegistration; - - static val LOG = LoggerFactory.getLogger(MeterProvider); - - def void start() { - commitHandler = new FlowCommitHandler(salMeterService) - val InstanceIdentifier path = InstanceIdentifier.builder(Nodes) - .child(Node) - .augmentation(FlowCapableNode) - .child(Meter) - .toInstance(); - commitHandlerRegistration = dataService.registerCommitHandler(path,commitHandler); - LOG.info("Meter Config Provider started."); - } - - protected def startChange() { - return dataService.beginTransaction; - } - - override close() throws Exception { - throw new UnsupportedOperationException("TODO: auto-generated method stub") - } - -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend deleted file mode 100644 index 491fa082a2..0000000000 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransaction.xtend +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.frm.meter - -import org.opendaylight.controller.frm.AbstractTransaction -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri - -class MeterTransaction extends AbstractTransaction { - - @Property - val SalMeterService salMeterService; - - new(DataModification, DataObject> modification,SalMeterService salMeterService) { - super(modification) - _salMeterService = salMeterService; - } - - override remove(InstanceIdentifier instanceId, DataObject obj) { - if(obj instanceof Meter) { - val meter = (obj as Meter) - val nodeInstanceId = instanceId.firstIdentifierOf(Node); - val builder = new RemoveMeterInputBuilder(meter); - builder.setNode(new NodeRef(nodeInstanceId)); - builder.setMeterRef(new MeterRef(instanceId)); - builder.setTransactionUri(new Uri(modification.getIdentifier() as String)); - _salMeterService.removeMeter(builder.build()); - } - } - - override update(InstanceIdentifier instanceId, DataObject originalObj, DataObject updatedObj) { - if(originalObj instanceof Meter && updatedObj instanceof Meter) { - val originalMeter = (originalObj as Meter) - val updatedMeter = (updatedObj as Meter) - val nodeInstanceId = instanceId.firstIdentifierOf(Node); - val builder = new UpdateMeterInputBuilder(); - builder.setNode(new NodeRef(nodeInstanceId)); - builder.setMeterRef(new MeterRef(instanceId)); - val ufb = new UpdatedMeterBuilder(updatedMeter); - builder.setUpdatedMeter((ufb.build())); - builder.setTransactionUri(new Uri(modification.getIdentifier() as String)); - val ofb = new OriginalMeterBuilder(originalMeter); - builder.setOriginalMeter(ofb.build()); - _salMeterService.updateMeter(builder.build()); - - } - } - - override add(InstanceIdentifier instanceId, DataObject obj) { - if(obj instanceof Meter) { - val meter = (obj as Meter) - val nodeInstanceId = instanceId.firstIdentifierOf(Node); - val builder = new AddMeterInputBuilder(meter); - builder.setNode(new NodeRef(nodeInstanceId)); - builder.setMeterRef(new MeterRef(instanceId)); - builder.setTransactionUri(new Uri(modification.getIdentifier() as String)); - _salMeterService.addMeter(builder.build()); - } - } - - override validate() throws IllegalStateException { - MeterTransactionValidator.validate(this) - } -} diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransactionValidator.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransactionValidator.java index b16739cc5b..c8fba23b93 100644 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransactionValidator.java +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/frm/meter/MeterTransactionValidator.java @@ -1,4 +1,4 @@ -/* +/** * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the @@ -9,8 +9,7 @@ package org.opendaylight.controller.frm.meter; public class MeterTransactionValidator { - public static void validate(MeterTransaction transaction) throws IllegalStateException { + public static void validate(MeterChangeListener transaction) throws IllegalStateException { // NOOP } - } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java index 6bd6e6aaf5..cc9c6ebaa6 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java @@ -82,7 +82,7 @@ public class AbstractForwardedTransaction path, final DataObject data) { + invalidateCache(store, path); + final Entry> normalized = codec + .toNormalizedNode(path, data); + + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey(); + ensureParentsByMerge(writeTransaction, store, normalized.getKey(), path); + LOG.debug("Tx: {} : Merge data {}",getDelegate().getIdentifier(),normalized.getKey()); + writeTransaction.merge(store, normalized.getKey(), normalized.getValue()); + } + + private void ensureParentsByMerge(final DOMDataReadWriteTransaction writeTransaction, + final LogicalDatastoreType store, + final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath, + final InstanceIdentifier path) { List currentArguments = new ArrayList<>(); DataNormalizationOperation currentOp = codec.getDataNormalizer().getRootOperation(); Iterator iterator = normalizedPath.getPath().iterator(); @@ -135,8 +156,6 @@ public class AbstractForwardedTransaction implements DataModificationTransaction { + private final ListenerRegistry listeners = ListenerRegistry.create(); private final Map, DataObject> updated = new HashMap<>(); private final Map, DataObject> created = new HashMap<>(); private final Set> removed = new HashSet<>(); @@ -218,13 +219,17 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat @Override public void putOperationalData(final InstanceIdentifier path, final DataObject data) { - posponedRemovedOperational.remove(path); - doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data); + boolean previouslyRemoved = posponedRemovedOperational.remove(path); + if(previouslyRemoved) { + doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data); + } else { + doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.OPERATIONAL, path, data); + } } @Override public void putConfigurationData(final InstanceIdentifier path, final DataObject data) { - posponedRemovedConfiguration.remove(path); + boolean previouslyRemoved = posponedRemovedConfiguration.remove(path); DataObject originalObj = readConfigurationData(path); if (originalObj != null) { original.put(path, originalObj); @@ -233,7 +238,11 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat created.put(path, data); } updated.put(path, data); - doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data); + if(previouslyRemoved) { + doPutWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data); + } else { + doMergeWithEnsureParents(getDelegate(), LogicalDatastoreType.CONFIGURATION, path, data); + } } @Override @@ -314,6 +323,14 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat private void changeStatus(final TransactionStatus status) { LOG.trace("Transaction {} changed status to {}", getIdentifier(), status); this.status = status; + + for(ListenerRegistration listener : listeners) { + try { + listener.getInstance().onStatusUpdated(this, status); + } catch (Exception e) { + LOG.error("Error during invoking transaction listener {}",listener.getInstance(),e); + } + } } @Override @@ -327,10 +344,10 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat doDelete(getDelegate(), LogicalDatastoreType.OPERATIONAL, path); } - final ListenableFuture> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this); - changeStatus(TransactionStatus.SUBMITED); + final ListenableFuture> f = ForwardedBackwardsCompatibleDataBroker.this.commit(this); + Futures.addCallback(f, new FutureCallback>() { @Override public void onSuccess(final RpcResult result) { @@ -349,7 +366,7 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat @Override public ListenerRegistration registerListener(final DataTransactionListener listener) { - throw new UnsupportedOperationException(); + return listeners.register(listener); } } 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 ac26445bf4..4141bba2d4 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 @@ -33,6 +33,8 @@ public class SingletonHolder { public static final int CORE_NOTIFICATION_THREADS = 4; public static final int MAX_NOTIFICATION_THREADS = 32; + // block caller thread after MAX_NOTIFICATION_THREADS + MAX_NOTIFICATION_QUEUE_SIZE pending notifications + public static final int MAX_NOTIFICATION_QUEUE_SIZE = 10; public static final int NOTIFICATION_THREAD_LIFE = 15; private static ListeningExecutorService NOTIFICATION_EXECUTOR = null; @@ -47,19 +49,15 @@ public class SingletonHolder { public static synchronized final ListeningExecutorService getDefaultNotificationExecutor() { if (NOTIFICATION_EXECUTOR == null) { - // Overriding the queue since we need an unbounded queue - // and threadpoolexecutor would not create new threads if the queue is not full - BlockingQueue queue = new LinkedBlockingQueue() { + // Overriding the queue: + // ThreadPoolExecutor would not create new threads if the queue is not full, thus adding + // occurs in RejectedExecutionHandler. + // This impl saturates threadpool first, then queue. When both are full caller will get blocked. + BlockingQueue queue = new LinkedBlockingQueue(MAX_NOTIFICATION_QUEUE_SIZE) { @Override public boolean offer(Runnable r) { - if (size() <= 1) { - // if the queue is empty (or has just 1), no need to rampup the threads - return super.offer(r); - } else { - // if the queue is not empty, force the queue to return false. - // threadpoolexecutor will spawn a new thread if the queue.offer returns false. - return false; - } + // ThreadPoolExecutor will spawn a new thread after core size is reached only if the queue.offer returns false. + return false; } }; @@ -74,7 +72,8 @@ public class SingletonHolder { try { executor.getQueue().put(r); } catch (InterruptedException e) { - e.printStackTrace(); + Thread.currentThread().interrupt();// set interrupt flag after clearing + throw new IllegalStateException(e); } } }); diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolderTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolderTest.java new file mode 100644 index 0000000000..0e4c5ccb84 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolderTest.java @@ -0,0 +1,56 @@ +/* + * 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.sal.binding.codegen.impl; + +import com.google.common.util.concurrent.ListeningExecutorService; +import java.lang.reflect.Field; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Ignore +public class SingletonHolderTest { + private static final Logger logger = LoggerFactory.getLogger(SingletonHolderTest.class); + + @Test + public void testNotificationExecutor() throws Exception { + ListeningExecutorService executor = SingletonHolder.getDefaultNotificationExecutor(); + ThreadPoolExecutor tpExecutor = (ThreadPoolExecutor) setAccessible(executor.getClass().getDeclaredField("delegate")).get(executor); + BlockingQueue queue = tpExecutor.getQueue(); + + for (int idx = 0; idx < 100; idx++) { + final int idx2 = idx; + logger.info("Adding {}\t{}\t{}", idx, queue.size(), tpExecutor.getActiveCount()); + executor.execute(new Runnable() { + + @Override + public void run() { + logger.info("in {}", idx2); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + logger.info("out {}", idx2); + } + }); + } + executor.shutdown(); + executor.awaitTermination(10, TimeUnit.SECONDS); + } + + private static Field setAccessible(Field field) { + field.setAccessible(true); + return field; + } +} diff --git a/opendaylight/md-sal/sal-binding-dom-it/pom.xml b/opendaylight/md-sal/sal-binding-dom-it/pom.xml index 21fa207d78..d1354f897f 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/pom.xml +++ b/opendaylight/md-sal/sal-binding-dom-it/pom.xml @@ -14,6 +14,10 @@ junit junit + + org.opendaylight.yangtools + yang-binding + org.opendaylight.controller sal-binding-broker-impl @@ -25,10 +29,6 @@ test-jar test - - org.opendaylight.yangtools - yang-binding - org.opendaylight.controller.model model-flow-management @@ -54,26 +54,6 @@ - - org.opendaylight.yangtools - yang-maven-plugin - - - - generate-sources - - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - ${salGeneratorPath} - - - true - - - - org.jacoco jacoco-maven-plugin @@ -98,6 +78,26 @@ + + org.opendaylight.yangtools + yang-maven-plugin + + + + generate-sources + + + + + org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + ${salGeneratorPath} + + + true + + + + diff --git a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NotificationTest.java similarity index 99% rename from opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java rename to opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NotificationTest.java index 9519a2a732..e6bbaab2d9 100644 --- a/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NoficationTest.java +++ b/opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/NotificationTest.java @@ -16,6 +16,7 @@ import java.util.Collection; import java.util.List; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; @@ -36,7 +37,8 @@ import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.NotificationListener; import org.opendaylight.yangtools.yang.binding.RpcService; -public class NoficationTest extends AbstractTest { +@Ignore +public class NotificationTest extends AbstractTest { private final FlowListener listener1 = new FlowListener(); private final FlowListener listener2 = new FlowListener(); diff --git a/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml b/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml index 08d22b96d6..37ef257224 100644 --- a/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml +++ b/opendaylight/md-sal/sal-binding-it/src/test/resources/controller.xml @@ -147,6 +147,7 @@ + binding:binding-broker-osgi-registry @@ -158,6 +159,13 @@ + + binding:binding-rpc-registry + + binding-rpc-broker + /modules/module[type='binding-broker-impl'][name='binding-broker-impl'] + + binding-impl:binding-dom-mapping-service diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java index a91799d458..19235d2ddf 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/ImmutableDataChangeEvent.java @@ -11,6 +11,7 @@ import com.google.common.base.Predicate; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; public final class ImmutableDataChangeEvent

, D> implements DataChangeEvent { @@ -127,6 +128,8 @@ public final class ImmutableDataChangeEvent

, D> implements Dat originalOperational.putAll(Maps.filterKeys(data.getOriginalOperationalData(), keyFilter)); createdOperational.putAll(Maps.filterKeys(data.getCreatedOperationalData(), keyFilter)); createdConfiguration.putAll(Maps.filterKeys(data.getCreatedConfigurationData(), keyFilter)); + removedOperational.addAll(Sets.filter(data.getRemovedOperationalData(), keyFilter)); + removedConfiguration.addAll(Sets.filter(data.getRemovedConfigurationData(), keyFilter)); return this; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java index c62c27dea8..e74ba95891 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java @@ -394,7 +394,8 @@ public class ResolveDataChangeEventsTask implements Callable listeners, final NormalizedNode node, final SimpleEventFactory eventFactory) { - DOMImmutableDataChangeEvent event = eventFactory.create(path, node); - - if (!listeners.isEmpty()) { + final DOMImmutableDataChangeEvent event = eventFactory.create(path, node); + DOMImmutableDataChangeEvent propagateEvent = event; // We have listeners for this node or it's children, so we will try // to do additional processing - if (node instanceof NormalizedNodeContainer) { - // Node has children, so we will try to resolve it's children - // changes. - @SuppressWarnings("unchecked") - NormalizedNodeContainer> container = (NormalizedNodeContainer>) node; - for (NormalizedNode child : container.getValue()) { - PathArgument childId = child.getIdentifier(); - Collection childListeners = getListenerChildrenWildcarded(listeners, childId); - if (!childListeners.isEmpty()) { - resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory); - } - } + if (node instanceof NormalizedNodeContainer) { + Builder eventBuilder = builder(DataChangeScope.BASE); + eventBuilder.merge(event); + eventBuilder.setBefore(event.getOriginalSubtree()); + eventBuilder.setAfter(event.getUpdatedSubtree()); + + // Node has children, so we will try to resolve it's children + // changes. + @SuppressWarnings("unchecked") + NormalizedNodeContainer> container = (NormalizedNodeContainer>) node; + for (NormalizedNode child : container.getValue()) { + PathArgument childId = child.getIdentifier(); + Collection childListeners = getListenerChildrenWildcarded(listeners, childId); + eventBuilder.merge(resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory)); } + propagateEvent = eventBuilder.build(); + } else { + // We do not dispatch leaf events since Binding Aware components do not support them. + propagateEvent = builder(DataChangeScope.BASE).build(); + } + if (!listeners.isEmpty()) { addPartialTask(listeners, event); } - return event; + return propagateEvent; } private DOMImmutableDataChangeEvent resolveSubtreeChangeEvent(final InstanceIdentifier path, @@ -476,7 +484,7 @@ public class ResolveDataChangeEventsTask implements Callable { protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) { - super(schema, AugmentationNode.class); + super(createAugmentProxy(schema,resolved), AugmentationNode.class); // FIXME: Use resolved children instead of unresolved. } @@ -563,12 +575,12 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } - public static class LeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { + public static class UnorderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { private final Optional entryStrategy; @SuppressWarnings({ "unchecked", "rawtypes" }) - protected LeafSetModificationStrategy(final LeafListSchemaNode schema) { + protected UnorderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { super((Class) LeafSetNode.class); entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); } @@ -589,6 +601,32 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } + public static class OrderedLeafSetModificationStrategy extends NormalizedNodeContainerModificationStrategy { + + private final Optional entryStrategy; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected OrderedLeafSetModificationStrategy(final LeafListSchemaNode schema) { + super((Class) LeafSetNode.class); + entryStrategy = Optional. of(new LeafSetEntryModificationStrategy(schema)); + } + + @SuppressWarnings("rawtypes") + @Override + protected NormalizedNodeContainerBuilder createBuilder(final PathArgument identifier) { + return ImmutableOrderedLeafSetNodeBuilder.create().withNodeIdentifier((NodeIdentifier) identifier); + } + + @Override + public Optional getChild(final PathArgument identifier) { + if (identifier instanceof NodeWithValue) { + return entryStrategy; + } + return Optional.absent(); + } + + } + public static class UnkeyedListModificationStrategy extends SchemaAwareApplyOperation { private final Optional entryStrategy; @@ -698,4 +736,12 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } + public static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) { + Set realChildSchemas = new HashSet<>(); + for(DataSchemaNode augChild : schema.getChildNodes()) { + realChildSchemas.add(resolved.getDataChildByName(augChild.getQName())); + } + return new AugmentationSchemaProxy(schema, realChildSchemas); + } + } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java index 8d52950a29..aa5c6f40a9 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.java @@ -289,7 +289,7 @@ public class NetconfDevice implements Provider, // @Override public ListenableFuture> invokeRpc(QName rpc, CompositeNode input) { - return listener.sendRequest(toRpcMessage(rpc, input, getSchemaContext())); + return listener.sendRequest(toRpcMessage(rpc, input, getSchemaContext()), rpc); } @Override diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java index 94f5e166a1..1dfc3b44d3 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java @@ -25,6 +25,7 @@ import org.opendaylight.controller.netconf.client.NetconfClientSession; import org.opendaylight.controller.netconf.client.NetconfClientSessionListener; 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.controller.sal.common.util.Rpcs; import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; import org.opendaylight.yangtools.yang.common.QName; @@ -45,10 +46,12 @@ class NetconfDeviceListener implements NetconfClientSessionListener { private static final class Request { final UncancellableFuture> future; final NetconfMessage request; + final QName rpc; - private Request(UncancellableFuture> future, NetconfMessage request) { + private Request(UncancellableFuture> future, NetconfMessage request, final QName rpc) { this.future = future; this.request = request; + this.rpc = rpc; } } @@ -163,14 +166,13 @@ class NetconfDeviceListener implements NetconfClientSessionListener { return; } - r.future.set(Rpcs.getRpcResult(true, NetconfMapping.toNotificationNode(message, device.getSchemaContext()), - Collections.emptyList())); + r.future.set(NetconfMapping.toRpcResult(message, r.rpc, device.getSchemaContext())); } else { LOG.warn("Ignoring unsolicited message", message); } } - synchronized ListenableFuture> sendRequest(final NetconfMessage message) { + synchronized ListenableFuture> sendRequest(final NetconfMessage message, final QName rpc) { if (session == null) { LOG.debug("Session to {} is disconnected, failing RPC request {}", device.getName(), message); return Futures.>immediateFuture(new RpcResult() { @@ -192,7 +194,7 @@ class NetconfDeviceListener implements NetconfClientSessionListener { }); } - final Request req = new Request(new UncancellableFuture>(true), message); + final Request req = new Request(new UncancellableFuture>(true), message, rpc); requests.add(req); session.sendMessage(req.request).addListener(new FutureListener() { @@ -200,7 +202,7 @@ class NetconfDeviceListener implements NetconfClientSessionListener { public void operationComplete(final Future future) throws Exception { if (!future.isSuccess()) { // We expect that a session down will occur at this point - LOG.debug("Failed to send request {}", req.request, future.cause()); + LOG.debug("Failed to send request {}", XmlUtil.toString(req.request.getDocument()), future.cause()); req.future.setException(future.cause()); } else { LOG.trace("Finished sending request {}", req.request); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java index a6e6b3dfdf..f0b711d368 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java @@ -192,12 +192,6 @@ public class NetconfMapping { rawRpc = it.toInstance(); // sys(xmlData) } else { - RpcDefinition rpcSchema = Iterables.find(context.get().getOperations(), new Predicate() { - @Override - public boolean apply(final RpcDefinition input) { - return rpc == input.getQName(); - } - }); rawRpc = (CompositeNode) toCompositeNode(message.getDocument()); } else { diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java index c734e80d9a..abd935dd63 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java @@ -20,6 +20,8 @@ import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider; import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider { @@ -30,8 +32,11 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider private final NetconfDevice device; + private final Logger logger; + public NetconfRemoteSchemaSourceProvider(NetconfDevice device) { this.device = Preconditions.checkNotNull(device); + logger = LoggerFactory.getLogger(NetconfDevice.class + "#" + device.getName()); } @Override @@ -44,7 +49,7 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider request.addLeaf("version", revision.get()); } - device.logger.trace("Loading YANG schema source for {}:{}", moduleName, revision); + logger.trace("Loading YANG schema source for {}:{}", moduleName, revision); try { RpcResult schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance()).get(); if (schemaReply.isSuccessful()) { @@ -54,9 +59,9 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider return Optional.of(schemaBody); } } - device.logger.warn("YANG shcema was not successfully retrieved."); + logger.warn("YANG shcema was not successfully retrieved."); } catch (InterruptedException | ExecutionException e) { - device.logger.warn("YANG shcema was not successfully retrieved.", e); + logger.warn("YANG shcema was not successfully retrieved.", e); } return Optional.absent(); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java index e19f9f5805..4d9958ee6b 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonReader.java @@ -122,7 +122,7 @@ class JsonReader { // it could be identityref Built-In Type URI namespace = getNamespaceFor(value); if (namespace != null) { - return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null); + return new IdentityValuesDTO(namespace.toString(), getLocalNameFor(value), null,value); } // it is not "prefix:value" but just "value" return value; diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java index 225eb7de6a..ba3e315e72 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestUtil.java @@ -42,7 +42,7 @@ public final class RestUtil { if (xPathParts.length < 2) { // must be at least "/pr:node" return null; } - IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO(); + IdentityValuesDTO identityValuesDTO = new IdentityValuesDTO(value); for (int i = 1; i < xPathParts.length; i++) { String xPathPartTrimmed = xPathParts[i].trim(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java index d807070dbd..a75f6b4a85 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/XmlReader.java @@ -205,7 +205,7 @@ public class XmlReader { if (namespaceAndValue.length == 2) { String namespace = startElement.getNamespaceContext().getNamespaceURI(namespaceAndValue[0]); if (namespace != null && !namespace.isEmpty()) { - return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0]); + return new IdentityValuesDTO(namespace, namespaceAndValue[1], namespaceAndValue[0],value); } } // it is not "prefix:value" but just "value" diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java index 4fb75141d5..14a558967d 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/IdentityValuesDTO.java @@ -14,13 +14,19 @@ import java.util.List; public final class IdentityValuesDTO { private final List elementData = new ArrayList<>(); + private final String originValue; - public IdentityValuesDTO(String namespace, String value, String prefix) { + public IdentityValuesDTO(String namespace, String value, String prefix,String originValue) { elementData.add(new IdentityValue(namespace, value, prefix)); + this.originValue = originValue; + } + + public IdentityValuesDTO(String originValue) { + this.originValue = originValue; } public IdentityValuesDTO() { - + originValue = null; } public void add(String namespace, String value, String prefix) { @@ -40,6 +46,10 @@ public final class IdentityValuesDTO { public String toString() { return elementData.toString(); } + + public String getOriginValue() { + return originValue; + } public static final class IdentityValue { diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java index d6b530039e..42658d79f1 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestCodec.java @@ -89,6 +89,9 @@ public class RestCodec { input == null ? "null" : input.getClass(), String.valueOf(input)); return null; } else if (type instanceof LeafrefTypeDefinition) { + if (input instanceof IdentityValuesDTO) { + return LEAFREF_DEFAULT_CODEC.deserialize(((IdentityValuesDTO)input).getOriginValue()); + } return LEAFREF_DEFAULT_CODEC.deserialize(input); } else if (type instanceof InstanceIdentifierTypeDefinition) { if (input instanceof IdentityValuesDTO) { @@ -102,6 +105,9 @@ public class RestCodec { TypeDefinitionAwareCodec> typeAwarecodec = TypeDefinitionAwareCodec .from(type); if (typeAwarecodec != null) { + if (input instanceof IdentityValuesDTO) { + return typeAwarecodec.deserialize(((IdentityValuesDTO)input).getOriginValue()); + } return typeAwarecodec.deserialize(String.valueOf(input)); } else { logger.debug("Codec for type \"" + type.getQName().getLocalName() @@ -162,7 +168,7 @@ public class RestCodec { @Override public IdentityValuesDTO serialize(QName data) { - return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix()); + return new IdentityValuesDTO(data.getNamespace().toString(), data.getLocalName(), data.getPrefix(),null); } @Override diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend index fa478ac72e..a0bd99c5d2 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend @@ -669,7 +669,7 @@ class RestconfImpl implements RestconfService { if (schema.typeDefinition instanceof IdentityrefTypeDefinition) { if (value instanceof String) { - inputValue = new IdentityValuesDTO(nodeBuilder.namespace.toString, value as String, null) + inputValue = new IdentityValuesDTO(nodeBuilder.namespace.toString, value as String, null,value as String); } // else value is already instance of IdentityValuesDTO } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java new file mode 100644 index 0000000000..e5a737e6d5 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/XmlAndJsonToCnSnLeafRefTest.java @@ -0,0 +1,71 @@ +/* + * 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.sal.restconf.impl.test; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.net.URISyntaxException; + +import javax.ws.rs.WebApplicationException; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; +import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; + +public class XmlAndJsonToCnSnLeafRefTest extends YangAndXmlAndDataSchemaLoader { + + @BeforeClass + public static void initialize() { + dataLoad("/leafref/yang", 2, "leafref-module", "cont"); + } + + @Test + public void loadXmlToCnSn() throws WebApplicationException, IOException, URISyntaxException { + CompositeNode cnSn = TestUtils.readInputToCnSn("/leafref/xml/xmldata.xml", XmlToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath); + verifyContPredicate(cnSn, "/ns:cont/ns:lf1", "/cont/lf1", "/ns:cont/ns:lf1", "../lf1"); + } + + @Test + public void loadJsonToCnSn() throws WebApplicationException, IOException, URISyntaxException { + CompositeNode cnSn = TestUtils.readInputToCnSn("/leafref/json/jsondata.json", + JsonToCompositeNodeProvider.INSTANCE); + TestUtils.normalizeCompositeNode(cnSn, modules, schemaNodePath); + verifyContPredicate(cnSn, "/leafref-module:cont/leafref-module:lf1", "/leafref-module:cont/leafref-module:lf1", + "/referenced-module:cont/referenced-module:lf1", "/leafref-module:cont/leafref-module:lf1"); + } + + private void verifyContPredicate(CompositeNode cnSn, String... values) throws URISyntaxException { + Object lf2Value = null; + Object lf3Value = null; + Object lf4Value = null; + Object lf5Value = null; + + for (Node node : cnSn.getValue()) { + if (node.getNodeType().getLocalName().equals("lf2")) { + lf2Value = ((SimpleNode) node).getValue(); + } else if (node.getNodeType().getLocalName().equals("lf3")) { + lf3Value = ((SimpleNode) node).getValue(); + } else if (node.getNodeType().getLocalName().equals("lf4")) { + lf4Value = ((SimpleNode) node).getValue(); + } else if (node.getNodeType().getLocalName().equals("lf5")) { + lf5Value = ((SimpleNode) node).getValue(); + } + } + assertEquals(values[0], lf2Value); + assertEquals(values[1], lf3Value); + assertEquals(values[2], lf4Value); + assertEquals(values[3], lf5Value); + } + +} diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/json/jsondata.json b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/json/jsondata.json new file mode 100644 index 0000000000..cbe455b33b --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/json/jsondata.json @@ -0,0 +1,8 @@ +{ + "leafref-module:cont" : { + "lf4" : "/referenced-module:cont/referenced-module:lf1", + "lf2" : "/leafref-module:cont/leafref-module:lf1", + "lf3" : "/leafref-module:cont/leafref-module:lf1", + "lf5" : "/leafref-module:cont/leafref-module:lf1" + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/xml/xmldata.xml b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/xml/xmldata.xml new file mode 100644 index 0000000000..01bf092d27 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/xml/xmldata.xml @@ -0,0 +1,6 @@ + + /ns:cont/ns:lf1 + /ns:cont/ns:lf1 + /cont/lf1 + ../lf1 + diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/leafref-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/leafref-module.yang new file mode 100644 index 0000000000..00df290691 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/leafref-module.yang @@ -0,0 +1,44 @@ +module leafref-module { + namespace "leafref:module"; + + + prefix "lfrfmodule"; + + import referenced-module { prefix refmod; revision-date 2014-04-17;} + + + revision 2014-04-17 { + } + + + container cont { + leaf lf1 { + type instance-identifier; + } + + leaf lf2 { + type leafref { + path "../lf1"; + } + } + + leaf lf3 { + type leafref { + path "/refmod:cont/refmod:lf1"; + } + } + + leaf lf4 { + type leafref { + path "/cont/lf1"; + } + } + + leaf lf5 { + type leafref { + path "../lf1"; + } + } + + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/referenced-module.yang b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/referenced-module.yang new file mode 100644 index 0000000000..b6de719e4d --- /dev/null +++ b/opendaylight/md-sal/sal-rest-connector/src/test/resources/leafref/yang/referenced-module.yang @@ -0,0 +1,13 @@ +module referenced-module { + namespace "referenced:module"; + + prefix "refmodule"; + revision 2014-04-17 { + } + + container cont { + leaf lf1 { + type instance-identifier; + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java index 4a58579b13..167fb21ffd 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractListeningStatsTracker.java @@ -20,8 +20,8 @@ abstract class AbstractListeningStatsTracker extends AbstractStatsTracker< private static final Logger logger = LoggerFactory.getLogger(AbstractListeningStatsTracker.class); private ListenerRegistration reg; - protected AbstractListeningStatsTracker(FlowCapableContext context, long lifetimeNanos) { - super(context, lifetimeNanos); + protected AbstractListeningStatsTracker(FlowCapableContext context) { + super(context); } protected abstract InstanceIdentifier listenPath(); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java index c29b6a7730..e922656d91 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/AbstractStatsTracker.java @@ -32,6 +32,9 @@ import com.google.common.util.concurrent.JdkFutureAdapters; abstract class AbstractStatsTracker { private static final Logger logger = LoggerFactory.getLogger(AbstractStatsTracker.class); + + private static final int WAIT_FOR_REQUEST_CYCLE = 2; + private final FutureCallback> callback = new FutureCallback>() { @Override @@ -62,11 +65,11 @@ abstract class AbstractStatsTracker { private final Map trackedItems = new HashMap<>(); private final FlowCapableContext context; - private final long lifetimeNanos; + private long requestCounter; - protected AbstractStatsTracker(final FlowCapableContext context, final long lifetimeNanos) { + protected AbstractStatsTracker(final FlowCapableContext context) { this.context = Preconditions.checkNotNull(context); - this.lifetimeNanos = lifetimeNanos; + this.requestCounter = 0; } protected final InstanceIdentifierBuilder getNodeIdentifierBuilder() { @@ -89,24 +92,32 @@ abstract class AbstractStatsTracker { return context.startDataModification(); } + public final synchronized void increaseRequestCounter(){ + this.requestCounter++; + } protected abstract void cleanupSingleStat(DataModificationTransaction trans, K item); protected abstract K updateSingleStat(DataModificationTransaction trans, I item); + public abstract void request(); public final synchronized void updateStats(List list) { - final Long expiryTime = System.nanoTime() + lifetimeNanos; + final DataModificationTransaction trans = startTransaction(); for (final I item : list) { - trackedItems.put(updateSingleStat(trans, item), expiryTime); + trackedItems.put(updateSingleStat(trans, item), requestCounter); } trans.commit(); } - public final synchronized void cleanup(final DataModificationTransaction trans, long now) { + /** + * Statistics will be cleaned up if not update in last two request cycles. + * @param trans + */ + public final synchronized void cleanup(final DataModificationTransaction trans) { for (Iterator> it = trackedItems.entrySet().iterator();it.hasNext();){ Entry e = it.next(); - if (now > e.getValue()) { + if (requestCounter >= e.getValue()+WAIT_FOR_REQUEST_CYCLE) { cleanupSingleStat(trans, e.getKey()); it.remove(); } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java index 90ddc28acd..06d6e82112 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowStatsTracker.java @@ -7,6 +7,7 @@ */ package org.opendaylight.controller.md.statistics.manager; +import java.util.Collection; import java.util.Map.Entry; import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; @@ -37,12 +38,17 @@ import org.slf4j.LoggerFactory; final class FlowStatsTracker extends AbstractListeningStatsTracker { private static final Logger logger = LoggerFactory.getLogger(FlowStatsTracker.class); private final OpendaylightFlowStatisticsService flowStatsService; + private FlowTableStatsTracker flowTableStats; private int unaccountedFlowsCounter = 1; - FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, long lifetimeNanos) { - super(context, lifetimeNanos); + FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context) { + super(context); this.flowStatsService = flowStatsService; } + FlowStatsTracker(OpendaylightFlowStatisticsService flowStatsService, final FlowCapableContext context, FlowTableStatsTracker flowTableStats) { + this(flowStatsService, context); + this.flowTableStats = flowTableStats; + } @Override protected void cleanupSingleStat(DataModificationTransaction trans, FlowStatsEntry item) { @@ -203,6 +209,20 @@ final class FlowStatsTracker extends AbstractListeningStatsTracker tables = flowTableStats.getTables(); + logger.debug("Node {} supports {} table(s)", this.getNodeRef(), tables.size()); + for (final TableKey key : tables) { + logger.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), this.getNodeRef()); + this.requestAggregateFlows(key); + } + + this.requestAllFlowsAllTables(); + + } public void requestAllFlowsAllTables() { if (flowStatsService != null) { final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input = new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder(); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java index 3fe68c111a..a160f6d467 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/FlowTableStatsTracker.java @@ -30,8 +30,8 @@ final class FlowTableStatsTracker extends AbstractStatsTracker tables = Collections.unmodifiableSet(privateTables); private final OpendaylightFlowTableStatisticsService flowTableStatsService; - FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context, long lifetimeNanos) { - super(context, lifetimeNanos); + FlowTableStatsTracker(OpendaylightFlowTableStatisticsService flowTableStatsService, final FlowCapableContext context) { + super(context); this.flowTableStatsService = flowTableStatsService; } @@ -61,6 +61,7 @@ final class FlowTableStatsTracker extends AbstractStatsTracker targetNodeIdentifier; private final FlowStatsTracker flowStats; private final FlowTableStatsTracker flowTableStats; @@ -103,23 +103,25 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo final OpendaylightGroupStatisticsService groupStatsService, final OpendaylightMeterStatisticsService meterStatsService, final OpendaylightPortStatisticsService portStatsService, - final OpendaylightQueueStatisticsService queueStatsService) { + final OpendaylightQueueStatisticsService queueStatsService, + final StatisticsRequestScheduler srScheduler) { this.dps = Preconditions.checkNotNull(dps); this.targetNodeKey = Preconditions.checkNotNull(nodeKey); + this.srScheduler = Preconditions.checkNotNull(srScheduler); this.targetNodeIdentifier = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey).build(); this.targetNodeRef = new NodeRef(targetNodeIdentifier); final long lifetimeNanos = TimeUnit.MILLISECONDS.toNanos(STATS_COLLECTION_MILLIS * NUMBER_OF_WAIT_CYCLES); msgManager = new MultipartMessageManager(lifetimeNanos); - flowStats = new FlowStatsTracker(flowStatsService, this, lifetimeNanos); - flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this, lifetimeNanos); - groupDescStats = new GroupDescStatsTracker(groupStatsService, this, lifetimeNanos); - groupStats = new GroupStatsTracker(groupStatsService, this, lifetimeNanos); - meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this, lifetimeNanos); - meterStats = new MeterStatsTracker(meterStatsService, this, lifetimeNanos); - nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this, lifetimeNanos); - queueStats = new QueueStatsTracker(queueStatsService, this, lifetimeNanos); + flowTableStats = new FlowTableStatsTracker(flowTableStatsService, this); + flowStats = new FlowStatsTracker(flowStatsService, this, flowTableStats); + groupDescStats = new GroupDescStatsTracker(groupStatsService, this); + groupStats = new GroupStatsTracker(groupStatsService, this); + meterConfigStats = new MeterConfigStatsTracker(meterStatsService, this); + meterStats = new MeterStatsTracker(meterStatsService, this); + nodeConnectorStats = new NodeConnectorStatsTracker(portStatsService, this); + queueStats = new QueueStatsTracker(queueStatsService, this); } public NodeKey getTargetNodeKey() { @@ -138,7 +140,9 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo @Override public DataModificationTransaction startDataModification() { - return dps.beginTransaction(); + DataModificationTransaction dmt = dps.beginTransaction(); + dmt.registerListener(this.srScheduler); + return dmt; } public synchronized void updateGroupDescStats(TransactionAware transaction, List list) { @@ -186,7 +190,7 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo public synchronized void updateAggregateFlowStats(TransactionAware transaction, AggregateFlowStatistics flowStats) { final Short tableId = msgManager.isExpectedTableTransaction(transaction); if (tableId != null) { - final DataModificationTransaction trans = dps.beginTransaction(); + final DataModificationTransaction trans = this.startDataModification(); InstanceIdentifier

tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey) .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId)).toInstance(); @@ -214,7 +218,7 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo } public synchronized void updateGroupFeatures(GroupFeatures notification) { - final DataModificationTransaction trans = dps.beginTransaction(); + final DataModificationTransaction trans = this.startDataModification(); final NodeBuilder nodeData = new NodeBuilder(); nodeData.setKey(targetNodeKey); @@ -232,7 +236,7 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo } public synchronized void updateMeterFeatures(MeterFeatures features) { - final DataModificationTransaction trans = dps.beginTransaction(); + final DataModificationTransaction trans = this.startDataModification(); final NodeBuilder nodeData = new NodeBuilder(); nodeData.setKey(targetNodeKey); @@ -250,16 +254,15 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo } public synchronized void cleanStaleStatistics() { - final DataModificationTransaction trans = dps.beginTransaction(); - final long now = System.nanoTime(); - - flowStats.cleanup(trans, now); - groupDescStats.cleanup(trans, now); - groupStats.cleanup(trans, now); - meterConfigStats.cleanup(trans, now); - meterStats.cleanup(trans, now); - nodeConnectorStats.cleanup(trans, now); - queueStats.cleanup(trans, now); + final DataModificationTransaction trans = this.startDataModification(); + + flowStats.cleanup(trans); + groupDescStats.cleanup(trans); + groupStats.cleanup(trans); + meterConfigStats.cleanup(trans); + meterStats.cleanup(trans); + nodeConnectorStats.cleanup(trans); + queueStats.cleanup(trans); msgManager.cleanStaleTransactionIds(); trans.commit(); @@ -268,26 +271,23 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo public synchronized void requestPeriodicStatistics() { logger.debug("Send requests for statistics collection to node : {}", targetNodeKey); - flowTableStats.request(); - - // FIXME: it does not make sense to trigger this before sendAllFlowTablesStatisticsRequest() - // comes back -- we do not have any tables anyway. - final Collection tables = flowTableStats.getTables(); - logger.debug("Node {} supports {} table(s)", targetNodeKey, tables.size()); - for (final TableKey key : tables) { - logger.debug("Send aggregate stats request for flow table {} to node {}", key.getId(), targetNodeKey); - flowStats.requestAggregateFlows(key); - } - - flowStats.requestAllFlowsAllTables(); - nodeConnectorStats.request(); - groupStats.request(); - groupDescStats.request(); - meterStats.request(); - meterConfigStats.request(); - queueStats.request(); + this.srScheduler.addRequestToSchedulerQueue(flowTableStats); + + this.srScheduler.addRequestToSchedulerQueue(flowStats); + + this.srScheduler.addRequestToSchedulerQueue(nodeConnectorStats); + + this.srScheduler.addRequestToSchedulerQueue(groupStats); + + this.srScheduler.addRequestToSchedulerQueue(groupDescStats); + + this.srScheduler.addRequestToSchedulerQueue(meterStats); + + this.srScheduler.addRequestToSchedulerQueue(meterConfigStats); + + this.srScheduler.addRequestToSchedulerQueue(queueStats); } - + public synchronized void start(final Timer timer) { flowStats.start(dps); groupDescStats.start(dps); diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java index f187c7082e..6f93eeb617 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/QueueStatsTracker.java @@ -36,8 +36,8 @@ final class QueueStatsTracker extends AbstractListeningStatsTracker requestQueue = + Collections.synchronizedMap(new LinkedHashMap()); + + private Long PendingTransactions; + + private long lastRequestTime = System.nanoTime(); + + private static final long REQUEST_MONITOR_INTERVAL = 1000; + + private final TimerTask task = new TimerTask() { + @Override + public void run() { + long now = System.nanoTime(); + if(now > lastRequestTime+TimeUnit.MILLISECONDS.toNanos(REQUEST_MONITOR_INTERVAL)){ + requestStatistics(); + } + } + }; + + public StatisticsRequestScheduler(){ + PendingTransactions = (long) 0; + } + + public void addRequestToSchedulerQueue(AbstractStatsTracker statsRequest){ + requestQueue.put(statsRequest, null); + } + + public AbstractStatsTracker getNextRequestFromSchedulerQueue(){ + //Remove first element + AbstractStatsTracker stats = null; + synchronized(requestQueue){ + Iterator> nodesItr = requestQueue.entrySet().iterator(); + if(nodesItr.hasNext()){ + stats = nodesItr.next().getKey(); + srsLogger.debug("{} chosen up for execution",stats.getNodeRef()); + nodesItr.remove(); + return stats; + } + } + return stats; + } + + private void requestStatistics(){ + AbstractStatsTracker stats = this.getNextRequestFromSchedulerQueue(); + if(stats != null) { + stats.request(); + stats.increaseRequestCounter(); + } + } + @Override + public void onStatusUpdated(DataModificationTransaction transaction, TransactionStatus status) { + + AbstractStatsTracker stats = null; + synchronized(PendingTransactions){ + switch(status){ + case SUBMITED: + this.PendingTransactions++; + break; + case COMMITED: + case FAILED: + this.PendingTransactions--; + if(PendingTransactions == 0){ + lastRequestTime = System.nanoTime(); + stats = this.getNextRequestFromSchedulerQueue(); + } + srsLogger.debug("Pending MD-SAL transactions : {} & Scheduler queue size : {}",this.PendingTransactions,this.requestQueue.size()); + break; + default: + break; + } + } + if(stats != null){ + stats.request(); + stats.increaseRequestCounter(); + } + } + + public void start(){ + timer.schedule(task, 0, REQUEST_MONITOR_INTERVAL); + } +} diff --git a/opendaylight/md-sal/topology-lldp-discovery/pom.xml b/opendaylight/md-sal/topology-lldp-discovery/pom.xml index 2d003f8079..a51f6c2f9f 100644 --- a/opendaylight/md-sal/topology-lldp-discovery/pom.xml +++ b/opendaylight/md-sal/topology-lldp-discovery/pom.xml @@ -34,10 +34,6 @@ equinoxSDK381 org.eclipse.osgi - - org.eclipse.xtend - org.eclipse.xtend.lib - org.opendaylight.controller sal @@ -82,10 +78,6 @@ ${project.basedir}/META-INF - - org.eclipse.xtend - xtend-maven-plugin - diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.java new file mode 100644 index 0000000000..0e003dbe7f --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.java @@ -0,0 +1,30 @@ +/** + * 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.md.controller.topology.lldp; + +import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.osgi.framework.BundleContext; + +public class LLDPActivator extends AbstractBindingAwareProvider { + private static LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider(); + + public void onSessionInitiated(final ProviderContext session) { + DataProviderService dataService = session.getSALService(DataProviderService.class); + provider.setDataService(dataService); + NotificationProviderService notificationService = session.getSALService(NotificationProviderService.class); + provider.setNotificationService(notificationService); + provider.start(); + } + + protected void stopImpl(final BundleContext context) { + provider.close(); + } +} diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend deleted file mode 100644 index 674e919cd7..0000000000 --- a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPActivator.xtend +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.md.controller.topology.lldp - -import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext -import org.opendaylight.controller.sal.binding.api.NotificationProviderService -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.osgi.framework.BundleContext - -class LLDPActivator extends AbstractBindingAwareProvider { - - static var LLDPDiscoveryProvider provider = new LLDPDiscoveryProvider(); - - override onSessionInitiated(ProviderContext session) { - provider.dataService = session.getSALService(DataProviderService) - provider.notificationService = session.getSALService(NotificationProviderService) - provider.start(); - } - - override protected stopImpl(BundleContext context) { - provider.close(); - } - -} diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.java b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.java new file mode 100644 index 0000000000..b219722ba8 --- /dev/null +++ b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.java @@ -0,0 +1,58 @@ +/** + * 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.md.controller.topology.lldp; + +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.NotificationListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LLDPDiscoveryProvider implements AutoCloseable { + private final static Logger LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider.class); + private DataProviderService dataService; + private NotificationProviderService notificationService; + private final LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(LLDPDiscoveryProvider.this); + private Registration listenerRegistration; + + public DataProviderService getDataService() { + return this.dataService; + } + + public void setDataService(final DataProviderService dataService) { + this.dataService = dataService; + } + + public NotificationProviderService getNotificationService() { + return this.notificationService; + } + + public void setNotificationService(final NotificationProviderService notificationService) { + this.notificationService = notificationService; + } + + public void start() { + Registration registerNotificationListener = this.getNotificationService().registerNotificationListener(this.commiter); + this.listenerRegistration = registerNotificationListener; + LLDPLinkAger.getInstance().setManager(this); + LOG.info("LLDPDiscoveryListener Started."); + } + + public void close() { + try { + LOG.info("LLDPDiscoveryListener stopped."); + if (this.listenerRegistration!=null) { + this.listenerRegistration.close(); + } + LLDPLinkAger.getInstance().close(); + } catch (Exception e) { + throw new Error(e); + } + } +} diff --git a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend b/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend deleted file mode 100644 index fc724ac680..0000000000 --- a/opendaylight/md-sal/topology-lldp-discovery/src/main/java/org/opendaylight/md/controller/topology/lldp/LLDPDiscoveryProvider.xtend +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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.md.controller.topology.lldp - -import org.opendaylight.controller.sal.binding.api.NotificationProviderService -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.yangtools.concepts.Registration -import org.opendaylight.yangtools.yang.binding.NotificationListener -import org.slf4j.LoggerFactory - -class LLDPDiscoveryProvider implements AutoCloseable { - - - static val LOG = LoggerFactory.getLogger(LLDPDiscoveryProvider); - - @Property - DataProviderService dataService; - - @Property - NotificationProviderService notificationService; - - val LLDPDiscoveryListener commiter = new LLDPDiscoveryListener(this); - - Registration listenerRegistration - - def void start() { - listenerRegistration = notificationService.registerNotificationListener(commiter); - LLDPLinkAger.instance.manager = this; - LOG.info("LLDPDiscoveryListener Started."); - - } - - override close() { - LOG.info("LLDPDiscoveryListener stopped."); - listenerRegistration?.close(); - LLDPLinkAger.instance.close(); - } - -} - - diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java index 54d24a4cec..c08be06c9f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java @@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition; public abstract class AttributeIfcSwitchStatement { - protected AttributeIfc lastAttribute; + private AttributeIfc lastAttribute; public T switchAttribute(AttributeIfc attributeIfc) { @@ -39,8 +39,9 @@ public abstract class AttributeIfcSwitchStatement { return caseJavaUnionAttribute(openType); } else if(((JavaAttribute)attributeIfc).isIdentityRef()) { return caseJavaIdentityRefAttribute(openType); - } else + } else { return caseJavaAttribute(openType); + } } catch (UnknownOpenTypeException e) { throw getIllegalArgumentException(attributeIfc); } @@ -58,6 +59,10 @@ public abstract class AttributeIfcSwitchStatement { throw getIllegalArgumentException(attributeIfc); } + public AttributeIfc getLastAttribute() { + return lastAttribute; + } + protected T caseJavaIdentityRefAttribute(OpenType openType) { return caseJavaAttribute(openType); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java index dbc1b48d4f..dcc2fa1543 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml; import com.google.common.base.Optional; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy; import javax.management.openmbean.OpenType; @@ -39,7 +40,7 @@ public class AttributeConfigElement { } public void resolveValue(AttributeResolvingStrategy> attributeResolvingStrategy, - String attrName) { + String attrName) throws NetconfDocumentedException { resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value); Optional resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue); resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java index 5f44c16dca..bf9eee7f26 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java @@ -55,7 +55,7 @@ public class ObjectNameAttributeReadingStrategy extends AbstractAttributeReading public static String checkPrefixAndExtractServiceName(XmlElement typeElement, Map.Entry prefixNamespace) throws NetconfDocumentedException { String serviceName = typeElement.getTextContent(); - Preconditions.checkState(prefixNamespace.equals("") == false, "Service %s value not prefixed with namespace", + Preconditions.checkState(!prefixNamespace.equals(""), "Service %s value not prefixed with namespace", XmlNetconfConstants.TYPE_KEY); String prefix = prefixNamespace.getKey() + PREFIX_SEPARATOR; Preconditions.checkState(serviceName.startsWith(prefix), diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java index 61db74feb5..61ea76bbfe 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java @@ -50,31 +50,31 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement openType) { - return new SimpleBinaryAttributeReadingStrategy(lastAttribute.getNullableDefault()); + return new SimpleBinaryAttributeReadingStrategy(getLastAttribute().getNullableDefault()); } @Override protected AttributeReadingStrategy caseJavaUnionAttribute(OpenType openType) { String mappingKey = JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION; - return new SimpleUnionAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey); + return new SimpleUnionAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey); } @Override public AttributeReadingStrategy caseJavaSimpleAttribute(SimpleType openType) { - return new SimpleAttributeReadingStrategy(lastAttribute.getNullableDefault()); + return new SimpleAttributeReadingStrategy(getLastAttribute().getNullableDefault()); } @Override public AttributeReadingStrategy caseJavaArrayAttribute(ArrayType openType) { - SimpleAttributeReadingStrategy innerStrategy = new SimpleAttributeReadingStrategy(lastAttribute.getNullableDefault()); - return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy); + SimpleAttributeReadingStrategy innerStrategy = new SimpleAttributeReadingStrategy(getLastAttribute().getNullableDefault()); + return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy); } @Override public AttributeReadingStrategy caseJavaCompositeAttribute(CompositeType openType) { Preconditions.checkState(openType.keySet().size() == 1, "Unexpected number of elements for open type %s, should be 1", openType); String mappingKey = openType.keySet().iterator().next(); - return new SimpleCompositeAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey); + return new SimpleCompositeAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey); } @Override @@ -83,18 +83,18 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement keys = ((CompositeType) openType).keySet(); Preconditions.checkState(keys.size() == 1, "Unexpected number of elements for open type %s, should be 1", openType); String mappingKey = keys.iterator().next(); - return new SimpleIdentityRefAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey, identityMap); + return new SimpleIdentityRefAttributeReadingStrategy(getLastAttribute().getNullableDefault(), mappingKey, identityMap); } @Override protected AttributeReadingStrategy caseDependencyAttribute(SimpleType openType) { - return new ObjectNameAttributeReadingStrategy(lastAttribute.getNullableDefault()); + return new ObjectNameAttributeReadingStrategy(getLastAttribute().getNullableDefault()); } @Override protected AttributeReadingStrategy caseTOAttribute(CompositeType openType) { - Preconditions.checkState(lastAttribute instanceof TOAttribute); - Map inner = ((TOAttribute)lastAttribute).getYangPropertiesToTypesMap(); + Preconditions.checkState(getLastAttribute() instanceof TOAttribute); + Map inner = ((TOAttribute)getLastAttribute()).getYangPropertiesToTypesMap(); Map innerStrategies = Maps.newHashMap(); @@ -104,21 +104,21 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement openType) { - Preconditions.checkState(lastAttribute instanceof ListAttribute); - AttributeReadingStrategy innerStrategy = prepareReadingStrategy(key, ((ListAttribute) lastAttribute).getInnerAttribute()); - return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy); + Preconditions.checkState(getLastAttribute() instanceof ListAttribute); + AttributeReadingStrategy innerStrategy = prepareReadingStrategy(key, ((ListAttribute) getLastAttribute()).getInnerAttribute()); + return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy); } @Override protected AttributeReadingStrategy caseListDependeciesAttribute(ArrayType openType) { - Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute); AttributeReadingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME); - return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy); + return new ArrayAttributeReadingStrategy(getLastAttribute().getNullableDefault(), innerStrategy); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java index 58f91a7dee..8e7ba708c6 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleIdentityRefAttributeReadingStrategy.java @@ -54,9 +54,9 @@ public class SimpleIdentityRefAttributeReadingStrategy extends SimpleAttributeRe revision = date; } } - } else + } else { revision = revisions.keySet().iterator().next(); - + } return QName.create(URI.create(namespace), revision, localName).toString(); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java index 30436bb42f..54ffe08cfb 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ArrayAttributeMappingStrategy.java @@ -30,8 +30,9 @@ public class ArrayAttributeMappingStrategy extends AbstractAttributeMappingStrat @Override public Optional> mapAttribute(Object value) { - if (value == null) + if (value == null){ return Optional.absent(); + } Preconditions.checkArgument(value.getClass().isArray(), "Value has to be instanceof Array "); @@ -39,19 +40,11 @@ public class ArrayAttributeMappingStrategy extends AbstractAttributeMappingStrat for (int i = 0; i < Array.getLength(value); i++) { Object innerValue = Array.get(value, i); - // String expectedClassName = - // getOpenType().getElementOpenType().getClassName(); - // String realClassName = value.getClass().getName(); - - // Preconditions.checkState(realClassName.contains(expectedClassName), - // "Element in collection/array should be of type " + - // expectedClassName + " but was " - // + realClassName + " for attribute: " + getOpenType()); - Optional mapAttribute = innerElementStrategy.mapAttribute(innerValue); - if (mapAttribute.isPresent()) + if (mapAttribute.isPresent()){ retVal.add(mapAttribute.get()); + } } return Optional.of(retVal); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java index 368e1f12a6..594953e569 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/CompositeAttributeMappingStrategy.java @@ -35,8 +35,9 @@ public class CompositeAttributeMappingStrategy extends @Override public Optional> mapAttribute(Object value) { - if (value == null) + if (value == null){ return Optional.absent(); + } Util.checkType(value, CompositeDataSupport.class); @@ -54,8 +55,9 @@ public class CompositeAttributeMappingStrategy extends for (String jmxName : jmxToJavaNameMapping.keySet()) { Optional mapped = mapInnerAttribute(compositeData, jmxName, expectedType.getDescription(jmxName)); - if(mapped.isPresent()) + if(mapped.isPresent()){ retVal.put(jmxToJavaNameMapping.get(jmxName), mapped.get()); + } } return Optional.of(retVal); @@ -66,8 +68,7 @@ public class CompositeAttributeMappingStrategy extends AttributeMappingStrategy> attributeMappingStrategy = innerStrategies .get(jmxName); - Optional mapAttribute = attributeMappingStrategy.mapAttribute(innerValue); - return mapAttribute; + return attributeMappingStrategy.mapAttribute(innerValue); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java index 506d7d61c3..01844f27d4 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java @@ -112,7 +112,7 @@ public class ObjectMapper extends AttributeIfcSwitchStatement> caseDependencyAttribute( SimpleType openType) { - return new ObjectNameAttributeMappingStrategy(openType, dependencyTracker, + return new ObjectNameAttributeMappingStrategy(openType, serviceNameOfDepAttr, namespaceOfDepAttr); } @@ -120,10 +120,10 @@ public class ObjectMapper extends AttributeIfcSwitchStatement> caseTOAttribute(CompositeType openType) { Map>> innerStrategies = Maps.newHashMap(); - Preconditions.checkState(lastAttribute instanceof TOAttribute); - TOAttribute lastTO = (TOAttribute) lastAttribute; + Preconditions.checkState(getLastAttribute() instanceof TOAttribute); + TOAttribute lastTO = (TOAttribute) getLastAttribute(); - for (Entry innerAttrEntry : ((TOAttribute)lastAttribute).getJmxPropertiesToTypesMap().entrySet()) { + for (Entry innerAttrEntry : ((TOAttribute)getLastAttribute()).getJmxPropertiesToTypesMap().entrySet()) { innerStrategies.put(innerAttrEntry.getKey(), prepareStrategy(innerAttrEntry.getValue())); } @@ -133,14 +133,14 @@ public class ObjectMapper extends AttributeIfcSwitchStatement> caseListAttribute(ArrayType openType) { - Preconditions.checkState(lastAttribute instanceof ListAttribute); + Preconditions.checkState(getLastAttribute() instanceof ListAttribute); return new ArrayAttributeMappingStrategy(openType, - prepareStrategy(((ListAttribute) lastAttribute).getInnerAttribute())); + prepareStrategy(((ListAttribute) getLastAttribute()).getInnerAttribute())); } @Override protected AttributeMappingStrategy> caseListDependeciesAttribute(ArrayType openType) { - Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute); return new ArrayAttributeMappingStrategy(openType, caseDependencyAttribute(SimpleType.OBJECTNAME)); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java index 83e8086eef..b827a5b039 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java @@ -10,31 +10,28 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; -import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; - import javax.management.ObjectName; import javax.management.openmbean.SimpleType; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; public class ObjectNameAttributeMappingStrategy extends AbstractAttributeMappingStrategy> { - private final ServiceRegistryWrapper tracker; private final String serviceName; private final String namespace; - public ObjectNameAttributeMappingStrategy(SimpleType openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) { + public ObjectNameAttributeMappingStrategy(SimpleType openType, String serviceName, String namespace) { super(openType); - this.tracker = dependencyTracker; this.serviceName = serviceName; this.namespace = namespace; } @Override public Optional mapAttribute(Object value) { - if (value == null) + if (value == null){ return Optional.absent(); + } String expectedClass = getOpenType().getClassName(); String realClass = value.getClass().getName(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java index d92b7c432d..7dbf4f41bc 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/SimpleAttributeMappingStrategy.java @@ -25,8 +25,9 @@ public class SimpleAttributeMappingStrategy extends AbstractAttributeMappingStra @Override public Optional mapAttribute(Object value) { - if (value == null) + if (value == null){ return Optional.absent(); + } String expectedClass = getOpenType().getClassName(); String realClass = value.getClass().getName(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java index 81a1e53598..1754fc7e09 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/UnionCompositeAttributeMappingStrategy.java @@ -26,9 +26,9 @@ public class UnionCompositeAttributeMappingStrategy extends @Override protected Optional mapInnerAttribute(CompositeDataSupport compositeData, String jmxName, String description) { - if(description.equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION) == false) + if(!description.equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)){ return Optional.absent(); - + } return super.mapInnerAttribute(compositeData, jmxName, description); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java index adee8bec58..f0d7960085 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ArrayAttributeResolvingStrategy.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving; import com.google.common.base.Optional; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +34,7 @@ final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingSt } @Override - public Optional parseAttribute(String attrName, Object value) { + public Optional parseAttribute(String attrName, Object value) throws NetconfDocumentedException { if (value == null) { return Optional.absent(); } @@ -45,31 +46,31 @@ final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingSt if (innerTypeResolvingStrategy.getOpenType() instanceof CompositeType) { innerTypeClass = CompositeDataSupport.class; - } else + } else { try { innerTypeClass = Class.forName(getOpenType().getElementOpenType().getClassName()); } catch (ClassNotFoundException e) { - throw new RuntimeException("Unable to locate class for " + throw new IllegalStateException("Unable to locate class for " + getOpenType().getElementOpenType().getClassName(), e); } + } Object parsedArray = null; if (getOpenType().isPrimitiveArray()) { Class primitiveType = getPrimitiveType(innerTypeClass); parsedArray = Array.newInstance(primitiveType, valueList.size()); - } else + } else { parsedArray = Array.newInstance(innerTypeClass, valueList.size()); + } int i = 0; for (Object innerValue : valueList) { Optional parsedElement = innerTypeResolvingStrategy.parseAttribute(attrName + "_" + i, innerValue); - - if (!parsedElement.isPresent()) + if (!parsedElement.isPresent()){ continue; - + } Array.set(parsedArray, i, parsedElement.get()); - // parsedArray[i] = parsedElement.get(); i++; } @@ -94,7 +95,7 @@ final class ArrayAttributeResolvingStrategy extends AbstractAttributeResolvingSt try { return (Class) innerTypeClass.getField("TYPE").get(null); } catch (Exception e) { - throw new RuntimeException("Unable to determine primitive type to " + innerTypeClass); + throw new IllegalStateException("Unable to determine primitive type to " + innerTypeClass); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java index 0bb274ae41..599d81396e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/AttributeResolvingStrategy.java @@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import javax.management.openmbean.OpenType; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; /** * Create real object from String or Map that corresponds to given opentype. @@ -18,5 +19,5 @@ import javax.management.openmbean.OpenType; public interface AttributeResolvingStrategy> { O getOpenType(); - Optional parseAttribute(String attrName, Object value); + Optional parseAttribute(String attrName, Object value) throws NetconfDocumentedException; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java index e8e97f990f..83ebf65d7f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/CompositeAttributeResolvingStrategy.java @@ -11,6 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,7 +42,7 @@ class CompositeAttributeResolvingStrategy extends } @Override - public Optional parseAttribute(String attrName, Object value) { + public Optional parseAttribute(String attrName, Object value) throws NetconfDocumentedException { if (value == null) { return Optional.absent(); @@ -75,7 +76,7 @@ class CompositeAttributeResolvingStrategy extends try { parsedValue = new CompositeDataSupport(getOpenType(), items); } catch (OpenDataException e) { - throw new RuntimeException("An error occured during restoration of composite type " + this + throw new IllegalStateException("An error occured during restoration of composite type " + this + " for attribute " + attrName + " from value " + value, e); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java index 82c8c1ec6b..4a4281a55e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java @@ -106,8 +106,8 @@ public class ObjectResolver extends AttributeIfcSwitchStatement> caseTOAttribute(CompositeType openType) { - Preconditions.checkState(lastAttribute instanceof TOAttribute); - TOAttribute toAttribute = (TOAttribute) lastAttribute; + Preconditions.checkState(getLastAttribute() instanceof TOAttribute); + TOAttribute toAttribute = (TOAttribute) getLastAttribute(); Map>> innerMap = Maps.newHashMap(); @@ -122,14 +122,14 @@ public class ObjectResolver extends AttributeIfcSwitchStatement> caseListAttribute(ArrayType openType) { - Preconditions.checkState(lastAttribute instanceof ListAttribute); - AttributeIfc innerAttribute = ((ListAttribute) lastAttribute).getInnerAttribute(); + Preconditions.checkState(getLastAttribute() instanceof ListAttribute); + AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute(); return new ArrayAttributeResolvingStrategy(prepareStrategy(innerAttribute), openType); } @Override protected AttributeResolvingStrategy> caseListDependeciesAttribute(ArrayType openType) { - Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute); return new ArrayAttributeResolvingStrategy(caseDependencyAttribute(SimpleType.OBJECTNAME), openType); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java index e1b8ecf17e..26709dbe6b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java @@ -10,6 +10,9 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import com.google.common.collect.Maps; +import java.lang.reflect.InvocationTargetException; +import java.text.ParseException; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +38,7 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS } @Override - public Optional parseAttribute(String attrName, Object value) { + public Optional parseAttribute(String attrName, Object value) throws NetconfDocumentedException { if (value == null) { return Optional.absent(); } @@ -70,32 +73,42 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS } static interface Resolver { - Object resolveObject(Class type, String attrName, String value); + Object resolveObject(Class type, String attrName, String value) throws NetconfDocumentedException; } static class DefaultResolver implements Resolver { @Override - public Object resolveObject(Class type, String attrName, String value) { + public Object resolveObject(Class type, String attrName, String value) throws NetconfDocumentedException { try { - Object parsedValue = parseObject(type, value); - return parsedValue; + return parseObject(type, value); } catch (Exception e) { - throw new RuntimeException("Unable to resolve attribute " + attrName + " from " + value, e); + throw new NetconfDocumentedException("Unable to resolve attribute " + attrName + " from " + value, + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); } } - protected Object parseObject(Class type, String value) throws Exception { - Method method = type.getMethod("valueOf", String.class); - Object parsedValue = method.invoke(null, value); - return parsedValue; + protected Object parseObject(Class type, String value) throws NetconfDocumentedException { + Method method = null; + try { + method = type.getMethod("valueOf", String.class); + return method.invoke(null, value); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + logger.trace("Error parsing object {}",e); + throw new NetconfDocumentedException("Error parsing object.", + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } } } static class StringResolver extends DefaultResolver { @Override - protected Object parseObject(Class type, String value) throws Exception { + protected Object parseObject(Class type, String value) { return value; } } @@ -103,7 +116,7 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS static class BigIntegerResolver extends DefaultResolver { @Override - protected Object parseObject(Class type, String value) throws Exception { + protected Object parseObject(Class type, String value) { return new BigInteger(value); } } @@ -111,7 +124,7 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS static class BigDecimalResolver extends DefaultResolver { @Override - protected Object parseObject(Class type, String value) throws Exception { + protected Object parseObject(Class type, String value) { return new BigDecimal(value); } } @@ -119,16 +132,23 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS static class CharResolver extends DefaultResolver { @Override - protected Object parseObject(Class type, String value) throws Exception { + protected Object parseObject(Class type, String value) { return new Character(value.charAt(0)); } } static class DateResolver extends DefaultResolver { - @Override - protected Object parseObject(Class type, String value) throws Exception { - return Util.readDate(value); + protected Object parseObject(Class type, String value) throws NetconfDocumentedException { + try { + return Util.readDate(value); + } catch (ParseException e) { + logger.trace("Unable parse value {} due to {}",value, e); + throw new NetconfDocumentedException("Unable to parse value "+value+" as date.", + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java index bc99ecf09a..cdebcfaa34 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/UnionCompositeAttributeResolvingStrategy.java @@ -34,10 +34,11 @@ final class UnionCompositeAttributeResolvingStrategy extends CompositeAttributeR Map newMap = Maps.newHashMap(); for (String key : openType.keySet()) { - if (openType.getDescription(key).equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)) + if (openType.getDescription(key).equals(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)){ newMap.put(key, valueMap.get(JavaAttribute.DESCRIPTION_OF_VALUE_ATTRIBUTE_FOR_UNION)); - else + } else { newMap.put(key, null); + } } return newMap; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java new file mode 100644 index 0000000000..61465f93e8 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java @@ -0,0 +1,14 @@ +/* + * 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.mapping.attributes.toxml; + +public abstract class AbstractAttributeWritingStrategy { + protected Object preprocess(Object value) { + return value; + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java index 051f365086..b17842b8e2 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/CompositeAttributeWritingStrategy.java @@ -20,9 +20,9 @@ import com.google.common.base.Optional; public class CompositeAttributeWritingStrategy implements AttributeWritingStrategy { - protected final String key; - protected final Document document; - protected final Map innerStrats; + private final String key; + private final Document document; + private final Map innerStrats; public CompositeAttributeWritingStrategy(Document document, String key, Map innerStrats) { @@ -49,4 +49,16 @@ public class CompositeAttributeWritingStrategy implements AttributeWritingStrate } parentElement.appendChild(innerNode); } + + public String getKey() { + return key; + } + + public Document getDocument() { + return document; + } + + public Map getInnerStrats() { + return innerStrats; + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java index 8d63bb05d8..4e07ec8c31 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java @@ -90,11 +90,11 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement innerStrats = Maps.newHashMap(); String currentKey = key; - for (Entry innerAttrEntry : ((TOAttribute) lastAttribute).getYangPropertiesToTypesMap().entrySet()) { + for (Entry innerAttrEntry : ((TOAttribute) getLastAttribute()).getYangPropertiesToTypesMap().entrySet()) { AttributeWritingStrategy innerStrategy = prepareWritingStrategy(innerAttrEntry.getKey(), innerAttrEntry.getValue(), document); @@ -106,8 +106,8 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement openType) { - Preconditions.checkState(lastAttribute instanceof ListAttribute); - AttributeIfc innerAttribute = ((ListAttribute) lastAttribute).getInnerAttribute(); + Preconditions.checkState(getLastAttribute() instanceof ListAttribute); + AttributeIfc innerAttribute = ((ListAttribute) getLastAttribute()).getInnerAttribute(); AttributeWritingStrategy innerStrategy = prepareWritingStrategy(key, innerAttribute, document); return new ArrayAttributeWritingStrategy(innerStrategy); @@ -115,7 +115,7 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement openType) { - Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + Preconditions.checkState(getLastAttribute() instanceof ListDependenciesAttribute); AttributeWritingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME); return new ArrayAttributeWritingStrategy(innerStrategy); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java index b2555f712a..a74afd0812 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java @@ -8,15 +8,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml; -import java.util.Map; -import java.util.Map.Entry; - +import com.google.common.base.Optional; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; +import java.util.Map; +import java.util.Map.Entry; public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingStrategy { @@ -36,7 +35,7 @@ public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingSt public void writeElement(Element parentElement, String namespace, Object value) { Util.checkType(value, Map.class); - Element innerNode = XmlUtil.createElement(document, key, Optional.absent()); + Element innerNode = XmlUtil.createElement(getDocument(), getKey(), Optional.absent()); Map map = (Map) value; @@ -46,7 +45,7 @@ public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingSt // bean Util.checkType(runtimeBeanInstanceMappingEntry.getValue(), Map.class); Map innerMap = (Map) runtimeBeanInstanceMappingEntry.getValue(); - Element runtimeInstanceNode = XmlUtil.createElement(document, "_" + Element runtimeInstanceNode = XmlUtil.createElement(getDocument(), "_" + (String) runtimeBeanInstanceMappingEntry.getKey(), Optional.absent()); innerNode.appendChild(runtimeInstanceNode); @@ -57,7 +56,7 @@ public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingSt String innerKey = (String) innerObjectEntry.getKey(); Object innerValue = innerObjectEntry.getValue(); - innerStrats.get(innerKey).writeElement(runtimeInstanceNode, namespace, innerValue); + getInnerStrats().get(innerKey).writeElement(runtimeInstanceNode, namespace, innerValue); } } parentElement.appendChild(innerNode); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java index 1b15171ca0..12988071ba 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleAttributeWritingStrategy.java @@ -43,7 +43,6 @@ public class SimpleAttributeWritingStrategy implements AttributeWritingStrategy typeElement.appendChild(document.createTextNode(value)); return typeElement; } - protected Object preprocess(Object value) { return value; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java index c159e46987..4e92c26e36 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleBinaryAttributeWritingStrategy.java @@ -25,6 +25,7 @@ public class SimpleBinaryAttributeWritingStrategy extends SimpleAttributeWriting super(document, key); } + @Override protected Object preprocess(Object value) { Util.checkType(value, List.class); BaseEncoding en = BaseEncoding.base64(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java index 68d31ae207..ed3bb2a9d9 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java @@ -21,7 +21,6 @@ import com.google.common.base.Preconditions; public class SimpleIdentityRefAttributeWritingStrategy extends SimpleAttributeWritingStrategy { - private static final char QNAME_SEPARATOR = ':'; private static final String PREFIX = "prefix"; /** diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java index bb5a67cb9c..854f99c5c0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java @@ -8,20 +8,20 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import static com.google.common.base.Preconditions.checkState; -import static java.lang.String.format; - +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; - import javax.management.ObjectName; - import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; @@ -29,24 +29,15 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi 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.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; +import static com.google.common.base.Preconditions.checkState; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; public class Config { - private final Logger logger = LoggerFactory.getLogger(Config.class); private final Map> moduleConfigs; - private final Map moduleNamesToConfigs; private final Map> identityMap; @@ -56,11 +47,6 @@ public class Config { public Config(Map> moduleConfigs, Map> identityMap) { this.moduleConfigs = moduleConfigs; - Map moduleNamesToConfigs = new HashMap<>(); - for (Entry> entry : moduleConfigs.entrySet()) { - moduleNamesToConfigs.putAll(entry.getValue()); - } - this.moduleNamesToConfigs = Collections.unmodifiableMap(moduleNamesToConfigs); this.identityMap = identityMap; } @@ -82,8 +68,9 @@ public class Config { // TODO, this code does not support same module names from different namespaces // Namespace should be present in ObjectName - if (instances == null) + if (instances == null){ continue; + } innerRetVal.put(moduleName, instances); @@ -104,11 +91,6 @@ public class Config { return retVal; } - // public Element toXml(Set instancesToMap, String namespace, - // Document document) { - // return toXml(instancesToMap, Optional.of(namespace), document); - // } - public Element toXml(Set instancesToMap, Optional maybeNamespace, Document document, Element dataElement, ServiceRegistryWrapper serviceTracker) { @@ -264,10 +246,12 @@ public class Config { Optional modulesOpt = getModulesElement(parent); List recognised = Lists.newArrayList(); - if(servicesOpt.isPresent()) + if(servicesOpt.isPresent()){ recognised.add(servicesOpt.get()); - if(modulesOpt.isPresent()) + } + if(modulesOpt.isPresent()){ recognised.add(modulesOpt.get()); + } parent.checkUnrecognisedElements(recognised); } @@ -275,7 +259,7 @@ public class Config { private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) { checkState( factoryNameWithPrefix.startsWith(prefixOrEmptyString), - format("Internal error: text " + "content '%s' of type node does not start with prefix '%s'", + String.format("Internal error: text " + "content '%s' of type node does not start with prefix '%s'", factoryNameWithPrefix, prefixOrEmptyString)); int factoryNameAfterPrefixIndex; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java index 1da9fabdb3..0fe5fad29c 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java @@ -63,26 +63,24 @@ public final class InstanceConfig { Map toXml = Maps.newHashMap(); for (Entry configDefEntry : jmxToAttrConfig.entrySet()) { - // Skip children runtime beans as they are mapped by InstanceRuntime - if (configDefEntry.getValue() instanceof RuntimeBeanEntry) + if (configDefEntry.getValue() instanceof RuntimeBeanEntry){ continue; - + } Object value = configRegistryClient.getAttributeCurrentValue(on, configDefEntry.getKey()); try { AttributeMappingStrategy> attributeMappingStrategy = mappingStrategies .get(configDefEntry.getKey()); Optional a = attributeMappingStrategy.mapAttribute(value); - if (a.isPresent() == false) + if (!a.isPresent()){ continue; - + } toXml.put(configDefEntry.getValue().getAttributeYangName(), a.get()); } catch (Exception e) { throw new IllegalStateException("Unable to map value " + value + " to attribute " + configDefEntry.getKey(), e); } } - return toXml; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java index 0d55902b12..c9605af586 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java @@ -9,15 +9,13 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; import com.google.common.collect.Multimap; +import java.util.Map; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy; -import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; -import java.util.Map; - /** * Parsed xml element containing whole configuration for an instance of some * module. Contains preferred edit strategy type. @@ -44,16 +42,6 @@ public class InstanceConfigElementResolved { static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) throws OperationNotPermittedException { - if (null == currentStrategy || currentStrategy.equals("")){ - throw new OperationNotPermittedException(String.format("With " - + defaultStrategy - + " as " - + EditConfigXmlParser.DEFAULT_OPERATION_KEY - + " operations on module elements are not permitted since the default option is restrictive"), - NetconfDocumentedException.ErrorType.application, - NetconfDocumentedException.ErrorTag.operation_failed, - NetconfDocumentedException.ErrorSeverity.error); - } EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy); EditStrategyType.compareParsedStrategyToDefaultEnforcing(parsedStrategy,defaultStrategy); return parsedStrategy; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java index f3d75d07be..a5a625a2d6 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java @@ -8,12 +8,9 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import java.util.Collection; -import java.util.Date; -import java.util.Map; - -import javax.management.ObjectName; - +import com.google.common.base.Optional; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; @@ -25,9 +22,10 @@ import org.opendaylight.yangtools.yang.common.QName; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; +import javax.management.ObjectName; +import java.util.Collection; +import java.util.Date; +import java.util.Map; public class ModuleConfig { @@ -64,7 +62,7 @@ public class ModuleConfig { Element root = XmlUtil.createElement(document, XmlNetconfConstants.MODULE_KEY, Optional.absent()); // Xml.addNamespaceAttr(document, root, namespace); - final String prefix = getPrefix(namespace); + final String prefix = getPrefix(); Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(prefix, XmlNetconfConstants.TYPE_KEY), prefix, moduleName, Optional.of(namespace)); // Xml.addNamespaceAttr(document, typeElement, @@ -82,12 +80,8 @@ public class ModuleConfig { return root; } - private String getPrefix(String namespace) { - // if(namespace.contains(":")==false) + private String getPrefix() { return XmlNetconfConstants.PREFIX; - // return namespace.substring(namespace.lastIndexOf(':') + 1, - // namespace.length()); - } public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName, diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java index d1c3ebeb0d..b772eee0d7 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java @@ -27,20 +27,22 @@ public class ModuleElementDefinition { public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) { this.instanceName = instanceName; - EditStrategyType _edStrategy = null; - try { - _edStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy); - } catch (OperationNotPermittedException e) { - _edStrategy = defaultStrategy; - logger.warn("Operation not permitted on current strategy {} while default strategy is {}. Element definition strategy set to default.", - currentStrategy, - defaultStrategy, - e); + if (currentStrategy == null || currentStrategy.isEmpty()) { + this.editStrategy = defaultStrategy; + } else { + EditStrategyType _edStrategy = null; + try { + _edStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy); + } catch (OperationNotPermittedException e) { + _edStrategy = defaultStrategy; + logger.warn("Operation not permitted on current strategy {} while default strategy is {}. Element definition strategy set to default.", + currentStrategy, + defaultStrategy, + e); + } + this.editStrategy = _edStrategy; } - if (currentStrategy == null || currentStrategy.isEmpty()) - _edStrategy = defaultStrategy; - this.editStrategy = _edStrategy; } public String getInstanceName() { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java index 8d2d149822..1f63555e83 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java @@ -35,7 +35,9 @@ public class ServiceRegistryWrapper { public boolean hasRefName(String namespace, String serviceName, ObjectName on) { String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName); Map forQName = configServiceRefRegistry.getServiceMapping().get(qname); - if(forQName==null) return false; + if(forQName==null){ + return false; + } return forQName.values().contains(on); } @@ -70,7 +72,7 @@ public class ServiceRegistryWrapper { Map>> retVal = Maps.newHashMap(); Map> serviceMapping = configServiceRefRegistry.getServiceMapping(); - for (String serviceQName : serviceMapping.keySet()) + for (String serviceQName : serviceMapping.keySet()){ for (String refName : serviceMapping.get(serviceQName).keySet()) { ObjectName on = serviceMapping.get(serviceQName).get(refName); @@ -91,11 +93,12 @@ public class ServiceRegistryWrapper { serviceToRefs.put(localName, refsToSis); } - Preconditions.checkState(refsToSis.containsKey(refName) == false, + Preconditions.checkState(!refsToSis.containsKey(refName), "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace, localName, on); refsToSis.put(refName, si.toString()); } + } return retVal; } @@ -108,10 +111,11 @@ public class ServiceRegistryWrapper { Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); Map refNameToInstance; - if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) { + if(serviceNameToRefNameToInstance == null || !serviceNameToRefNameToInstance.containsKey(serviceName)) { refNameToInstance = Collections.emptyMap(); - } else + } else { refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); + } final Set refNamesAsSet = toSet(refNameToInstance.keySet()); if (refNamesAsSet.contains(refName)) { @@ -135,12 +139,13 @@ public class ServiceRegistryWrapper { } private String findAvailableRefName(String refName, Set refNamesAsSet) { - String intitialRefName = refName; + String availableRefName = ""; while (true) { - refName = intitialRefName + "_" + suffix++; - if (refNamesAsSet.contains(refName) == false) - return refName; + availableRefName = refName + "_" + suffix++; + if (!refNamesAsSet.contains(availableRefName)){ + return availableRefName; + } } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java index f9df717008..eb5c018cf3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java @@ -8,33 +8,27 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.management.ObjectName; - +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.Maps; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy; 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.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; +import javax.management.ObjectName; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public final class Services { - private static final Logger logger = LoggerFactory.getLogger(Services.class); - private static final String PROVIDER_KEY = "provider"; private static final String NAME_KEY = "name"; public static final String TYPE_KEY = "type"; @@ -98,7 +92,7 @@ public final class Services { XmlElement typeElement = service.getOnlyChildElement(TYPE_KEY); Entry prefixNamespace = typeElement.findNamespaceOfTextContent(); - Preconditions.checkState(prefixNamespace.getKey()!=null && prefixNamespace.getKey().equals("") == false, "Type attribute was not prefixed"); + Preconditions.checkState(prefixNamespace.getKey()!=null && !prefixNamespace.getKey().equals(""), "Type attribute was not prefixed"); Map> namespaceToServices = retVal.get(prefixNamespace.getValue()); if(namespaceToServices == null) { @@ -169,7 +163,7 @@ public final class Services { public static ServiceInstance fromString(String instanceId) { instanceId = instanceId.trim(); Matcher matcher = p.matcher(instanceId); - if(matcher.matches() == false) { + if(!matcher.matches()) { matcher = pDeprecated.matcher(instanceId); } @@ -237,23 +231,30 @@ public final class Services { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj){ return true; - if (obj == null) + } + if (obj == null){ return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()){ return false; + } ServiceInstance other = (ServiceInstance) obj; if (instanceName == null) { - if (other.instanceName != null) + if (other.instanceName != null){ return false; - } else if (!instanceName.equals(other.instanceName)) + } + } else if (!instanceName.equals(other.instanceName)){ return false; + } if (moduleName == null) { - if (other.moduleName != null) + if (other.moduleName != null){ return false; - } else if (!moduleName.equals(other.moduleName)) + } + } else if (!moduleName.equals(other.moduleName)){ return false; + } return true; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java index a081890d39..28b1417893 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java @@ -17,12 +17,12 @@ import java.util.Map; public final class ModuleRpcs { - Map yangToJavaNames = Maps.newHashMap(); - Map> rpcMapping = Maps.newHashMap(); + private final Map yangToJavaNames = Maps.newHashMap(); + private final Map> rpcMapping = Maps.newHashMap(); public void addNameMapping(RuntimeBeanEntry runtimeEntry) { String yangName = runtimeEntry.getYangName(); - Preconditions.checkState(yangToJavaNames.containsKey(yangName) == false, + Preconditions.checkState(!yangToJavaNames.containsKey(yangName), "RuntimeBean %s found twice in same namespace", yangName); yangToJavaNames.put(yangName, runtimeEntry.getJavaNamePrefix()); } @@ -35,7 +35,7 @@ public final class ModuleRpcs { rpcMapping.put(yangName, map); } - Preconditions.checkState(map.containsKey(rpc.getYangName()) == false, "Rpc %s for runtime bean %s added twice", + Preconditions.checkState(!map.containsKey(rpc.getYangName()), "Rpc %s for runtime bean %s added twice", rpc.getYangName(), yangName); map.put(rpc.getYangName(), new InstanceRuntimeRpc(rpc)); } @@ -55,4 +55,12 @@ public final class ModuleRpcs { Preconditions.checkState(rpc != null, "No rpc found for runtime bean %s with name %s", rbeName, rpcName); return rpc; } + + public Map getYangToJavaNames() { + return yangToJavaNames; + } + + public Map> getRpcMapping() { + return rpcMapping; + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java index 8c3b35122c..6a49275f26 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java @@ -8,22 +8,19 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime; -import java.util.Hashtable; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import javax.management.ObjectName; - +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.Sets; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.google.common.collect.Sets; +import javax.management.ObjectName; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; public class InstanceRuntime { @@ -48,20 +45,23 @@ public class InstanceRuntime { * root + any number of additional properties */ private Set findChildren(ObjectName innerRootBean, Set childRbeOns) { - final Hashtable wantedProperties = innerRootBean.getKeyPropertyList(); + final Map wantedProperties = innerRootBean.getKeyPropertyList(); return Sets.newHashSet(Collections2.filter(childRbeOns, new Predicate() { @Override public boolean apply(ObjectName on) { - Hashtable localProperties = on.getKeyPropertyList(); + Map localProperties = on.getKeyPropertyList(); for (Entry propertyEntry : wantedProperties.entrySet()) { - if (!localProperties.containsKey(propertyEntry.getKey())) + if (!localProperties.containsKey(propertyEntry.getKey())){ return false; - if (!localProperties.get(propertyEntry.getKey()).equals(propertyEntry.getValue())) + } + if (!localProperties.get(propertyEntry.getKey()).equals(propertyEntry.getValue())){ return false; - if (localProperties.size() <= wantedProperties.size()) + } + if (localProperties.size() <= wantedProperties.size()){ return false; + } } return true; } @@ -77,10 +77,12 @@ public class InstanceRuntime { @Override public boolean apply(ObjectName on) { - if (on.getKeyPropertyList().size() != keyListSize + 1) + if (on.getKeyPropertyList().size() != keyListSize + 1){ return false; - if (!on.getKeyPropertyList().containsKey(string)) + } + if (!on.getKeyPropertyList().containsKey(string)){ return false; + } return true; } })); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java index 4936d1dbcd..59767fec6e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java @@ -20,11 +20,9 @@ import java.util.Set; public class ModuleRuntime { - private final String moduleName; private final InstanceRuntime instanceRuntime; public ModuleRuntime(String moduleName, InstanceRuntime instanceRuntime) { - this.moduleName = moduleName; this.instanceRuntime = instanceRuntime; } @@ -34,8 +32,9 @@ public class ModuleRuntime { private ObjectName findRoot(Collection runtimeBeanOns) { for (ObjectName objectName : runtimeBeanOns) { - if (objectName.getKeyPropertyList().size() == 3) + if (objectName.getKeyPropertyList().size() == 3){ return objectName; + } } throw new IllegalStateException("Root runtime bean not found among " + runtimeBeanOns); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java index 8fc3ee1423..439dea2a80 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java @@ -85,7 +85,7 @@ public class Runtime { Element runtimeXml; ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName); - if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) { + if(instanceToRbe==null || !instanceToRbe.containsKey(instanceName)) { runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace); } else { ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName); @@ -101,14 +101,4 @@ public class Runtime { return root; } - private ObjectName findInstance(Collection objectNames, String instanceName) { - for (ObjectName objectName : objectNames) { - String name = ObjectNameUtil.getInstanceName(objectName); - if(name.equals(instanceName)) - return objectName; - } - - throw new UnsupportedOperationException("Unable to find config bean instance under name " + instanceName + " among " + objectNames); - } - } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java index cd99ac4d8d..c4217106ce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java @@ -13,11 +13,15 @@ import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOpera public abstract class AbstractConfigNetconfOperation extends AbstractLastNetconfOperation { - protected final ConfigRegistryClient configRegistryClient; + private final ConfigRegistryClient configRegistryClient; protected AbstractConfigNetconfOperation(ConfigRegistryClient configRegistryClient, String netconfSessionIdForReporting) { super(netconfSessionIdForReporting); this.configRegistryClient = configRegistryClient; } + + public ConfigRegistryClient getConfigRegistryClient() { + return configRegistryClient; + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java index e88863c685..c5fadb097f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java @@ -8,8 +8,9 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; +import java.util.Map; +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; @@ -18,23 +19,10 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; -import java.util.Map; - public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy { private static final Logger logger = LoggerFactory.getLogger(DeleteEditConfigStrategy.class); - private final Multimap providedServices; - - public DeleteEditConfigStrategy() { - this.providedServices = HashMultimap.create(); - } - - public DeleteEditConfigStrategy(Multimap providedServices) { - this.providedServices = providedServices; - } @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java index 428ddb3b74..3ea26055f3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java @@ -72,11 +72,11 @@ public class EditConfig extends AbstractConfigNetconfOperation { final EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException, NetconfConfigHandlingException { if (editConfigExecution.shouldTest()) { - executeTests(configRegistryClient, editConfigExecution); + executeTests(getConfigRegistryClient(), editConfigExecution); } if (editConfigExecution.shouldSet()) { - executeSet(configRegistryClient, editConfigExecution); + executeSet(getConfigRegistryClient(), editConfigExecution); } logger.trace("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG); @@ -224,7 +224,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { void addIdSchemaNode(IdentitySchemaNode node) { String name = node.getQName().getLocalName(); - Preconditions.checkState(identityNameToSchemaNode.containsKey(name) == false); + Preconditions.checkState(!identityNameToSchemaNode.containsKey(name)); identityNameToSchemaNode.put(name, node); } @@ -250,7 +250,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { } Date revision = module.getRevision(); - Preconditions.checkState(revisionsByNamespace.containsKey(revision) == false, + Preconditions.checkState(!revisionsByNamespace.containsKey(revision), "Duplicate revision %s for namespace %s", revision, namespace); IdentityMapping identityMapping = revisionsByNamespace.get(revision); @@ -306,8 +306,8 @@ public class EditConfig extends AbstractConfigNetconfOperation { protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { EditConfigXmlParser.EditConfigExecution editConfigExecution; - Config cfg = getConfigMapping(configRegistryClient, yangStoreSnapshot); - editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, configRegistryClient); + Config cfg = getConfigMapping(getConfigRegistryClient(), yangStoreSnapshot); + editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, getConfigRegistryClient()); Element responseInternal; responseInternal = getResponseInternal(document, editConfigExecution); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java index de6979565e..547ffcda3d 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java @@ -98,9 +98,10 @@ public class EditConfigXmlParser { .getOnlyChildElementWithSameNamespaceOptionally(EditConfigXmlParser.ERROR_OPTION_KEY); if (errorOptionElement.isPresent()) { String errorOptionParsed = errorOptionElement.get().getTextContent(); - if (false == errorOptionParsed.equals(EditConfigXmlParser.DEFAULT_ERROR_OPTION)) + if (!errorOptionParsed.equals(EditConfigXmlParser.DEFAULT_ERROR_OPTION)){ throw new UnsupportedOperationException("Only " + EditConfigXmlParser.DEFAULT_ERROR_OPTION + " supported for " + EditConfigXmlParser.ERROR_OPTION_KEY + ", was " + errorOptionParsed); + } } // Default op diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java index 2f41defac8..6b81603dcd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java @@ -65,7 +65,7 @@ public enum EditStrategyType { case replace: return new ReplaceEditConfigStrategy(providedServices); case delete: - return new DeleteEditConfigStrategy(providedServices); + return new DeleteEditConfigStrategy(); case remove: return new RemoveEditConfigStrategy(); case none: diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java index 0a72547d78..3e5707cf6d 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java @@ -54,8 +54,9 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), - namespaceToService.getValue(), on)) + namespaceToService.getValue(), on)){ continue; + } String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java index b61fcbadc0..bc3082ff50 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java @@ -55,8 +55,9 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), - namespaceToService.getValue(), on)) + namespaceToService.getValue(), on)){ continue; + } String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java index dd0e53b1bb..4665c2cc89 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java @@ -69,12 +69,14 @@ public class Get extends AbstractConfigNetconfOperation { RuntimeBeanEntry root = null; for (RuntimeBeanEntry rbe : mbe.getRuntimeBeans()) { cache.put(rbe, new InstanceConfig(configRegistryClient, rbe.getYangPropertiesToTypesMap())); - if (rbe.isRoot()) + if (rbe.isRoot()){ root = rbe; + } } - if (root == null) + if (root == null){ continue; + } InstanceRuntime rootInstanceRuntime = createInstanceRuntime(root, cache); ModuleRuntime moduleRuntime = new ModuleRuntime(module, rootInstanceRuntime); @@ -108,8 +110,9 @@ public class Get extends AbstractConfigNetconfOperation { xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); // Filter option - unsupported - if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0) + if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0){ throw new UnsupportedOperationException("Unsupported option " + XmlNetconfConstants.FILTER + " for " + XmlNetconfConstants.GET); + } } @Override @@ -121,21 +124,21 @@ public class Get extends AbstractConfigNetconfOperation { protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { checkXml(xml); - final Set runtimeBeans = configRegistryClient.lookupRuntimeBeans(); + final Set runtimeBeans = getConfigRegistryClient().lookupRuntimeBeans(); //Transaction provider required only for candidate datastore final Set configBeans = Datastore.getInstanceQueryStrategy(Datastore.running, null) - .queryInstances(configRegistryClient); + .queryInstances(getConfigRegistryClient()); - final Map> moduleRuntimes = createModuleRuntimes(configRegistryClient, + final Map> moduleRuntimes = createModuleRuntimes(getConfigRegistryClient(), yangStoreSnapshot.getModuleMXBeanEntryMap()); final Map> moduleConfigs = EditConfig.transformMbeToModuleConfigs( - configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap()); + getConfigRegistryClient(), yangStoreSnapshot.getModuleMXBeanEntryMap()); final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs); ObjectName txOn = transactionProvider.getOrCreateTransaction(); - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn); + ConfigTransactionClient ta = getConfigRegistryClient().getConfigTransactionClient(txOn); final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta)); logger.trace("{} operation successful", XmlNetconfConstants.GET); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java index 11d3e32edf..82e07c1e7b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java @@ -66,9 +66,10 @@ public class GetConfig extends AbstractConfigNetconfOperation { Datastore sourceDatastore = Datastore.valueOf(sourceParsed); // Filter option - unsupported - if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0) + if (xml.getChildElements(XmlNetconfConstants.FILTER).size() != 0){ throw new UnsupportedOperationException("Unsupported option " + XmlNetconfConstants.FILTER + " for " + GET_CONFIG); + } return sourceDatastore; @@ -104,6 +105,6 @@ public class GetConfig extends AbstractConfigNetconfOperation { public Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { Datastore source; source = fromXml(xml); - return getResponseInternal(document, configRegistryClient, source); + return getResponseInternal(document, getConfigRegistryClient(), source); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java index 5a30fc8352..7790e09cee 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java @@ -139,8 +139,9 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { final Optional contextInstanceElement = operationElement .getOnlyChildElementOptionally(CONTEXT_INSTANCE); - if (contextInstanceElement.isPresent() == false) + if (!contextInstanceElement.isPresent()){ return HandlingPriority.CANNOT_HANDLE; + } final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get() .getTextContent(), netconfOperationName, netconfOperationNamespace); @@ -182,7 +183,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { logger.debug("Invoking operation {} on {} with arguments {}", execution.operationName, execution.on, execution.attributes); - final Object result = executeOperation(configRegistryClient, execution.on, execution.operationName, + final Object result = executeOperation(getConfigRegistryClient(), execution.on, execution.operationName, execution.attributes); logger.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.operationName, @@ -225,7 +226,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { for (XmlElement xmlElement : xml.getChildElements()) { final String name = xmlElement.getName(); - if (CONTEXT_INSTANCE.equals(name) == false) { // skip context + if (!CONTEXT_INSTANCE.equals(name)) { // skip context // instance child node // because it // specifies diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java index 0f0b1227a6..5cf7f30abc 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpcElementResolved.java @@ -93,12 +93,12 @@ public final class RuntimeRpcElementResolved { RuntimeRpc.CONTEXT_INSTANCE, xpath, elementName, xpathPatternBlueprint); PatternGroupResolver groups = new PatternGroupResolver(matcher.group("key1"), matcher.group("value1"), - matcher.group("key2"), matcher.group("value2"), matcher.group("additional")); + matcher.group("value2"), matcher.group("additional")); String moduleName = groups.getModuleName(); String instanceName = groups.getInstanceName(); - HashMap additionalAttributes = groups.getAdditionalKeys(elementName, moduleName); + Map additionalAttributes = groups.getAdditionalKeys(elementName, moduleName); return new RuntimeRpcElementResolved(namespace, moduleName, instanceName, groups.getRuntimeBeanYangName(), additionalAttributes); @@ -106,15 +106,14 @@ public final class RuntimeRpcElementResolved { private static final class PatternGroupResolver { - private final String key1, key2, value1, value2; + private final String key1, value1, value2; private final String additional; private String runtimeBeanYangName; - PatternGroupResolver(String key1, String value1, String key2, String value2, String additional) { + PatternGroupResolver(String key1, String value1, String value2, String additional) { this.key1 = Preconditions.checkNotNull(key1); this.value1 = Preconditions.checkNotNull(value1); - this.key2 = Preconditions.checkNotNull(key2); this.value2 = Preconditions.checkNotNull(value2); this.additional = Preconditions.checkNotNull(additional); @@ -128,13 +127,14 @@ public final class RuntimeRpcElementResolved { return key1.equals(XmlNetconfConstants.NAME_KEY) ? value1 : value2; } - HashMap getAdditionalKeys(String elementName, String moduleName) { + Map getAdditionalKeys(String elementName, String moduleName) { HashMap additionalAttributes = Maps.newHashMap(); runtimeBeanYangName = moduleName; for (String additionalKeyValue : additional.split("/")) { - if (Strings.isNullOrEmpty(additionalKeyValue)) + if (Strings.isNullOrEmpty(additionalKeyValue)){ continue; + } Matcher matcher = additionalPattern.matcher(additionalKeyValue); Preconditions .checkState( diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java index 421870ca36..3ba92b092e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java @@ -73,7 +73,7 @@ public class Activator implements BundleActivator { } @Override - public void stop(BundleContext context) throws Exception { + public void stop(BundleContext context) { if (configRegistryLookup != null) { configRegistryLookup.interrupt(); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java index 09966b8c3b..7f4f8fccb5 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java @@ -24,17 +24,11 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import java.util.Set; final class NetconfOperationProvider { - private final YangStoreSnapshot yangStoreSnapshot; private final Set operations; - private final ConfigRegistryClient configRegistryClient; - private final TransactionProvider transactionProvider; NetconfOperationProvider(YangStoreSnapshot yangStoreSnapshot, ConfigRegistryClient configRegistryClient, TransactionProvider transactionProvider, String netconfSessionIdForReporting) { - this.yangStoreSnapshot = yangStoreSnapshot; - this.configRegistryClient = configRegistryClient; - this.transactionProvider = transactionProvider; operations = setUpOperations(yangStoreSnapshot, configRegistryClient, transactionProvider, netconfSessionIdForReporting); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java index b8b7fcb47f..12469f66b7 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java @@ -52,7 +52,7 @@ public class NetconfOperationServiceFactoryImpl implements NetconfOperationServi Thread.sleep(ATTEMPT_TIMEOUT_MS); } catch (InterruptedException e1) { Thread.currentThread().interrupt(); - throw new RuntimeException("Interrupted while reattempting connection", e1); + throw new IllegalStateException("Interrupted while reattempting connection", e1); } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java index c6248df41b..1069858b47 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java @@ -61,8 +61,9 @@ public class NetconfOperationServiceImpl implements NetconfOperationService { for (Map moduleNameToMBE : moduleMXBeanEntryMap.values()) { for (ModuleMXBeanEntry moduleMXBeanEntry : moduleNameToMBE.values()) { String moduleSeenByYangStore = moduleMXBeanEntry.getYangModuleQName().toString(); - if(modulesSeenByConfig.contains(moduleSeenByYangStore) == false) + if(!modulesSeenByConfig.contains(moduleSeenByYangStore)){ missingModulesFromConfig.add(moduleSeenByYangStore); + } } } @@ -149,7 +150,7 @@ public class NetconfOperationServiceImpl implements NetconfOperationService { } } - private static class YangStoreCapability extends BasicCapability { + private static final class YangStoreCapability extends BasicCapability { private final String content; private final String revision; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java index 756a38ed94..250af688ea 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java @@ -34,6 +34,7 @@ public class TransactionProvider implements AutoCloseable { private final String netconfSessionIdForReporting; private ObjectName transaction; private final List allOpenedTransactions = new ArrayList<>(); + private static final String NO_TRANSACTION_FOUND_FOR_SESSION = "No transaction found for session "; public TransactionProvider(ConfigRegistryClient configRegistryClient, String netconfSessionIdForReporting) { this.configRegistryClient = configRegistryClient; @@ -56,11 +57,12 @@ public class TransactionProvider implements AutoCloseable { public Optional getTransaction() { - if (transaction == null) + if (transaction == null){ return Optional.absent(); + } // Transaction was already closed somehow - if (isStillOpenTransaction(transaction) == false) { + if (!isStillOpenTransaction(transaction)) { logger.warn("Fixing illegal state: transaction {} was closed in {}", transaction, netconfSessionIdForReporting); transaction = null; @@ -70,8 +72,7 @@ public class TransactionProvider implements AutoCloseable { } private boolean isStillOpenTransaction(ObjectName transaction) { - boolean isStillOpenTransaction = configRegistryClient.getOpenConfigs().contains(transaction); - return isStillOpenTransaction; + return configRegistryClient.getOpenConfigs().contains(transaction); } public synchronized ObjectName getOrCreateTransaction() { @@ -126,7 +127,7 @@ public class TransactionProvider implements AutoCloseable { public synchronized void abortTransaction() { logger.debug("Aborting current transaction"); Optional taON = getTransaction(); - Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting); + Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get()); transactionClient.abortConfig(); @@ -143,7 +144,7 @@ public class TransactionProvider implements AutoCloseable { public void validateTransaction() throws ValidationException { Optional taON = getTransaction(); - Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting); + Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get()); transactionClient.validateConfig(); @@ -171,10 +172,11 @@ public class TransactionProvider implements AutoCloseable { try { transactionClient.destroyModule(instance); } catch (InstanceNotFoundException e) { - if (isTest) + if (isTest){ logger.debug("Unable to clean configuration in transactiom {}", taON, e); - else + } else { logger.warn("Unable to clean configuration in transactiom {}", taON, e); + } throw new IllegalStateException("Unable to clean configuration in transactiom " + taON, e); } @@ -187,7 +189,7 @@ public class TransactionProvider implements AutoCloseable { public void wipeTransaction() { Optional taON = getTransaction(); - Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting); + Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); wipeInternal(taON.get(), false, null); } 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 f151949abc..2e8d1f64ab 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 @@ -145,7 +145,7 @@ public class NetconfMappingTest extends AbstractConfigTest { this.factory = new NetconfTestImplModuleFactory(); this.factory2 = new DepTestImplModuleFactory(); this.factory3 = new IdentityTestModuleFactory(); - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.factory, this.factory2, + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, this.factory, this.factory2, this.factory3)); transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID); diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java index 1616857949..40a15be706 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/ConfigPersisterNotificationHandler.java @@ -50,7 +50,7 @@ public class ConfigPersisterNotificationHandler implements Closeable { try { mBeanServerConnection.addNotificationListener(DefaultCommitOperationMXBean.OBJECT_NAME, listener, null, null); } catch (InstanceNotFoundException | IOException e) { - throw new RuntimeException("Cannot register as JMX listener to netconf", e); + throw new IllegalStateException("Cannot register as JMX listener to netconf", e); } } @@ -79,9 +79,8 @@ class ConfigPersisterNotificationListener implements NotificationListener { @Override public void handleNotification(Notification notification, Object handback) { - if (notification instanceof NetconfJMXNotification == false) { + if (!(notification instanceof NetconfJMXNotification)) return; - } // Socket should not be closed at this point // Activator unregisters this as JMX listener before close is called diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java index 31a4f08036..a0e7974b94 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterAggregator.java @@ -9,20 +9,19 @@ package org.opendaylight.controller.netconf.persist.impl; import com.google.common.annotations.VisibleForTesting; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.ListIterator; import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; import org.opendaylight.controller.config.persist.api.Persister; +import org.opendaylight.controller.config.persist.api.PropertiesProvider; import org.opendaylight.controller.config.persist.api.StorageAdapter; import org.opendaylight.controller.netconf.persist.impl.osgi.ConfigPersisterActivator; -import org.opendaylight.controller.netconf.persist.impl.osgi.PropertiesProviderBaseImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.ListIterator; - /** * {@link Persister} implementation that delegates persisting functionality to * underlying {@link Persister} storages. Each storage has unique id, class, readonly value. @@ -88,7 +87,7 @@ public final class PersisterAggregator implements Persister { } } - private static PersisterWithConfiguration loadConfiguration(final String index, final PropertiesProviderBaseImpl propertiesProvider) { + private static PersisterWithConfiguration loadConfiguration(final String index, final PropertiesProvider propertiesProvider) { String classKey = index + "." + ConfigPersisterActivator.STORAGE_ADAPTER_CLASS_PROP_SUFFIX; String storageAdapterClass = propertiesProvider.getProperty(classKey); @@ -102,7 +101,7 @@ public final class PersisterAggregator implements Persister { try { Class clazz = Class.forName(storageAdapterClass); boolean implementsCorrectIfc = StorageAdapter.class.isAssignableFrom(clazz); - if (implementsCorrectIfc == false) { + if (!implementsCorrectIfc) { throw new IllegalArgumentException("Storage adapter " + clazz + " does not implement " + StorageAdapter.class); } storageAdapter = StorageAdapter.class.cast(clazz.newInstance()); @@ -131,10 +130,10 @@ public final class PersisterAggregator implements Persister { } - public static PersisterAggregator createFromProperties(PropertiesProviderBaseImpl propertiesProvider) { + public static PersisterAggregator createFromProperties(PropertiesProvider propertiesProvider) { List persisterWithConfigurations = new ArrayList<>(); String prefixes = propertiesProvider.getProperty("active"); - if (prefixes!=null && prefixes.isEmpty() == false) { + if (prefixes!=null && !prefixes.isEmpty()) { String [] keys = prefixes.split(","); for (String index: keys) { persisterWithConfigurations.add(PersisterAggregator.loadConfiguration(index, propertiesProvider)); @@ -169,7 +168,7 @@ public final class PersisterAggregator implements Persister { } catch (IOException e) { throw new RuntimeException("Error while calling loadLastConfig on " + persisterWithConfiguration, e); } - if (configs.isEmpty() == false) { + if (!configs.isEmpty()) { logger.debug("Found non empty configs using {}:{}", persisterWithConfiguration, configs); return configs; } diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java index d9466ff00b..238661f638 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PropertiesProviderAdapterImpl.java @@ -8,13 +8,12 @@ package org.opendaylight.controller.netconf.persist.impl; import org.opendaylight.controller.config.persist.api.PropertiesProvider; -import org.opendaylight.controller.netconf.persist.impl.osgi.PropertiesProviderBaseImpl; public class PropertiesProviderAdapterImpl implements PropertiesProvider { - private final PropertiesProviderBaseImpl inner; + private final PropertiesProvider inner; private final String index; - public PropertiesProviderAdapterImpl(PropertiesProviderBaseImpl inner, String index) { + public PropertiesProviderAdapterImpl(PropertiesProvider inner, String index) { this.inner = inner; this.index = index; } @@ -29,6 +28,12 @@ public class PropertiesProviderAdapterImpl implements PropertiesProvider { return inner.getPrefix() + "." + index + ".properties"; } + @Override + public String getPropertyWithoutPrefix(String fullKey) { + return inner.getPropertyWithoutPrefix(fullKey); + } + + @Override public String getFullKeyForReporting(String key) { return getPrefix() + "." + key; diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java index 1a261da323..87bbb50860 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java @@ -62,7 +62,7 @@ public class ConfigPersisterActivator implements BundleActivator { long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider); List configs = persisterAggregator.loadLastConfigs(); long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider); - logger.trace("Following configs will be pushed: {}", configs); + logger.debug("Following configs will be pushed: {}", configs); InnerCustomizer innerCustomizer = new InnerCustomizer(configs, maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis, persisterAggregator); diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java index b1bf232928..e02e27a745 100644 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java +++ b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java @@ -81,7 +81,7 @@ public class ConfigPersisterTest { // this means pushing of config was successful public void assertCannotRegisterAsJMXListener_pushWasSuccessful() { - handler.assertException(RuntimeException.class, "Cannot register as JMX listener to netconf"); + handler.assertException(IllegalStateException.class, "Cannot register as JMX listener to netconf"); } public NetconfOperationService getWorkingService(Document document) throws SAXException, IOException, NetconfDocumentedException { diff --git a/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java b/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java index 0a084b0ff6..8e62a147d2 100644 --- a/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java +++ b/opendaylight/netconf/ietf-netconf-monitoring/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/netconf/monitoring/rev101004/netconf/state/schemas/LocationBuilder.java @@ -13,7 +13,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.mon /** **/ -public class LocationBuilder { +public final class LocationBuilder { public static Location getDefaultInstance(String defaultValue) { return defaultValue.equals("NETCONF") ? new Location(Location.Enumeration.NETCONF) : new Location(new Uri( diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java new file mode 100644 index 0000000000..d98211d0dd --- /dev/null +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java @@ -0,0 +1,171 @@ +/* + * 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.client; + +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GlobalEventExecutor; + +import java.io.Closeable; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.Set; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.opendaylight.controller.netconf.api.NetconfMessage; +import org.opendaylight.protocol.framework.NeverReconnectStrategy; +import org.opendaylight.protocol.framework.ReconnectStrategy; +import org.opendaylight.protocol.framework.TimedReconnectStrategy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Preconditions; +import com.google.common.base.Stopwatch; +import com.google.common.collect.Sets; + +/** + * @deprecated Use {@link NetconfClientDispatcher.createClient()} or {@link NetconfClientDispatcher.createReconnectingClient()} instead. + */ +@Deprecated +public class NetconfClient implements Closeable { + + private static final Logger logger = LoggerFactory.getLogger(NetconfClient.class); + + public static final int DEFAULT_CONNECT_TIMEOUT = 5000; + private final NetconfClientDispatcher dispatch; + private final String label; + private final NetconfClientSession clientSession; + private final NetconfClientSessionListener sessionListener; + private final long sessionId; + private final InetSocketAddress address; + + // TODO test reconnecting constructor + public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectionAttempts, + int attemptMsTimeout, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this(clientLabelForLogging, address, getReconnectStrategy(connectionAttempts, attemptMsTimeout), + netconfClientDispatcher); + } + + private NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this.label = clientLabelForLogging; + dispatch = netconfClientDispatcher; + sessionListener = new SimpleNetconfClientSessionListener(); + Future clientFuture = dispatch.createClient(address, sessionListener, strat); + this.address = address; + clientSession = get(clientFuture); + this.sessionId = clientSession.getSessionId(); + } + + private NetconfClientSession get(Future clientFuture) throws InterruptedException { + try { + return clientFuture.get(); + } catch (CancellationException e) { + throw new RuntimeException("Cancelling " + this, e); + } catch (ExecutionException e) { + throw new IllegalStateException("Unable to create " + this, e); + } + } + + public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher); + } + + public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, + ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException { + return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher,listener); + } + + public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs, + NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this(clientLabelForLogging, address, + new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, connectTimeoutMs), netconfClientDispatcher); + } + + public NetconfClient(String clientLabelForLogging, InetSocketAddress address, + NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this(clientLabelForLogging, address, new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, + DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher); + } + + public NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy, + NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException{ + this.label = clientLabelForLogging; + dispatch = netconfClientDispatcher; + sessionListener = listener; + Future clientFuture = dispatch.createClient(address, sessionListener, strategy); + this.address = address; + clientSession = get(clientFuture); + this.sessionId = clientSession.getSessionId(); + } + + public Future sendRequest(NetconfMessage message) { + return ((SimpleNetconfClientSessionListener)sessionListener).sendRequest(message); + } + + /** + * @deprecated Use {@link sendRequest} instead + */ + @Deprecated + public NetconfMessage sendMessage(NetconfMessage message) throws ExecutionException, InterruptedException, TimeoutException { + return sendMessage(message, 5, 1000); + } + + /** + * @deprecated Use {@link sendRequest} instead + */ + @Deprecated + public NetconfMessage sendMessage(NetconfMessage message, int attempts, int attemptMsDelay) throws ExecutionException, InterruptedException, TimeoutException { + final Stopwatch stopwatch = new Stopwatch().start(); + + try { + return sendRequest(message).get(attempts * attemptMsDelay, TimeUnit.MILLISECONDS); + } finally { + stopwatch.stop(); + logger.debug("Total time spent waiting for response from {}: {} ms", address, stopwatch.elapsed(TimeUnit.MILLISECONDS)); + } + } + + @Override + public void close() throws IOException { + clientSession.close(); + } + + public NetconfClientDispatcher getNetconfClientDispatcher() { + return dispatch; + } + + private static ReconnectStrategy getReconnectStrategy(int connectionAttempts, int attemptMsTimeout) { + return new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null, + Long.valueOf(connectionAttempts), null); + } + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("NetconfClient{"); + sb.append("label=").append(label); + sb.append(", sessionId=").append(sessionId); + sb.append('}'); + return sb.toString(); + } + + public long getSessionId() { + return sessionId; + } + + public Set getCapabilities() { + Preconditions.checkState(clientSession != null, "Client was not initialized successfully"); + return Sets.newHashSet(clientSession.getServerCapabilities()); + } + + public NetconfClientSession getClientSession() { + return clientSession; + } +} diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java index 20da6aa869..c7c723cb27 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientDispatcher.java @@ -79,7 +79,7 @@ public class NetconfClientDispatcher extends AbstractDispatcher { + private static final class ClientChannelInitializer extends AbstractChannelInitializer { private final NetconfClientSessionNegotiatorFactory negotiatorFactory; private final NetconfClientSessionListener sessionListener; diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSession.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSession.java index ad50fedf6b..f4efb1fc7d 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSession.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSession.java @@ -8,7 +8,8 @@ package org.opendaylight.controller.netconf.client; -import io.netty.channel.Channel; +import java.util.Collection; + import org.opendaylight.controller.netconf.util.AbstractNetconfSession; import org.opendaylight.controller.netconf.util.handler.NetconfEXICodec; import org.opendaylight.controller.netconf.util.handler.NetconfEXIToMessageDecoder; @@ -18,7 +19,7 @@ import org.opendaylight.controller.netconf.util.handler.NetconfXMLToMessageDecod import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Collection; +import io.netty.channel.Channel; public final class NetconfClientSession extends AbstractNetconfSession { @@ -36,7 +37,6 @@ public final class NetconfClientSession extends AbstractNetconfSession @@ -55,19 +58,45 @@ public class NetconfClientSessionNegotiator extends @Override protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException { - NetconfClientSession session = super.getSessionForHelloMessage(netconfMessage); - - if (shouldUseExi(netconfMessage.getDocument())){ - logger.debug("Netconf session: {} should use exi.", session); - tryToStartExi(session); + final NetconfClientSession session = getSessionForHelloMessage(netconfMessage); + replaceHelloMessageInboundHandler(session); + + // If exi should be used, try to initiate exi communication + // Call negotiationSuccessFul after exi negotiation is finished successfully or not + if (shouldUseExi(netconfMessage)) { + logger.debug("Netconf session {} should use exi.", session); + NetconfStartExiMessage startExiMessage = (NetconfStartExiMessage) sessionPreferences.getStartExiMessage(); + tryToInitiateExi(session, startExiMessage); + // Exi is not supported, release session immediately } else { logger.debug("Netconf session {} isn't capable using exi.", session); negotiationSuccessful(session); } } - private boolean shouldUseExi(Document doc) { - return containsExi10Capability(doc) + /** + * Initiates exi communication by sending start-exi message and waiting for positive/negative response. + * + * @param startExiMessage + */ + void tryToInitiateExi(final NetconfClientSession session, final NetconfStartExiMessage startExiMessage) { + session.sendMessage(startExiMessage).addListener(new ChannelFutureListener() { + @Override + public void operationComplete(final ChannelFuture f) { + if (!f.isSuccess()) { + logger.warn("Failed to send start-exi message {} on session {}", startExiMessage, this, f.cause()); + } else { + logger.trace("Start-exi message {} sent to socket on session {}", startExiMessage, this); + channel.pipeline().addAfter( + AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER, + new ExiConfirmationInboundHandler(session, startExiMessage)); + } + } + }); + } + + private boolean shouldUseExi(NetconfHelloMessage helloMsg) { + return containsExi10Capability(helloMsg.getDocument()) && containsExi10Capability(sessionPreferences.getHelloMessage().getDocument()); } @@ -81,23 +110,6 @@ public class NetconfClientSessionNegotiator extends return false; } - private void tryToStartExi(final NetconfClientSession session) { - final NetconfMessage startExi = sessionPreferences.getStartExiMessage(); - session.sendMessage(startExi).addListener(new ChannelFutureListener() { - @Override - public void operationComplete(final ChannelFuture f) { - if (!f.isSuccess()) { - logger.warn("Failed to send start-exi message {} on session {}", startExi, session, f.cause()); - } else { - logger.trace("Start-exi message {} sent to socket on session {}", startExi, session); - NetconfClientSessionNegotiator.this.channel.pipeline().addAfter( - AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, ExiConfirmationInboundHandler.EXI_CONFIRMED_HANDLER, - new ExiConfirmationInboundHandler(session)); - } - } - }); - } - private long extractSessionId(Document doc) { final Node sessionIdNode = (Node) XmlUtil.evaluateXPath(sessionIdXPath, doc, XPathConstants.NODE); String textContent = sessionIdNode.getTextContent(); @@ -109,9 +121,11 @@ public class NetconfClientSessionNegotiator extends } @Override - protected NetconfClientSession getSession(NetconfClientSessionListener sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException { - return new NetconfClientSession(sessionListener, channel, extractSessionId(message.getDocument()), - NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument())); + protected NetconfClientSession getSession(NetconfClientSessionListener sessionListener, Channel channel, + NetconfHelloMessage message) throws NetconfDocumentedException { + long sessionId = extractSessionId(message.getDocument()); + Collection capabilities = NetconfMessageUtil.extractCapabilitiesFromHello(message.getDocument()); + return new NetconfClientSession(sessionListener, channel, sessionId, capabilities); } /** @@ -121,9 +135,11 @@ public class NetconfClientSessionNegotiator extends private static final String EXI_CONFIRMED_HANDLER = "exiConfirmedHandler"; private final NetconfClientSession session; + private NetconfStartExiMessage startExiMessage; - ExiConfirmationInboundHandler(NetconfClientSession session) { + ExiConfirmationInboundHandler(NetconfClientSession session, final NetconfStartExiMessage startExiMessage) { this.session = session; + this.startExiMessage = startExiMessage; } @Override @@ -136,19 +152,19 @@ public class NetconfClientSessionNegotiator extends if (NetconfMessageUtil.isOKMessage(netconfMessage)) { logger.trace("Positive response on start-exi call received on session {}", session); try { - session.startExiCommunication(sessionPreferences.getStartExiMessage()); + session.startExiCommunication(startExiMessage); } catch (RuntimeException e) { // Unable to add exi, continue without exi logger.warn("Unable to start exi communication, Communication will continue without exi on session {}", session, e); } - // Error response + // Error response } else if(NetconfMessageUtil.isErrorMessage(netconfMessage)) { logger.warn( "Error response to start-exi message {}, Communication will continue without exi on session {}", XmlUtil.toString(netconfMessage.getDocument()), session); - // Unexpected response to start-exi, throwing message away, continue without exi + // Unexpected response to start-exi, throwing message away, continue without exi } else { logger.warn( "Unexpected response to start-exi message, should be ok, was {}, " + @@ -159,4 +175,5 @@ public class NetconfClientSessionNegotiator extends negotiationSuccessful(session); } } + } diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java index 9e15b49a84..e65adc3fdf 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java @@ -33,8 +33,8 @@ import org.slf4j.LoggerFactory; public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorFactory { public static final java.util.Set CLIENT_CAPABILITIES = Sets.newHashSet( - XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, - XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1, + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0, + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1, XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0); private static final String START_EXI_MESSAGE_ID = "default-start-exi"; @@ -74,7 +74,7 @@ public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorF throw new IllegalStateException(e); } - NetconfClientSessionPreferences proposal = new NetconfClientSessionPreferences(helloMessage,startExiMessage); + NetconfClientSessionPreferences proposal = new NetconfClientSessionPreferences(helloMessage, startExiMessage); return new NetconfClientSessionNegotiator(proposal, promise, channel, timer, sessionListenerFactory.getSessionListener(),connectionTimeoutMillis); } diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java index 504e4c9949..524f0b52b7 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java @@ -26,8 +26,8 @@ import com.google.common.base.Preconditions; public class SimpleNetconfClientSessionListener implements NetconfClientSessionListener { private static final class RequestEntry { - final Promise promise; - final NetconfMessage request; + private final Promise promise; + private final NetconfMessage request; public RequestEntry(Promise future, NetconfMessage request) { this.promise = Preconditions.checkNotNull(future); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java index 6a86ecd21f..91385bab33 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java @@ -68,12 +68,11 @@ public class CapabilityProviderImpl implements CapabilityProvider { final Set caps = netconfOperationService.getCapabilities(); for (Capability cap : caps) { - if (cap.getModuleName().isPresent() == false) - continue; - if (cap.getRevision().isPresent() == false) - continue; - if (cap.getCapabilitySchema().isPresent() == false) + if (!cap.getModuleName().isPresent() + || !cap.getRevision().isPresent() + || !cap.getCapabilitySchema().isPresent()){ continue; + } final String currentModuleName = cap.getModuleName().get(); Map revisionMap = mappedModulesToRevisionToSchema.get(currentModuleName); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java index 4461054437..203fdf2725 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/DefaultCommitNotificationProducer.java @@ -35,6 +35,7 @@ public class DefaultCommitNotificationProducer extends NotificationBroadcasterSu public DefaultCommitNotificationProducer(MBeanServer mBeanServer) { this.mbeanServer = mBeanServer; + logger.debug("Registering to JMX under {}", on); registerMBean(this, mbeanServer, on); } @@ -42,7 +43,7 @@ public class DefaultCommitNotificationProducer extends NotificationBroadcasterSu try { mbs.registerMBean(instance, on); } catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) { - throw new RuntimeException("Unable to register " + instance + " as " + on, e); + throw new IllegalStateException("Unable to register " + instance + " as " + on, e); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java index b3245fff2b..75be1f8fe0 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java @@ -9,6 +9,8 @@ package org.opendaylight.controller.netconf.impl; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouter; @@ -26,9 +28,6 @@ import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; - public class NetconfServerSessionListener implements NetconfSessionListener { static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionListener.class); @@ -97,8 +96,9 @@ public class NetconfServerSessionListener implements NetconfSessionListener { @@ -32,6 +35,14 @@ public class NetconfServerSessionNegotiator extends super(sessionPreferences, promise, channel, timer, sessionListener, connectionTimeoutMillis); } + @Override + protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException { + NetconfServerSession session = getSessionForHelloMessage(netconfMessage); + replaceHelloMessageInboundHandler(session); + // Negotiation successful after all non hello messages were processed + negotiationSuccessful(session); + } + @Override protected NetconfServerSession getSession(NetconfServerSessionListener sessionListener, Channel channel, NetconfHelloMessage message) { Optional additionalHeader = message.getAdditionalHeader(); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java index 9d95866061..d5a34d11b2 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java @@ -8,10 +8,12 @@ package org.opendaylight.controller.netconf.impl; -import com.google.common.collect.Sets; -import io.netty.channel.Channel; -import io.netty.util.Timer; -import io.netty.util.concurrent.Promise; +import static org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider.NetconfOperationProviderUtil.getNetconfSessionIdForReporting; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import java.util.Set; + import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences; import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; @@ -23,18 +25,22 @@ import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.protocol.framework.SessionListenerFactory; import org.opendaylight.protocol.framework.SessionNegotiator; import org.opendaylight.protocol.framework.SessionNegotiatorFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.util.Set; +import com.google.common.collect.Sets; -import static org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider.NetconfOperationProviderUtil.getNetconfSessionIdForReporting; +import io.netty.channel.Channel; +import io.netty.util.Timer; +import io.netty.util.concurrent.Promise; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory { - private static final Set DEFAULT_CAPABILITIES = Sets.newHashSet( - XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, - XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0); + public static final Set DEFAULT_BASE_CAPABILITIES = ImmutableSet.of( + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0, + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1, + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0 + ); private final Timer timer; @@ -44,16 +50,42 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF private final DefaultCommitNotificationProducer commitNotificationProducer; private final SessionMonitoringService monitoringService; private static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionNegotiatorFactory.class); + private final Set baseCapabilities; + + // TODO too many params, refactor + public NetconfServerSessionNegotiatorFactory(Timer timer, NetconfOperationProvider netconfOperationProvider, + SessionIdProvider idProvider, long connectionTimeoutMillis, + DefaultCommitNotificationProducer commitNot, + SessionMonitoringService monitoringService) { + this(timer, netconfOperationProvider, idProvider, connectionTimeoutMillis, commitNot, monitoringService, DEFAULT_BASE_CAPABILITIES); + } + // TODO too many params, refactor public NetconfServerSessionNegotiatorFactory(Timer timer, NetconfOperationProvider netconfOperationProvider, SessionIdProvider idProvider, long connectionTimeoutMillis, - DefaultCommitNotificationProducer commitNot, SessionMonitoringService monitoringService) { + DefaultCommitNotificationProducer commitNot, + SessionMonitoringService monitoringService, Set baseCapabilities) { this.timer = timer; this.netconfOperationProvider = netconfOperationProvider; this.idProvider = idProvider; this.connectionTimeoutMillis = connectionTimeoutMillis; this.commitNotificationProducer = commitNot; this.monitoringService = monitoringService; + this.baseCapabilities = validateBaseCapabilities(baseCapabilities); + } + + private ImmutableSet validateBaseCapabilities(final Set baseCapabilities) { + // Check base capabilities to be supported by the server + Sets.SetView unknownBaseCaps = Sets.difference(baseCapabilities, DEFAULT_BASE_CAPABILITIES); + Preconditions.checkArgument(unknownBaseCaps.isEmpty(), + "Base capabilities that will be supported by netconf server have to be subset of %s, unknown base capabilities: %s", + DEFAULT_BASE_CAPABILITIES, unknownBaseCaps); + + ImmutableSet.Builder b = ImmutableSet.builder(); + b.addAll(baseCapabilities); + // Base 1.0 capability is supported by default + b.add(XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0); + return b.build(); } /** @@ -91,7 +123,7 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF } private NetconfHelloMessage createHelloMessage(long sessionId, CapabilityProvider capabilityProvider) throws NetconfDocumentedException { - return NetconfHelloMessage.createServerHello(Sets.union(capabilityProvider.getCapabilities(), DEFAULT_CAPABILITIES), sessionId); + return NetconfHelloMessage.createServerHello(Sets.union(capabilityProvider.getCapabilities(), baseCapabilities), sessionId); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java index d6940a1a45..d4545430b4 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java @@ -64,14 +64,14 @@ public class DefaultCommit extends AbstractNetconfOperation { @Override public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException { - Preconditions.checkArgument(subsequentOperation.isExecutionTermination() == false, + Preconditions.checkArgument(!subsequentOperation.isExecutionTermination(), "Subsequent netconf operation expected by %s", this); if (isCommitWithoutNotification(requestMessage)) { logger.debug("Skipping commit notification"); } else { // Send commit notification if commit was not issued by persister - requestMessage = removePersisterAttributes(requestMessage); + removePersisterAttributes(requestMessage); Element cfgSnapshot = getConfigSnapshot(operationRouter); logger.debug("Config snapshot retrieved successfully {}", cfgSnapshot); notificationProducer.sendCommitNotification("ok", cfgSnapshot, cap.getCapabilities()); @@ -90,10 +90,8 @@ public class DefaultCommit extends AbstractNetconfOperation { return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.increasePriority(1); } - private Document removePersisterAttributes(Document message) { - final Element documentElement = message.getDocumentElement(); - documentElement.removeAttribute(NOTIFY_ATTR); - return message; + private void removePersisterAttributes(Document message) { + message.getDocumentElement().removeAttribute(NOTIFY_ATTR); } private boolean isCommitWithoutNotification(Document message) { @@ -108,9 +106,9 @@ public class DefaultCommit extends AbstractNetconfOperation { String attr = xmlElement.getAttribute(NOTIFY_ATTR); - if (attr == null || attr.equals("")) + if (attr == null || attr.equals("")){ return false; - else if (attr.equals(Boolean.toString(false))) { + } else if (attr.equals(Boolean.toString(false))) { logger.debug("Commit operation received with notify=false attribute {}", message); return true; } else { 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 bbd07e42bf..303047df12 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 @@ -39,7 +39,7 @@ public class NetconfImplActivator implements BundleActivator { private ServiceRegistration regMonitoring; @Override - public void start(final BundleContext context) throws Exception { + public void start(final BundleContext context) { InetSocketAddress address = NetconfConfigUtil.extractTCPNetconfAddress(context, "TCP is not configured, netconf not available.", false); @@ -85,7 +85,7 @@ public class NetconfImplActivator implements BundleActivator { } @Override - public void stop(final BundleContext context) throws Exception { + public void stop(final BundleContext context) { logger.info("Shutting down netconf because YangStoreService service was removed"); commitNot.close(); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java index a7560fadb6..81fac5f12f 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java @@ -51,7 +51,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S @Override public void onSessionUp(NetconfManagementSession session) { logger.debug("Session {} up", session); - Preconditions.checkState(sessions.contains(session) == false, "Session %s was already added", session); + Preconditions.checkState(!sessions.contains(session), "Session %s was already added", session); sessions.add(session); } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java index c2ab36f2c6..ff96ad779f 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java @@ -17,9 +17,9 @@ import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCommit; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultGetSchema; +import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStartExi; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStopExi; -import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultNetconfOperation; import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution; @@ -33,6 +33,7 @@ import org.w3c.dom.Document; import java.util.Collections; import java.util.HashSet; import java.util.Map; +import java.util.NavigableMap; import java.util.Set; import java.util.TreeMap; @@ -83,7 +84,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { for (NetconfOperationService netconfOperationService : netconfOperationServiceSnapshot.getServices()) { final Set netOpsFromService = netconfOperationService.getNetconfOperations(); for (NetconfOperation netconfOperation : netOpsFromService) { - Preconditions.checkState(result.contains(netconfOperation) == false, + Preconditions.checkState(!result.contains(netconfOperation), "Netconf operation %s already present", netconfOperation); result.add(netconfOperation); } @@ -97,9 +98,10 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { Preconditions.checkNotNull(allNetconfOperations, "Operation router was not initialized properly"); NetconfOperationExecution netconfOperationExecution; - String messageAsString = XmlUtil.toString(message); + String messageAsString = ""; try { + messageAsString = XmlUtil.toString(message); netconfOperationExecution = getNetconfOperationWithHighestPriority(message, session); } catch (IllegalArgumentException | IllegalStateException e) { logger.warn("Unable to handle rpc {} on session {}", messageAsString, session, e); @@ -155,7 +157,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { private NetconfOperationExecution getNetconfOperationWithHighestPriority( Document message, NetconfServerSession session) throws NetconfDocumentedException { - TreeMap sortedByPriority = getSortedNetconfOperationsWithCanHandle( + NavigableMap sortedByPriority = getSortedNetconfOperationsWithCanHandle( message, session); Preconditions.checkArgument(sortedByPriority.isEmpty() == false, @@ -174,9 +176,9 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { if (netconfOperation instanceof DefaultNetconfOperation) { ((DefaultNetconfOperation) netconfOperation).setNetconfSession(session); } - if (handlingPriority.equals(HandlingPriority.CANNOT_HANDLE) == false) { + if (!handlingPriority.equals(HandlingPriority.CANNOT_HANDLE)) { - Preconditions.checkState(sortedPriority.containsKey(handlingPriority) == false, + Preconditions.checkState(!sortedPriority.containsKey(handlingPriority), "Multiple %s available to handle message %s with priority %s", NetconfOperation.class.getName(), message, handlingPriority); sortedPriority.put(handlingPriority, netconfOperation); @@ -220,7 +222,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { } public static NetconfOperationExecution createExecutionChain( - TreeMap sortedByPriority, HandlingPriority handlingPriority) { + NavigableMap sortedByPriority, HandlingPriority handlingPriority) { NetconfOperation netconfOperation = sortedByPriority.get(handlingPriority); HandlingPriority subsequentHandlingPriority = sortedByPriority.lowerKey(handlingPriority); diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java index db5a359d7a..0a0cd22088 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java @@ -8,20 +8,47 @@ package org.opendaylight.controller.netconf.impl; -import com.google.common.base.Optional; -import com.google.common.collect.Sets; -import io.netty.channel.ChannelFuture; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; import io.netty.util.HashedWheelTimer; +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.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicLong; import org.apache.commons.io.IOUtils; import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; -import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; import org.opendaylight.controller.netconf.mapping.api.Capability; @@ -31,45 +58,61 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedEx import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory; import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader; +import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil; +import org.opendaylight.controller.netconf.util.messages.NetconfStartExiMessage; import org.opendaylight.controller.netconf.util.test.XmlFileLoader; +import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; -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 com.google.common.collect.Sets; -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.mock; +import io.netty.channel.ChannelFuture; +import io.netty.channel.nio.NioEventLoopGroup; +@RunWith(Parameterized.class) public class ConcurrentClientsTest { + private static final Logger logger = LoggerFactory.getLogger(ConcurrentClientsTest.class); - private static final int CONCURRENCY = 16; - private EventLoopGroup nettyGroup; - private NetconfClientDispatcher netconfClientDispatcher; + private static ExecutorService clientExecutor; - private final InetSocketAddress netconfAddress = new InetSocketAddress("127.0.0.1", 8303); + private static final int CONCURRENCY = 32; + private static final InetSocketAddress netconfAddress = new InetSocketAddress("127.0.0.1", 8303); - static final Logger logger = LoggerFactory.getLogger(ConcurrentClientsTest.class); + private int nettyThreads; + private Class clientRunnable; + private Set serverCaps; - private DefaultCommitNotificationProducer commitNot; - private NetconfServerDispatcher dispatch; + public ConcurrentClientsTest(int nettyThreads, Class clientRunnable, Set serverCaps) { + this.nettyThreads = nettyThreads; + this.clientRunnable = clientRunnable; + this.serverCaps = serverCaps; + } + + @Parameterized.Parameters() + public static Collection data() { + return Arrays.asList(new Object[][]{ + {4, TestingNetconfClientRunnable.class, NetconfServerSessionNegotiatorFactory.DEFAULT_BASE_CAPABILITIES}, + {1, TestingNetconfClientRunnable.class, NetconfServerSessionNegotiatorFactory.DEFAULT_BASE_CAPABILITIES}, + // empty set of capabilities = only base 1.0 netconf capability + {4, TestingNetconfClientRunnable.class, Collections.emptySet()}, + {4, TestingNetconfClientRunnable.class, getOnlyExiServerCaps()}, + {4, TestingNetconfClientRunnable.class, getOnlyChunkServerCaps()}, + + {4, BlockingClientRunnable.class, getOnlyExiServerCaps()}, + {1, BlockingClientRunnable.class, getOnlyExiServerCaps()}, + }); + } + private EventLoopGroup nettyGroup; + private NetconfClientDispatcher netconfClientDispatcher; + private DefaultCommitNotificationProducer commitNot; HashedWheelTimer hashedWheelTimer; + private TestingNetconfOperation testingNetconfOperation; public static SessionMonitoringService createMockedMonitoringService() { SessionMonitoringService monitoring = mock(SessionMonitoringService.class); @@ -78,27 +121,43 @@ public class ConcurrentClientsTest { return monitoring; } + @BeforeClass + public static void setUpClientExecutor() { + clientExecutor = Executors.newFixedThreadPool(CONCURRENCY, new ThreadFactory() { + int i = 1; + + @Override + public Thread newThread(final Runnable r) { + Thread thread = new Thread(r); + thread.setName("client-" + i++); + thread.setDaemon(true); + return thread; + } + }); + } + @Before public void setUp() throws Exception { - nettyGroup = new NioEventLoopGroup(); + nettyGroup = new NioEventLoopGroup(nettyThreads); NetconfHelloMessageAdditionalHeader additionalHeader = new NetconfHelloMessageAdditionalHeader("uname", "10.10.10.1", "830", "tcp", "client"); netconfClientDispatcher = new NetconfClientDispatcher( nettyGroup, nettyGroup, additionalHeader, 5000); NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); - factoriesListener.onAddNetconfOperationServiceFactory(mockOpF()); + + testingNetconfOperation = new TestingNetconfOperation(); + factoriesListener.onAddNetconfOperationServiceFactory(new TestingOperationServiceFactory(testingNetconfOperation)); SessionIdProvider idProvider = new SessionIdProvider(); hashedWheelTimer = new HashedWheelTimer(); + NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory( - hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, createMockedMonitoringService()); + hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, createMockedMonitoringService(), serverCaps); commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer()); - - NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory); - dispatch = new NetconfServerDispatcher(serverChannelInitializer, nettyGroup, nettyGroup); + final NetconfServerDispatcher dispatch = new NetconfServerDispatcher(serverChannelInitializer, nettyGroup, nettyGroup); ChannelFuture s = dispatch.createServer(netconfAddress); s.await(); @@ -106,111 +165,131 @@ public class ConcurrentClientsTest { @After public void tearDown(){ + commitNot.close(); hashedWheelTimer.stop(); - nettyGroup.shutdownGracefully(); + try { + nettyGroup.shutdownGracefully().get(); + } catch (InterruptedException | ExecutionException e) { + logger.warn("Ignoring exception while cleaning up after test", e); + } } - private NetconfOperationServiceFactory mockOpF() { - return new NetconfOperationServiceFactory() { - @Override - public NetconfOperationService createService(String netconfSessionIdForReporting) { - return new NetconfOperationService() { - @Override - public Set getCapabilities() { - return Collections.emptySet(); - } - - @Override - public Set getNetconfOperations() { - return Sets. newHashSet(new NetconfOperation() { - @Override - public HandlingPriority canHandle(Document message) { - return HandlingPriority.getHandlingPriority(Integer.MAX_VALUE); - } - - @Override - public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException { - try { - return XmlUtil.readXmlToDocument(""); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }); - } - - @Override - public void close() { - } - }; - } - }; + @AfterClass + public static void tearDownClientExecutor() { + clientExecutor.shutdownNow(); } - @After - public void cleanUp() throws Exception { - commitNot.close(); - } + @Test(timeout = CONCURRENCY * 1000) + public void testConcurrentClients() throws Exception { - @Test - public void multipleClients() throws Exception { - List threads = new ArrayList<>(); + List> futures = Lists.newArrayListWithCapacity(CONCURRENCY); - final int attempts = 5; for (int i = 0; i < CONCURRENCY; i++) { - TestingThread thread = new TestingThread(String.valueOf(i), attempts); - threads.add(thread); - thread.start(); + futures.add(clientExecutor.submit(getInstanceOfClientRunnable())); } - for (TestingThread thread : threads) { - thread.join(); - if(thread.thrownException.isPresent()) { - Exception exception = thread.thrownException.get(); - logger.error("Thread for testing client failed", exception); - fail("Client thread " + thread + " failed: " + exception.getMessage()); + for (Future future : futures) { + try { + future.get(); + } catch (InterruptedException e) { + throw new IllegalStateException(e); + } catch (ExecutionException e) { + logger.error("Thread for testing client failed", e); + fail("Client failed: " + e.getMessage()); } } + + assertEquals(CONCURRENCY, testingNetconfOperation.getMessageCount()); } - @Test - public void synchronizationTest() throws Exception { - new BlockingThread("foo").run2(); + public static Set getOnlyExiServerCaps() { + return Sets.newHashSet( + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0, + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0 + ); } - @Test - public void multipleBlockingClients() throws Exception { - List threads = new ArrayList<>(); - for (int i = 0; i < CONCURRENCY; i++) { - BlockingThread thread = new BlockingThread(String.valueOf(i)); - threads.add(thread); - thread.start(); + public static Set getOnlyChunkServerCaps() { + return Sets.newHashSet( + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_0, + XmlNetconfConstants.URN_IETF_PARAMS_NETCONF_BASE_1_1 + ); + } + + public Runnable getInstanceOfClientRunnable() throws Exception { + return clientRunnable.getConstructor(ConcurrentClientsTest.class).newInstance(this); + } + + /** + * Responds to all operations except start-exi and counts all requests + */ + private static class TestingNetconfOperation implements NetconfOperation { + + private final AtomicLong counter = new AtomicLong(); + + @Override + public HandlingPriority canHandle(Document message) { + return XmlUtil.toString(message).contains(NetconfStartExiMessage.START_EXI) ? + HandlingPriority.CANNOT_HANDLE : + HandlingPriority.HANDLE_WITH_MAX_PRIORITY; } - for (BlockingThread thread : threads) { - thread.join(); - if(thread.thrownException.isPresent()) { - Exception exception = thread.thrownException.get(); - logger.error("Thread for testing client failed", exception); - fail("Client thread " + thread + " failed: " + exception.getMessage()); + @Override + public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException { + try { + logger.info("Handling netconf message from test {}", XmlUtil.toString(requestMessage)); + counter.getAndIncrement(); + return XmlUtil.readXmlToDocument(""); + } catch (Exception e) { + throw new RuntimeException(e); } } + + public long getMessageCount() { + return counter.get(); + } } - class BlockingThread extends Thread { - private Optional thrownException; + /** + * Hardcoded operation service factory + */ + private static class TestingOperationServiceFactory implements NetconfOperationServiceFactory { + private final NetconfOperation[] operations; + + public TestingOperationServiceFactory(final NetconfOperation... operations) { + this.operations = operations; + } - public BlockingThread(String name) { - super("client-" + name); + @Override + public NetconfOperationService createService(String netconfSessionIdForReporting) { + return new NetconfOperationService() { + @Override + public Set getCapabilities() { + return Collections.emptySet(); + } + + @Override + public Set getNetconfOperations() { + return Sets.newHashSet(operations); + } + + @Override + public void close() {} + }; } + } + + /** + * Pure socket based blocking client + */ + public final class BlockingClientRunnable implements Runnable { @Override public void run() { try { run2(); - thrownException = Optional.absent(); } catch (Exception e) { - thrownException = Optional.of(e); + throw new IllegalStateException(Thread.currentThread().getName(), e); } } @@ -246,34 +325,32 @@ public class ConcurrentClientsTest { } } - class TestingThread extends Thread { - - private final String clientId; - private final int attempts; - private Optional thrownException; - - TestingThread(String clientId, int attempts) { - this.clientId = clientId; - this.attempts = attempts; - setName("client-" + clientId); - } + /** + * TestingNetconfClient based runnable + */ + public final class TestingNetconfClientRunnable implements Runnable { @Override public void run() { try { - final TestingNetconfClient netconfClient = new TestingNetconfClient(clientId, netconfAddress, netconfClientDispatcher); + final TestingNetconfClient netconfClient = new TestingNetconfClient(Thread.currentThread().getName(), + netconfAddress, netconfClientDispatcher); long sessionId = netconfClient.getSessionId(); - logger.info("Client with sessionid {} hello exchanged", sessionId); + logger.info("Client with session id {}: hello exchanged", sessionId); final NetconfMessage getMessage = XmlFileLoader .xmlFileToNetconfMessage("netconfMessages/getConfig.xml"); NetconfMessage result = netconfClient.sendRequest(getMessage).get(); - logger.info("Client with sessionid {} got result {}", sessionId, result); + logger.info("Client with session id {}: got result {}", sessionId, result); + + Preconditions.checkState(NetconfMessageUtil.isErrorMessage(result) == false, + "Received error response: " + XmlUtil.toString(result.getDocument()) + " to request: " + + XmlUtil.toString(getMessage.getDocument())); + netconfClient.close(); - logger.info("Client with session id {} ended", sessionId); - thrownException = Optional.absent(); + logger.info("Client with session id {}: ended", sessionId); } catch (final Exception e) { - thrownException = Optional.of(e); + throw new IllegalStateException(Thread.currentThread().getName(), e); } } } diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked1.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked1.txt deleted file mode 100644 index aad72393cb..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked1.txt +++ /dev/null @@ -1,35 +0,0 @@ - -#24 - - - 14 - fred - - < -#2 -/r -#3 -pc> -## diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked2.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked2.txt deleted file mode 100644 index a36a85ea1f..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked2.txt +++ /dev/null @@ -1,48 +0,0 @@ - -#22 - - - - - -#18 - - - -#19 - - -#8 - - -#77 - - - - - -## diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked3.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked3.txt deleted file mode 100644 index d9dc43d620..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked3.txt +++ /dev/null @@ -1,43 +0,0 @@ - -#43 - - -#26 - - - -#35 - - - -#39 - - < -#40 -top xmlns="http://example.com/schema/1.2 -#26 -/config"> - - -#36 - - f -#56 -red - - - -#28 - - - - -## diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked4.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked4.txt deleted file mode 100644 index 0b8a102dff..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked4.txt +++ /dev/null @@ -1,40 +0,0 @@ - -#17 - - - - - - -#43 - - - -#16 - - -#22 - - - -## diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked5.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked5.txt deleted file mode 100644 index f8f3c4d7c2..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/chunked5.txt +++ /dev/null @@ -1,42 +0,0 @@ - -#43 - - - - - < -#4 -/tar -#18 -get> - - -#41 - - - -#29 - Ethernet0/0 - 1500 - -#61 - - - - - -## diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_config_bean_response.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_config_bean_response.txt deleted file mode 100644 index 2ae32efb65..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_config_bean_response.txt +++ /dev/null @@ -1,18 +0,0 @@ -curl http://localhost:17777/jolokia/read/org.opendaylight.controller:instanceName=fixed1,type=ConfigBean,interfaceName=testing-threadpool | jsonpp -{ - "request": { - "mbean": "org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean", - "type": "read" - }, - "status": 200, - "timestamp": 1362416252, - "value": { - "ExportedInterfaces": [ - "testing-threadpool", - "modifiable-threadpool" - ], - "ImplementationName": "fixed", - "ThreadCount": 10, - "TriggerNewInstanceCreation": false - } -} \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_lookupConfigBeans.txt b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_lookupConfigBeans.txt deleted file mode 100644 index 2ae705a54f..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/listener/databaseinteractions/jolokia_lookupConfigBeans.txt +++ /dev/null @@ -1,18 +0,0 @@ -$ curl 'http://localhost:17777/jolokia/exec/org.opendaylight.controller:type=ConfigRegistry/lookupConfigBeans()' | jsonpp -{ - "request": { - "mbean": "org.opendaylight.controller:type=ConfigRegistry", - "operation": "lookupConfigBeans()", - "type": "exec" - }, - "status": 200, - "timestamp": 1362417043, - "value": [ - { - "objectName": "org.opendaylight.controller:instanceName=fixed1,interfaceName=modifiable-threadpool,type=ConfigBean" - }, - { - "objectName": "org.opendaylight.controller:instanceName=fixed1,interfaceName=testing-threadpool,type=ConfigBean" - } - ] -} diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_commit.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_commit.xml deleted file mode 100644 index 6eca609b6c..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_commit.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_candidate.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_candidate.xml deleted file mode 100644 index 6a9ed639d8..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_candidate.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_running.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_running.xml deleted file mode 100644 index 2d66c45906..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_lock_running.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_modify_candidate.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_modify_candidate.xml deleted file mode 100644 index ce67845de1..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_modify_candidate.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - none - test-then-set - stop-on-error - - - - 7 - - - - - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_candidate.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_candidate.xml deleted file mode 100644 index dd6fe1ba1e..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_candidate.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_running.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_running.xml deleted file mode 100644 index f94af4698d..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/client_unlock_running.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/server_error_missing_attribute.xml b/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/server_error_missing_attribute.xml deleted file mode 100644 index c70184e2b4..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/org/opendaylight/controller/netconf/impl/notused/server_error_missing_attribute.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - rpc - missing-attribute - error - - message-id - rpc - - - diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.json b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.json deleted file mode 100644 index fcef6b730c..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "value":null, - "status":200, - "request": { - "type":"exec", - "mbean":"java.util.logging:type=Logging", - "operation":"setLoggerLevel", - "arguments":["global","INFO"] - } -} \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.xml deleted file mode 100644 index 09ba714ea9..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/input.xml +++ /dev/null @@ -1,7 +0,0 @@ - - org.opendaylight.controller:type=AppDeployer - EXEC - lookupConfigBeans - abc,bcd.aas - 64 - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputList.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputList.xml deleted file mode 100644 index 011d472634..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputList.xml +++ /dev/null @@ -1,9 +0,0 @@ - - org.opendaylight.controller:type=AppDeployer - EXEC - lookupConfigBeans - - 22 - 69 - - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMap.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMap.xml deleted file mode 100644 index 947335d215..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMap.xml +++ /dev/null @@ -1,14 +0,0 @@ - - org.opendaylight.controller:type=AppDeployer - EXEC - lookupConfigBeans - - - single - mock - - 2 - 22 - arg - - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMultiple.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMultiple.xml deleted file mode 100644 index 2ad485f6c5..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputMultiple.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - org.opendaylight.controller:type=AppDeployer - EXEC - lookupConfigBeans - abc,bcd.aas - 22 - - - org.opendaylight.controller:type=AppDeployer - WRITE - attribute - 22 - - - org.opendaylight.controller:type=AppDeployer - EXEC - lookupConfigBeans - - - single - mock - - 2 - 22 - arg - - - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetter.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetter.xml deleted file mode 100644 index a5882d6ded..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetter.xml +++ /dev/null @@ -1,6 +0,0 @@ - - org.opendaylight.controller:type=AppDeployer - WRITE - attribute - 22 - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterList.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterList.xml deleted file mode 100644 index 24d2171fe4..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterList.xml +++ /dev/null @@ -1,8 +0,0 @@ - - org.opendaylight.controller:type=AppDeployer - WRITE - attribute - 22 - 222 - 223 - \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterMap.xml b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterMap.xml deleted file mode 100644 index 9af105fe58..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/inputSetterMap.xml +++ /dev/null @@ -1,9 +0,0 @@ - - org.opendaylight.controller:type=AppDeployer - WRITE - setAtr - - 1 - 2 - - diff --git a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/map.json b/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/map.json deleted file mode 100644 index d7538663e3..0000000000 --- a/opendaylight/netconf/netconf-impl/src/test/resources/testConfigs/map.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "timestamp":1362488209, - "status":200, - "request":{ - "mbean":"org.opendaylight.controller:type=ConfigRegistry", - "attribute":"AvailableInterfacesAndImplementations", - "type":"read" - }, - "value":{ - "topology-registry":[ - "single" - ], - "bgp-update":[ - "mock", - "bgp-impl" - ], - "positioning-service":[ - "combine", - "onehop", - "ondemand", - "pxe", - "precompute" - ], - "serializer":[ - "serializer-impl" - ], - "network-topology-factory":[ - "mock-xml", - "bgp-network-topology-factory", - "transient" - ], - "dwe-topology":[ - "ebgp", - "defaultmetric", - "igp", - "network" - ], - "thread-factory":[ - "naming-thread-factory" - ], - "bgp-parser":[ - "parser" - ], - "pcep-dispatcher":[ - "dispatcher" - ], - "threadpool":[ - "flexible", - "fixed", - "scheduled" - ], - "scheduled-threadpool":[ - "scheduled" - ], - "positioning-onehop":[ - "onehop" - ], - "bgp-dispatcher":[ - "bgp-dispatcher-impl" - ], - "cost-combiner":[ - "pxe" - ], - "apsp-provider":[ - "jgrapht", - "parallel", - "single-threaded" - ], - "topology":[ - "ebgp", - "defaultmetric", - "igp", - "network" - ], - "soap-resource":[ - "positioning-adaptor-pxe" - ], - "database-provider-factory":[ - "transient" - ], - "bgp-proposal-checker":[ - "bgp-proposal-checker-impl" - ], - "bgp-proposal":[ - "bgp-proposal-impl" - ], - "listenable-network-topology-factory":[ - "transient" - ], - "event-bus":[ - "sync", - "async" - ], - "topology-registry-provider":[ - "single" - ], - "topology-provider-factory":[ - "transient" - ], - "rest-resource":[ - "topology-resource-holder", - "alto-resource-holder", - "topology-visual-holder", - "network-resource-holder", - "path-resource-holder" - ], - "listenable-database-provider-factory":[ - "transient" - ], - "topology-validator":[ - "accept-all", - "threshold" - ], - "replicator":[ - "replicator-impl" - ], - "server":[ - "soap", - "rest" - ], - "combiner-pxe":[ - "pxe" - ], - "rest":[ - "rest" - ], - "soap":[ - "soap" - ], - "path-service":[ - "cariden" - ] - } -} \ No newline at end of file diff --git a/opendaylight/netconf/netconf-it/pom.xml b/opendaylight/netconf/netconf-it/pom.xml index b330f9bcd4..0c03dda45b 100644 --- a/opendaylight/netconf/netconf-it/pom.xml +++ b/opendaylight/netconf/netconf-it/pom.xml @@ -15,6 +15,18 @@ + + ${project.groupId} + sal-binding-it + + + + + org.ops4j.pax.url + pax-url-aether + + + org.opendaylight.controller commons.logback_settings @@ -127,10 +139,6 @@ netty-config-api test - - ${project.groupId} - sal-binding-it - org.opendaylight.controller yang-test diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java index 8b2af39343..af83fe4602 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java @@ -78,7 +78,7 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest { @Before public void setUp() throws Exception { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,NetconfITTest.getModuleFactoriesS().toArray( new ModuleFactory[0]))); NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider()); diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java index e45a249ad4..cc9e8c367a 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java @@ -46,7 +46,7 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest { @Before public void setUp() throws Exception { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,getModuleFactories().toArray( new ModuleFactory[0]))); NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index 634a18f852..b77d92e7cb 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -13,6 +13,20 @@ import ch.ethz.ssh2.Session; 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.lang.management.ManagementFactory; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; +import javax.management.ObjectName; +import javax.xml.parsers.ParserConfigurationException; import junit.framework.Assert; import org.apache.commons.io.IOUtils; import org.junit.After; @@ -52,22 +66,6 @@ import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.xml.sax.SAXException; - -import javax.management.ObjectName; -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; -import java.io.InputStream; -import java.lang.management.ManagementFactory; -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeoutException; - import static java.util.Collections.emptyList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -96,7 +94,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Before public void setUp() throws Exception { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,getModuleFactories().toArray( new ModuleFactory[0]))); loadMessages(); @@ -411,7 +409,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { try { c = sess.getStdout().read(bytes); } catch (IOException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + throw new IllegalStateException("IO exception while reading data on ssh bridge."); } logger.info("got data:" + bytes); if (c == 0) { diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java index 92caea17d5..8e98ab6320 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java @@ -17,12 +17,12 @@ import org.junit.Test; import org.mockito.Mock; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; import org.opendaylight.controller.config.spi.ModuleFactory; -import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; -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.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; +import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; @@ -72,7 +72,7 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest { @Before public void setUp() throws Exception { - super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray( + super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, NetconfITTest.getModuleFactoriesS().toArray( new ModuleFactory[0]))); monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider()); diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java index 96a9effcfc..c54285bc90 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java @@ -1,10 +1,10 @@ /* - * 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 - */ +* 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.it.pax; import static org.junit.Assert.fail; @@ -26,7 +26,6 @@ import java.net.InetSocketAddress; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import javax.inject.Inject; import javax.xml.parsers.ParserConfigurationException; import org.junit.Assert; @@ -59,7 +58,11 @@ public class IdentityRefNetconfTest { public static final int CLIENT_CONNECTION_TIMEOUT_MILLIS = 15000; // Wait for controller to start - @Inject + + // FIXME move this (pax) test to different module + // pax jars contain guava classes that clash with real guava dependencies in non-pax tests + // + //@Inject @Filter(timeout = 60 * 1000) BindingAwareBroker broker; diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java index 05122be4d2..c08db906df 100644 --- a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java @@ -11,7 +11,7 @@ package org.opendaylight.controller.netconf.mapping.api; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -public class HandlingPriority implements Comparable { +public final class HandlingPriority implements Comparable { public static final HandlingPriority CANNOT_HANDLE = new HandlingPriority(); public static final HandlingPriority HANDLE_WITH_DEFAULT_PRIORITY = new HandlingPriority(Integer.MIN_VALUE); @@ -51,34 +51,42 @@ public class HandlingPriority implements Comparable { @Override public int compareTo(HandlingPriority o) { - if (this == o) + if (this == o){ return 0; - if (this == CANNOT_HANDLE) + } + if (this.equals(CANNOT_HANDLE)){ return -1; - if (o == CANNOT_HANDLE) + } + if (o.equals(CANNOT_HANDLE)){ return 1; + } - if (priority > o.priority) + if (priority > o.priority){ return 1; - if (priority == o.priority) + } + if (priority.equals(o.priority)){ return 0; - if (priority < o.priority) + } + if (priority < o.priority){ return -1; - + } throw new IllegalStateException("Unexpected state"); } @Override public boolean equals(Object o) { - if (this == o) + if (this == o){ return true; - if (!(o instanceof HandlingPriority)) + } + if (!(o instanceof HandlingPriority)){ return false; + } HandlingPriority that = (HandlingPriority) o; - if (priority != null ? !priority.equals(that.priority) : that.priority != null) + if (priority != null ? !priority.equals(that.priority) : that.priority != null){ return false; + } return true; } diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java index 6449c3e05f..c277e20553 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java @@ -7,7 +7,6 @@ */ package org.opendaylight.controller.netconf.monitoring; -import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService; @@ -63,8 +62,12 @@ public class Get extends AbstractNetconfOperation { @Override public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException { - Preconditions.checkArgument(subsequentOperation.isExecutionTermination() == false, - "Subsequent netconf operation expected by %s", this); + if (subsequentOperation.isExecutionTermination()){ + throw new NetconfDocumentedException(String.format("Subsequent netconf operation expected by %s", this), + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.operation_failed, + NetconfDocumentedException.ErrorSeverity.error); + } try { Document innerResult = subsequentOperation.execute(requestMessage); diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/MonitoringConstants.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/MonitoringConstants.java index 200cd344a6..d14464d667 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/MonitoringConstants.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/MonitoringConstants.java @@ -7,8 +7,11 @@ */ package org.opendaylight.controller.netconf.monitoring; -public class MonitoringConstants { +public final class MonitoringConstants { + private MonitoringConstants(){ + // not called - private constructor for utility class + } public static final String MODULE_NAME = "ietf-netconf-monitoring"; public static final String MODULE_REVISION = "2010-10-04"; diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java index de04484d13..14c47352a8 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringActivator.java @@ -21,14 +21,14 @@ public class NetconfMonitoringActivator implements BundleActivator { private NetconfMonitoringServiceTracker monitor; @Override - public void start(final BundleContext context) throws Exception { + public void start(final BundleContext context) { monitor = new NetconfMonitoringServiceTracker(context); monitor.open(); } @Override - public void stop(final BundleContext context) throws Exception { + public void stop(final BundleContext context) { if(monitor!=null) { try { monitor.close(); diff --git a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java index a42bc09591..731aad6d1a 100644 --- a/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java +++ b/opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java @@ -7,30 +7,20 @@ */ package org.opendaylight.controller.netconf.monitoring.osgi; -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.util.HashSet; +import com.google.common.base.Optional; +import com.google.common.collect.Sets; import java.util.List; import java.util.Set; - import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService; import org.opendaylight.controller.netconf.mapping.api.Capability; import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; import org.opendaylight.controller.netconf.monitoring.Get; import org.opendaylight.controller.netconf.monitoring.MonitoringConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas; - -import com.google.common.base.Charsets; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.collect.Sets; -import com.google.common.io.Files; public class NetconfMonitoringOperationService implements NetconfOperationService { - public static final HashSet CAPABILITIES = Sets.newHashSet(new Capability() { + public static final Set CAPABILITIES = Sets.newHashSet(new Capability() { @Override public String getCapabilityUri() { @@ -69,18 +59,6 @@ public class NetconfMonitoringOperationService implements NetconfOperationServic this.monitor = monitor; } - private static String readSchema() { - String schemaLocation = "/META-INF/yang/ietf-netconf-monitoring.yang"; - URL resource = Schemas.class.getClassLoader().getResource(schemaLocation); - Preconditions.checkNotNull(resource, "Unable to read schema content from %s", schemaLocation); - File file = new File(resource.getFile()); - try { - return Files.toString(file, Charsets.UTF_8); - } catch (IOException e) { - throw new RuntimeException("Unable to load schema from " + schemaLocation, e); - } - } - @Override public Set getCapabilities() { return CAPABILITIES; diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java index c2d0679155..51054dd938 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java @@ -20,7 +20,7 @@ import java.net.ServerSocket; import java.util.concurrent.atomic.AtomicLong; @ThreadSafe -public class NetconfSSHServer implements Runnable { +public final class NetconfSSHServer implements Runnable { private ServerSocket ss = null; private static final Logger logger = LoggerFactory.getLogger(NetconfSSHServer.class); @@ -29,12 +29,12 @@ public class NetconfSSHServer implements Runnable { private final AuthProvider authProvider; private boolean up = false; - private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws Exception{ + private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws IllegalStateException, IOException { logger.trace("Creating SSH server socket on port {}",serverPort); this.ss = new ServerSocket(serverPort); if (!ss.isBound()){ - throw new Exception("Socket can't be bound to requested port :"+serverPort); + throw new IllegalStateException("Socket can't be bound to requested port :"+serverPort); } logger.trace("Server socket created."); this.clientAddress = clientAddress; @@ -42,11 +42,11 @@ public class NetconfSSHServer implements Runnable { this.up = true; } - public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress,AuthProvider authProvider) throws Exception { + public static NetconfSSHServer start(int serverPort, InetSocketAddress clientAddress,AuthProvider authProvider) throws IllegalStateException, IOException { return new NetconfSSHServer(serverPort, clientAddress,authProvider); } - public void stop() throws Exception { + public void stop() throws IOException { up = false; logger.trace("Closing SSH server socket."); ss.close(); diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java index 2d380482ba..2e9a0b9d8b 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProvider.java @@ -7,42 +7,26 @@ */ package org.opendaylight.controller.netconf.ssh.authentication; +import java.io.IOException; import org.opendaylight.controller.sal.authorization.AuthResultEnum; -import org.opendaylight.controller.sal.authorization.UserLevel; import org.opendaylight.controller.usermanager.IUserManager; -import org.opendaylight.controller.usermanager.UserConfig; - -import java.util.ArrayList; -import java.util.List; - import static com.google.common.base.Preconditions.checkNotNull; public class AuthProvider implements AuthProviderInterface { - private static IUserManager um; //FIXME static mutable state, no locks - private static final String DEFAULT_USER = "netconf"; - private static final String DEFAULT_PASSWORD = "netconf"; + private IUserManager um; private final String pem; - public AuthProvider(IUserManager ium, String pemCertificate) throws Exception { + public AuthProvider(IUserManager ium, String pemCertificate) throws IllegalArgumentException, IOException { checkNotNull(pemCertificate, "Parameter 'pemCertificate' is null"); - AuthProvider.um = ium; - if (AuthProvider.um == null) { - throw new Exception("No usermanager service available."); - } - - List roles = new ArrayList(1); - roles.add(UserLevel.SYSTEMADMIN.toString()); - AuthProvider.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles)); //FIXME hardcoded auth + checkNotNull(ium, "No user manager service available."); + this.um = ium; pem = pemCertificate; } @Override - public boolean authenticated(String username, String password) throws Exception { - if (AuthProvider.um == null) { - throw new Exception("No usermanager service available."); - } - AuthResultEnum authResult = AuthProvider.um.authenticate(username, password); + public boolean authenticated(String username, String password) { + AuthResultEnum authResult = this.um.authenticate(username, password); return authResult.equals(AuthResultEnum.AUTH_ACCEPT) || authResult.equals(AuthResultEnum.AUTH_ACCEPT_LOC); } @@ -53,11 +37,11 @@ public class AuthProvider implements AuthProviderInterface { @Override public void removeUserManagerService() { - AuthProvider.um = null; + this.um = null; } @Override public void addUserManagerService(IUserManager userManagerService) { - AuthProvider.um = userManagerService; + this.um = userManagerService; } } diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java index 8e40578a0e..fad0f79a4e 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/authentication/AuthProviderInterface.java @@ -12,7 +12,7 @@ import org.opendaylight.controller.usermanager.IUserManager; public interface AuthProviderInterface { - public boolean authenticated(String username, String password) throws Exception; + public boolean authenticated(String username, String password) throws IllegalStateException; public char[] getPEMAsCharArray() throws Exception; public void removeUserManagerService(); public void addUserManagerService(IUserManager userManagerService); diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java index 112bf67f69..ca0c9454d4 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java @@ -8,12 +8,21 @@ package org.opendaylight.controller.netconf.ssh.osgi; import com.google.common.base.Optional; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.opendaylight.controller.netconf.ssh.NetconfSSHServer; import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider; import org.opendaylight.controller.netconf.ssh.authentication.PEMGenerator; import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil; +import org.opendaylight.controller.sal.authorization.UserLevel; import org.opendaylight.controller.usermanager.IUserManager; +import org.opendaylight.controller.usermanager.UserConfig; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; @@ -21,16 +30,12 @@ import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.InetSocketAddress; +import static com.google.common.base.Preconditions.checkNotNull; /** * Activator for netconf SSH bundle which creates SSH bridge between netconf client and netconf server. Activator * starts SSH Server in its own thread. This thread is closed when activator calls stop() method. Server opens socket - * and listen for client connections. Each client connection creation is handled in separate + * and listens for client connections. Each client connection creation is handled in separate * {@link org.opendaylight.controller.netconf.ssh.threads.SocketThread} thread. * This thread creates two additional threads {@link org.opendaylight.controller.netconf.ssh.threads.IOThread} * forwarding data from/to client.IOThread closes servers session and server connection when it gets -1 on input stream. @@ -44,8 +49,10 @@ public class NetconfSSHActivator implements BundleActivator{ private static final String EXCEPTION_MESSAGE = "Netconf ssh bridge is not available."; private IUserManager iUserManager; private BundleContext context = null; + private Optional defaultPassword; + private Optional defaultUser; - ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer(){ + private ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer(){ @Override public IUserManager addingService(ServiceReference reference) { logger.trace("Service {} added, let there be SSH bridge.", reference); @@ -72,36 +79,42 @@ public class NetconfSSHActivator implements BundleActivator{ @Override - public void start(BundleContext context) throws Exception { + public void start(BundleContext context) { this.context = context; listenForManagerService(); } @Override - public void stop(BundleContext context) throws Exception { + public void stop(BundleContext context) throws IOException { + if (this.defaultUser.isPresent()){ + this.iUserManager.removeLocalUser(this.defaultUser.get()); + } if (server != null){ server.stop(); logger.trace("Netconf SSH bridge is down ..."); } } - private void startSSHServer() throws Exception { + private void startSSHServer() throws IllegalStateException, IOException { + checkNotNull(this.iUserManager, "No user manager service available."); logger.trace("Starting netconf SSH bridge."); Optional sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context, EXCEPTION_MESSAGE); InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfAddress(context, EXCEPTION_MESSAGE, true); if (sshSocketAddressOptional.isPresent()){ - String path = NetconfConfigUtil.getPrivateKeyPath(context); - path = path.replace("\\", "/"); // FIXME: shouldn't this convert lines to system dependent path separator? + String path = FilenameUtils.separatorsToSystem(NetconfConfigUtil.getPrivateKeyPath(context)); if (path.equals("")){ - throw new Exception("Missing netconf.ssh.pk.path key in configuration file."); + throw new IllegalStateException("Missing netconf.ssh.pk.path key in configuration file."); } File privateKeyFile = new File(path); - String privateKeyPEMString; + String privateKeyPEMString = null; if (privateKeyFile.exists() == false) { - // generate & save to file - privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile); + try { + privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile); + } catch (Exception e) { + logger.error("Exception occurred while generating PEM string {}",e); + } } else { // read from file try (FileInputStream fis = new FileInputStream(path)) { @@ -111,7 +124,23 @@ public class NetconfSSHActivator implements BundleActivator{ throw new IllegalStateException("Error reading RSA key from file " + path); } } - AuthProvider authProvider = new AuthProvider(iUserManager, privateKeyPEMString); + AuthProvider authProvider = null; + try { + this.defaultPassword = NetconfConfigUtil.getSSHDefaultPassword(context); + this.defaultUser = NetconfConfigUtil.getSSHDefaultUser(context); + // Since there is no user data store yet (ldap, ...) this adds default user/password to UserManager + // if these parameters are set in netconf configuration file. + if (defaultUser.isPresent() && + defaultPassword.isPresent()){ + logger.trace(String.format("Default username and password for netconf ssh bridge found. Adding user %s to user manager.",defaultUser.get())); + List roles = new ArrayList(1); + roles.add(UserLevel.SYSTEMADMIN.toString()); + iUserManager.addLocalUser(new UserConfig(defaultUser.get(), defaultPassword.get(), roles)); + } + authProvider = new AuthProvider(iUserManager, privateKeyPEMString); + } catch (Exception e) { + logger.error("Error instantiating AuthProvider {}",e); + } this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider); Thread serverThread = new Thread(server,"netconf SSH server thread"); @@ -120,10 +149,10 @@ public class NetconfSSHActivator implements BundleActivator{ logger.trace("Netconf SSH bridge up and running."); } else { logger.trace("No valid connection configuration for SSH bridge found."); - throw new Exception("No valid connection configuration for SSH bridge found."); + throw new IllegalStateException("No valid connection configuration for SSH bridge found."); } } - private void onUserManagerFound(IUserManager userManager) throws Exception{ + private void onUserManagerFound(IUserManager userManager) throws IOException { if (server!=null && server.isUp()){ server.addUserManagerService(userManager); } else { diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java index ce26910b97..d6566c8ffa 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java @@ -112,18 +112,18 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser if (netconf_ssh_input != null) { netconf_ssh_input.join(); } - } catch (InterruptedException e) { + } catch (InterruptedException e1) { Thread.currentThread().interrupt(); - logger.error("netconf_ssh_input join error ", e); + logger.error("netconf_ssh_input join error ", e1); } try { if (netconf_ssh_output != null) { netconf_ssh_output.join(); } - } catch (InterruptedException e) { + } catch (InterruptedException e2) { Thread.currentThread().interrupt(); - logger.error("netconf_ssh_output join error ", e); + logger.error("netconf_ssh_output join error ", e2); } } } else { diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSession.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSession.java index 270af3505f..c789206436 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSession.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/AbstractNetconfSession.java @@ -61,7 +61,7 @@ public abstract class AbstractNetconfSession T removeHandler(final Class handlerType) { - return this.channel.pipeline().remove(handlerType); - } - - protected void replaceMessageDecoder(final ChannelHandler handler) { + protected final void replaceMessageDecoder(final ChannelHandler handler) { replaceChannelHandler(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, handler); } - protected void replaceMessageEncoder(final ChannelHandler handler) { + protected final void replaceMessageEncoder(final ChannelHandler handler) { replaceChannelHandler(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, handler); } - protected void replaceMessageEncoderAfterNextMessage(final ChannelHandler handler) { + protected final void replaceMessageEncoderAfterNextMessage(final ChannelHandler handler) { this.delayedEncoder = handler; } - protected void replaceChannelHandler(final String handlerName, final ChannelHandler handler) { + protected final void replaceChannelHandler(final String handlerName, final ChannelHandler handler) { channel.pipeline().replace(handlerName, handlerName, handler); } @@ -124,7 +120,7 @@ public abstract class AbstractNetconfSession { } @Override - protected void startNegotiation() { + protected final void startNegotiation() { final Optional sslHandler = getSslHandler(channel); if (sslHandler.isPresent()) { Future future = sslHandler.get().handshakeFuture(); @@ -125,27 +126,22 @@ extends AbstractSessionNegotiator { // FIXME, make sessionPreferences return HelloMessage, move NetconfHelloMessage to API sendMessage((NetconfHelloMessage)helloMessage); + + replaceHelloMessageOutboundHandler(); changeState(State.OPEN_WAIT); } + private void cancelTimeout() { if(timeout!=null) { timeout.cancel(); } } - @Override - protected void handleMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException { - S session = getSessionForHelloMessage(netconfMessage) ; - negotiationSuccessful(session); - } - protected final S getSessionForHelloMessage(NetconfHelloMessage netconfMessage) throws NetconfDocumentedException { Preconditions.checkNotNull(netconfMessage, "netconfMessage"); final Document doc = netconfMessage.getDocument(); - replaceHelloMessageHandlers(); - if (shouldUseChunkFraming(doc)) { insertChunkFramingToPipeline(); } @@ -157,23 +153,44 @@ extends AbstractSessionNegotiator { /** * Insert chunk framing handlers into the pipeline */ - protected void insertChunkFramingToPipeline() { + private void insertChunkFramingToPipeline() { replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_FRAME_ENCODER, FramingMechanismHandlerFactory.createHandler(FramingMechanism.CHUNK)); replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_AGGREGATOR, new NetconfChunkAggregator()); } - protected boolean shouldUseChunkFraming(Document doc) { + private boolean shouldUseChunkFraming(Document doc) { return containsBase11Capability(doc) && containsBase11Capability(sessionPreferences.getHelloMessage().getDocument()); } /** - * Remove special handlers for hello message. Insert regular netconf xml message (en|de)coders. + * Remove special inbound handler for hello message. Insert regular netconf xml message (en|de)coders. + * + * Inbound hello message handler should be kept until negotiation is successful + * It caches any non-hello messages while negotiation is still in progress + */ + protected final void replaceHelloMessageInboundHandler(final S session) { + ChannelHandler helloMessageHandler = replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new NetconfXMLToMessageDecoder()); + + Preconditions.checkState(helloMessageHandler instanceof NetconfXMLToHelloMessageDecoder, + "Pipeline handlers misplaced on session: %s, pipeline: %s", session, channel.pipeline()); + Iterable netconfMessagesFromNegotiation = + ((NetconfXMLToHelloMessageDecoder) helloMessageHandler).getPostHelloNetconfMessages(); + + // Process messages received during negotiation + // The hello message handler does not have to be synchronized, since it is always call from the same thread by netty + // It means, we are now using the thread now + for (NetconfMessage message : netconfMessagesFromNegotiation) { + session.handleMessage(message); + } + } + + /** + * Remove special outbound handler for hello message. Insert regular netconf xml message (en|de)coders. */ - protected void replaceHelloMessageHandlers() { - replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new NetconfXMLToMessageDecoder()); + private void replaceHelloMessageOutboundHandler() { replaceChannelHandler(channel, AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, new NetconfMessageToXMLEncoder()); } @@ -183,7 +200,7 @@ extends AbstractSessionNegotiator { protected abstract S getSession(L sessionListener, Channel channel, NetconfHelloMessage message) throws NetconfDocumentedException; - protected synchronized void changeState(final State newState) { + private synchronized void changeState(final State newState) { logger.debug("Changing state from : {} to : {}", state, newState); Preconditions.checkState(isStateChangePermitted(state, newState), "Cannot change state from %s to %s", state, newState); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ChunkedFramingMechanismEncoder.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ChunkedFramingMechanismEncoder.java index ccc80a7b71..8f4590cbb1 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ChunkedFramingMechanismEncoder.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ChunkedFramingMechanismEncoder.java @@ -40,7 +40,7 @@ public class ChunkedFramingMechanismEncoder extends MessageToByteEncoder chunkSize) { ByteBuf chunk = Unpooled.buffer(chunkSize); chunk.writeBytes(createChunkHeader(chunkSize)); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/EOMFramingMechanismEncoder.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/EOMFramingMechanismEncoder.java index a3efe8a16b..8df62a6702 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/EOMFramingMechanismEncoder.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/EOMFramingMechanismEncoder.java @@ -16,7 +16,7 @@ import org.opendaylight.controller.netconf.util.messages.NetconfMessageConstants public class EOMFramingMechanismEncoder extends MessageToByteEncoder { @Override - protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception { + protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) { out.writeBytes(msg); out.writeBytes(NetconfMessageConstants.END_OF_MESSAGE); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/FramingMechanismHandlerFactory.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/FramingMechanismHandlerFactory.java index 1f7a32dc70..bac83e49d3 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/FramingMechanismHandlerFactory.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/FramingMechanismHandlerFactory.java @@ -15,11 +15,13 @@ import org.slf4j.LoggerFactory; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.MessageToByteEncoder; -public class FramingMechanismHandlerFactory { +public final class FramingMechanismHandlerFactory { private static final Logger logger = LoggerFactory.getLogger(FramingMechanismHandlerFactory.class); - private FramingMechanismHandlerFactory() {} + private FramingMechanismHandlerFactory() { + // not called - private constructor for utility class + } public static MessageToByteEncoder createHandler(FramingMechanism framingMechanism) { logger.debug("{} framing mechanism was selected.", framingMechanism); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfChunkAggregator.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfChunkAggregator.java index 219e92c3f1..9f9f4191f7 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfChunkAggregator.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfChunkAggregator.java @@ -21,6 +21,8 @@ import io.netty.handler.codec.ByteToMessageDecoder; public class NetconfChunkAggregator extends ByteToMessageDecoder { private final static Logger logger = LoggerFactory.getLogger(NetconfChunkAggregator.class); + private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM = "Got byte {} while waiting for {}"; + private static final String GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM = "Got byte {} while waiting for {}-{}"; public static final int DEFAULT_MAXIMUM_CHUNK_SIZE = 16 * 1024 * 1024; private static enum State { @@ -40,17 +42,35 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { private long chunkSize; private CompositeByteBuf chunk; + private void checkNewLine(byte b,String errorMessage){ + if (b != '\n') { + logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'\n'); + throw new IllegalStateException(errorMessage); + } + } + + private void checkHash(byte b,String errorMessage){ + if (b != '#') { + logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM, b, (byte)'#'); + throw new IllegalStateException(errorMessage); + } + } + + private void checkChunkSize(){ + if (chunkSize > maxChunkSize) { + logger.debug("Parsed chunk size {}, maximum allowed is {}", chunkSize, maxChunkSize); + throw new IllegalStateException("Maximum chunk size exceeded"); + } + + } @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws IllegalStateException { while (in.isReadable()) { switch (state) { case HEADER_ONE: { final byte b = in.readByte(); - if (b != '\n') { - logger.debug("Got byte {} while waiting for {}", b, (byte)'\n'); - throw new IllegalStateException("Malformed chunk header encountered (byte 0)"); - } + checkNewLine(b, "Malformed chunk header encountered (byte 0)"); state = State.HEADER_TWO; @@ -60,10 +80,7 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { case HEADER_TWO: { final byte b = in.readByte(); - if (b != '#') { - logger.debug("Got byte {} while waiting for {}", b, (byte)'#'); - throw new IllegalStateException("Malformed chunk header encountered (byte 1)"); - } + checkHash(b, "Malformed chunk header encountered (byte 1)"); state = State.HEADER_LENGTH_FIRST; break; @@ -84,17 +101,13 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { } if (b < '0' || b > '9') { - logger.debug("Got byte {} while waiting for {}-{}", b, (byte)'0', (byte)'9'); + logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'0', (byte)'9'); throw new IllegalStateException("Invalid chunk size encountered"); } chunkSize *= 10; chunkSize += b - '0'; - - if (chunkSize > maxChunkSize) { - logger.debug("Parsed chunk size {}, maximum allowed is {}", chunkSize, maxChunkSize); - throw new IllegalStateException("Maximum chunk size exceeded"); - } + checkChunkSize(); break; } case DATA: @@ -109,18 +122,13 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { in.discardReadBytes(); return; } - aggregateChunks(in.readBytes((int) chunkSize)); state = State.FOOTER_ONE; break; case FOOTER_ONE: { final byte b = in.readByte(); - if (b != '\n') { - logger.debug("Got byte {} while waiting for {}", b, (byte)'\n'); - throw new IllegalStateException("Malformed chunk footer encountered (byte 0)"); - } - + checkNewLine(b,"Malformed chunk footer encountered (byte 0)"); state = State.FOOTER_TWO; chunkSize = 0; break; @@ -128,12 +136,7 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { case FOOTER_TWO: { final byte b = in.readByte(); - - if (b != '#') { - logger.debug("Got byte {} while waiting for {}", b, (byte)'#'); - throw new IllegalStateException("Malformed chunk footer encountered (byte 1)"); - } - + checkHash(b,"Malformed chunk footer encountered (byte 1)"); state = State.FOOTER_THREE; break; } @@ -144,28 +147,14 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { // In this state, either header-of-new-chunk or message-end is expected // Depends on the next character - if (isHeaderLengthFirst(b)) { - // Extract header length#1 from new chunk - chunkSize = processHeaderLengthFirst(b); - // Proceed with next chunk processing - state = State.HEADER_LENGTH_OTHER; - } else if (b == '#') { - state = State.FOOTER_FOUR; - } else { - logger.debug("Got byte {} while waiting for {} or {}-{}", b, (byte) '#', (byte) '1', (byte) '9'); - throw new IllegalStateException("Malformed chunk footer encountered (byte 2)"); - } + extractNewChunkOrMessageEnd(b); break; } case FOOTER_FOUR: { final byte b = in.readByte(); - if (b != '\n') { - logger.debug("Got byte {} while waiting for {}", b, (byte)'\n'); - throw new IllegalStateException("Malformed chunk footer encountered (byte 3)"); - } - + checkNewLine(b,"Malformed chunk footer encountered (byte 3)"); state = State.HEADER_ONE; out.add(chunk); chunk = null; @@ -177,6 +166,20 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { in.discardReadBytes(); } + private void extractNewChunkOrMessageEnd(byte b) { + if (isHeaderLengthFirst(b)) { + // Extract header length#1 from new chunk + chunkSize = processHeaderLengthFirst(b); + // Proceed with next chunk processing + state = State.HEADER_LENGTH_OTHER; + } else if (b == '#') { + state = State.FOOTER_FOUR; + } else { + logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte) '#', (byte) '1', (byte) '9'); + throw new IllegalStateException("Malformed chunk footer encountered (byte 2)"); + } + } + private void initChunk() { chunk = Unpooled.compositeBuffer(); } @@ -189,8 +192,8 @@ public class NetconfChunkAggregator extends ByteToMessageDecoder { } private static int processHeaderLengthFirst(byte b) { - if (isHeaderLengthFirst(b) == false) { - logger.debug("Got byte {} while waiting for {}-{}", b, (byte)'1', (byte)'9'); + if (!isHeaderLengthFirst(b)) { + logger.debug(GOT_PARAM_WHILE_WAITING_FOR_PARAM_PARAM, b, (byte)'1', (byte)'9'); throw new IllegalStateException("Invalid chunk size encountered (byte 0)"); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEOMAggregator.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEOMAggregator.java index 9435e6ff73..8b1bb3601d 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEOMAggregator.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEOMAggregator.java @@ -24,7 +24,7 @@ public class NetconfEOMAggregator extends ByteToMessageDecoder { private final static Logger logger = LoggerFactory.getLogger(NetconfEOMAggregator.class); @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { int index = indexOfSequence(in, NetconfMessageConstants.END_OF_MESSAGE); if (index == -1) { logger.debug("Message is not complete, read again."); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEXIToMessageDecoder.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEXIToMessageDecoder.java index cbfbfe1c05..ae330d67e6 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEXIToMessageDecoder.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfEXIToMessageDecoder.java @@ -34,8 +34,6 @@ public final class NetconfEXIToMessageDecoder extends ByteToMessageDecoder { private static final Logger LOG = LoggerFactory.getLogger(NetconfEXIToMessageDecoder.class); -// private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); - private final NetconfEXICodec codec; public NetconfEXIToMessageDecoder(final NetconfEXICodec codec) { @@ -50,9 +48,9 @@ public final class NetconfEXIToMessageDecoder extends ByteToMessageDecoder { * the use of EXI, which means the next message needs to be decoded not by us, but rather * by the XML decoder. */ - // If empty Byte buffer is passed to r.parse, EOFException is thrown - if (in.readableBytes() == 0) { + // If empty Byte buffer is passed to r.parse, EOFException is thrown + if (in.isReadable() == false) { LOG.debug("No more content in incoming buffer."); return; } @@ -69,7 +67,6 @@ public final class NetconfEXIToMessageDecoder extends ByteToMessageDecoder { final DOMResult domResult = new DOMResult(); handler.setResult(domResult); - try (final InputStream is = new ByteBufInputStream(in)) { r.parse(new InputSource(is)); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToHelloMessageDecoder.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToHelloMessageDecoder.java index c4808e0868..361d4fcee9 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToHelloMessageDecoder.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToHelloMessageDecoder.java @@ -7,16 +7,20 @@ */ package org.opendaylight.controller.netconf.util.handler; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage; import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader; @@ -28,12 +32,18 @@ import org.w3c.dom.Document; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableList; +import org.xml.sax.SAXException; /** * Customized NetconfXMLToMessageDecoder that reads additional header with * session metadata from * {@link org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage} - * . Used by netconf server to retrieve information about session metadata. + * + * + * This handler should be replaced in pipeline by regular message handler as last step of negotiation. + * It serves as a message barrier and halts all non-hello netconf messages. + * Netconf messages after hello should be processed once the negotiation succeeded. + * */ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder { private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToHelloMessageDecoder.class); @@ -46,9 +56,15 @@ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder new byte[] { '\r', '\n', '[' }, new byte[] { '\n', '[' }); + // State variables do not have to by synchronized + // Netty uses always the same (1) thread per pipeline + // We use instance of this per pipeline + private List nonHelloMessages = Lists.newArrayList(); + private boolean helloReceived = false; + @Override @VisibleForTesting - public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws IOException, SAXException, NetconfDocumentedException { if (in.readableBytes() == 0) { LOG.debug("No more content in incoming buffer."); return; @@ -76,18 +92,39 @@ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder Document doc = XmlUtil.readXmlToDocument(new ByteArrayInputStream(bytes)); - final NetconfMessage message; - if (additionalHeader != null) { - message = new NetconfHelloMessage(doc, NetconfHelloMessageAdditionalHeader.fromString(additionalHeader)); + final NetconfMessage message = getNetconfMessage(additionalHeader, doc); + if (message instanceof NetconfHelloMessage) { + Preconditions.checkState(helloReceived == false, + "Multiple hello messages received, unexpected hello: %s", + XmlUtil.toString(message.getDocument())); + out.add(message); + helloReceived = true; + // Non hello message, suspend the message and insert into cache } else { - message = new NetconfHelloMessage(doc); + Preconditions.checkState(helloReceived, "Hello message not received, instead received: %s", + XmlUtil.toString(message.getDocument())); + LOG.debug("Netconf message received during negotiation, caching {}", + XmlUtil.toString(message.getDocument())); + nonHelloMessages.add(message); } - out.add(message); } finally { in.discardReadBytes(); } } + private NetconfMessage getNetconfMessage(final String additionalHeader, final Document doc) throws NetconfDocumentedException { + NetconfMessage msg = new NetconfMessage(doc); + if(NetconfHelloMessage.isHelloMessage(msg)) { + if (additionalHeader != null) { + return new NetconfHelloMessage(doc, NetconfHelloMessageAdditionalHeader.fromString(additionalHeader)); + } else { + return new NetconfHelloMessage(doc); + } + } + + return msg; + } + private int getAdditionalHeaderEndIndex(byte[] bytes) { for (byte[] possibleEnd : POSSIBLE_ENDS) { int idx = findByteSequence(bytes, possibleEnd); @@ -152,4 +189,10 @@ public final class NetconfXMLToHelloMessageDecoder extends ByteToMessageDecoder return Charsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString(); } + /** + * @return Collection of NetconfMessages that were not hello, but were received during negotiation + */ + public Iterable getPostHelloNetconfMessages() { + return nonHelloMessages; + } } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToMessageDecoder.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToMessageDecoder.java index 06a4dc7207..23f48b31d8 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToMessageDecoder.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfXMLToMessageDecoder.java @@ -7,12 +7,6 @@ */ package org.opendaylight.controller.netconf.util.handler; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufInputStream; -import io.netty.buffer.ByteBufUtil; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ByteToMessageDecoder; - import java.util.List; import org.opendaylight.controller.netconf.api.NetconfMessage; @@ -22,12 +16,19 @@ import org.slf4j.LoggerFactory; import com.google.common.annotations.VisibleForTesting; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufInputStream; +import io.netty.buffer.ByteBufUtil; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; + public final class NetconfXMLToMessageDecoder extends ByteToMessageDecoder { private static final Logger LOG = LoggerFactory.getLogger(NetconfXMLToMessageDecoder.class); @Override @VisibleForTesting public void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + if (in.readableBytes() != 0) { LOG.trace("Received to decode: {}", ByteBufUtil.hexDump(in)); out.add(new NetconfMessage(XmlUtil.readXmlToDocument(new ByteBufInputStream(in)))); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/authentication/LoginPassword.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/authentication/LoginPassword.java index 4aa274c6df..c482e77735 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/authentication/LoginPassword.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/authentication/LoginPassword.java @@ -29,7 +29,7 @@ public class LoginPassword extends AuthenticationHandler { public void authenticate(Connection connection) throws IOException { boolean isAuthenticated = connection.authenticateWithPassword(username, password); - if (isAuthenticated == false) { + if (!isAuthenticated) { throw new IOException("Authentication failed."); } } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClient.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClient.java index 7beee649ab..50f44054c1 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClient.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClient.java @@ -58,8 +58,9 @@ public class SshClient { } public void close() { - for (SshSession session : openSessions.values()) + for (SshSession session : openSessions.values()){ closeSession(session); + } openSessions.clear(); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClientAdapter.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClientAdapter.java index 6350dd1544..244bcc0041 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClientAdapter.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/client/SshClientAdapter.java @@ -64,7 +64,7 @@ public class SshClientAdapter implements Runnable { } } - while (stopRequested.get() == false) { + while (!stopRequested.get()) { byte[] readBuff = new byte[BUFFER_SIZE]; int c = stdOut.read(readBuff); if (c == -1) { @@ -82,7 +82,7 @@ public class SshClientAdapter implements Runnable { // Netty closed connection prematurely. // Just pass and move on. } catch (Exception e) { - throw new RuntimeException(e); + throw new IllegalStateException(e); } finally { sshClient.close(); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java index 313ea93241..b8f13699ba 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/ssh/virtualsocket/ChannelInputStream.java @@ -12,7 +12,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandler; - import java.io.IOException; import java.io.InputStream; @@ -60,7 +59,7 @@ public class ChannelInputStream extends InputStream implements ChannelInboundHan lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new IllegalStateException(e); } } return this.bb.readByte() & 0xFF; diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java index 3fd25e814d..86b2ba1671 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfHelloMessage.java @@ -8,17 +8,21 @@ package org.opendaylight.controller.netconf.util.messages; -import com.google.common.base.Optional; -import com.google.common.collect.Sets; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; + +import java.util.Set; + +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; 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.w3c.dom.Document; import org.w3c.dom.Element; -import java.util.Set; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.Sets; /** * NetconfMessage that can carry additional header with session metadata. See {@link org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader} @@ -43,10 +47,10 @@ public final class NetconfHelloMessage extends NetconfMessage { return additionalHeader== null ? Optional.absent() : Optional.of(additionalHeader); } - private static void checkHelloMessage(Document doc) throws NetconfDocumentedException { - XmlElement.fromDomElementWithExpected(doc.getDocumentElement(), HELLO_TAG, - XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); - + private static void checkHelloMessage(Document doc) { + Preconditions.checkArgument(isHelloMessage(doc), + "Hello message invalid format, should contain %s tag from namespace %s, but is: %s", HELLO_TAG, + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, XmlUtil.toString(doc)); } public static NetconfHelloMessage createClientHello(Iterable capabilities, @@ -81,4 +85,21 @@ public final class NetconfHelloMessage extends NetconfMessage { doc.getDocumentElement().appendChild(sessionIdElement); return new NetconfHelloMessage(doc); } + + public static boolean isHelloMessage(final NetconfMessage msg) { + Document document = msg.getDocument(); + return isHelloMessage(document); + } + + private static boolean isHelloMessage(final Document document) { + XmlElement element = XmlElement.fromDomElement(document.getDocumentElement()); + try { + return element.getName().equals(HELLO_TAG) && + element.hasNamespace() && + element.getNamespace().equals(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); + } catch (MissingNameSpaceException e) { + // Cannot happen, since we check for hasNamespace + throw new IllegalStateException(e); + } + } } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageConstants.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageConstants.java index 8bd6b88659..5c2770a8c1 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageConstants.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/NetconfMessageConstants.java @@ -10,7 +10,9 @@ package org.opendaylight.controller.netconf.util.messages; import com.google.common.base.Charsets; -public class NetconfMessageConstants { +public final class NetconfMessageConstants { + + private NetconfMessageConstants(){} /** * The NETCONF 1.0 old-style message separator. This is framing mechanism * is used by default. @@ -26,4 +28,5 @@ public class NetconfMessageConstants { public static final int MAX_HEADER_LENGTH = 13; public static final byte[] END_OF_CHUNK = "\n##\n".getBytes(Charsets.UTF_8); + } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java index de2d6d7e0c..fdcaa2a5b8 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/messages/SendErrorExceptionUtil.java @@ -10,6 +10,8 @@ package org.opendaylight.controller.netconf.util.messages; import com.google.common.base.Preconditions; import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; import org.opendaylight.controller.netconf.api.NetconfSession; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; @@ -38,13 +40,15 @@ public final class SendErrorExceptionUtil { final NetconfDocumentedException sendErrorException) { logger.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException); final Document errorDocument = createDocument(sendErrorException); - session.sendMessage(new NetconfMessage(errorDocument)); + ChannelFuture f = session.sendMessage(new NetconfMessage(errorDocument)); + f.addListener(new SendErrorVerifyingListener(sendErrorException)); } public static void sendErrorMessage(Channel channel, NetconfDocumentedException sendErrorException) { logger.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException); final Document errorDocument = createDocument(sendErrorException); - channel.writeAndFlush(new NetconfMessage(errorDocument)); + ChannelFuture f = channel.writeAndFlush(new NetconfMessage(errorDocument)); + f.addListener(new SendErrorVerifyingListener(sendErrorException)); } public static void sendErrorMessage(NetconfSession session, NetconfDocumentedException sendErrorException, @@ -52,7 +56,8 @@ public final class SendErrorExceptionUtil { final Document errorDocument = createDocument(sendErrorException); logger.trace("Sending error {}", XmlUtil.toString(errorDocument)); tryToCopyAttributes(incommingMessage.getDocument(), errorDocument, sendErrorException); - session.sendMessage(new NetconfMessage(errorDocument)); + ChannelFuture f = session.sendMessage(new NetconfMessage(errorDocument)); + f.addListener(new SendErrorVerifyingListener(sendErrorException)); } private static void tryToCopyAttributes(final Document incommingDocument, final Document errorDocument, @@ -112,7 +117,7 @@ public final class SendErrorExceptionUtil { XPathConstants.NODE); errorSeverityNode.setTextContent(sendErrorException.getErrorSeverity().getTagValue()); - if (sendErrorException.getErrorInfo() != null && sendErrorException.getErrorInfo().isEmpty() == false) { + if (sendErrorException.getErrorInfo() != null && !sendErrorException.getErrorInfo().isEmpty()) { /* * message-id * rpc @@ -133,4 +138,20 @@ public final class SendErrorExceptionUtil { return errorDocument; } + /** + * Checks if netconf error was sent successfully. + */ + private static final class SendErrorVerifyingListener implements ChannelFutureListener { + private final NetconfDocumentedException sendErrorException; + + public SendErrorVerifyingListener(final NetconfDocumentedException sendErrorException) { + this.sendErrorException = sendErrorException; + } + + @Override + public void operationComplete(final ChannelFuture channelFuture) throws Exception { + Preconditions.checkState(channelFuture.isSuccess(), "Unable to send exception {}", sendErrorException, + channelFuture.cause()); + } + } } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java index 80eaa26de1..f89df2ac7c 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java @@ -9,12 +9,11 @@ package org.opendaylight.controller.netconf.util.osgi; import com.google.common.base.Optional; +import com.google.common.base.Strings; +import java.net.InetSocketAddress; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import java.net.InetSocketAddress; - import static com.google.common.base.Preconditions.checkNotNull; public final class NetconfConfigUtil { @@ -32,6 +31,8 @@ public final class NetconfConfigUtil { private static final String ADDRESS_SUFFIX_PROP = ".address"; private static final String CLIENT_PROP = ".client"; private static final String PRIVATE_KEY_PATH_PROP = ".pk.path"; + private static final String SSH_DEFAULT_USER = ".default.user"; + private static final String SSH_DEFAULT_PASSWORD = ".default.password"; private static final String CONNECTION_TIMEOUT_MILLIS_PROP = "connectionTimeoutMillis"; private static final long DEFAULT_TIMEOUT_MILLIS = 5000; @@ -54,7 +55,7 @@ public final class NetconfConfigUtil { Optional inetSocketAddressOptional = extractSomeNetconfAddress(context, InfixProp.tcp, exceptionMessageIfNotFound, forClient); - if (inetSocketAddressOptional.isPresent() == false) { + if (!inetSocketAddressOptional.isPresent()) { throw new IllegalStateException("Netconf tcp address not found." + exceptionMessageIfNotFound); } InetSocketAddress inetSocketAddress = inetSocketAddressOptional.get(); @@ -72,6 +73,13 @@ public final class NetconfConfigUtil { public static String getPrivateKeyPath(BundleContext context){ return getPropertyValue(context,PREFIX_PROP + InfixProp.ssh +PRIVATE_KEY_PATH_PROP); } + public static Optional getSSHDefaultUser(BundleContext context){ + return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_USER); + } + public static Optional getSSHDefaultPassword(BundleContext context){ + return getOptionalPropertyValue(context,PREFIX_PROP + InfixProp.ssh +SSH_DEFAULT_PASSWORD); + } + private static String getPropertyValue(BundleContext context, String propertyName){ String propertyValue = context.getProperty(propertyName); if (propertyValue == null){ @@ -79,6 +87,13 @@ public final class NetconfConfigUtil { } return propertyValue; } + private static Optional getOptionalPropertyValue(BundleContext context, String propertyName){ + String propertyValue = context.getProperty(propertyName); + if (Strings.isNullOrEmpty(propertyValue)){ + return Optional.absent(); + } + return Optional.fromNullable(propertyValue); + } /** * @param context * from which properties are being read. diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java index 17ea3740fc..66603fb6c2 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java @@ -180,7 +180,7 @@ public final class XmlElement { final List result = new ArrayList<>(); for (int i = 0; i < childNodes.getLength(); i++) { Node item = childNodes.item(i); - if (item instanceof Element == false) { + if (!(item instanceof Element)) { continue; } if (strat.accept((Element) item)) { @@ -400,7 +400,7 @@ public final class XmlElement { } else { prefix = ""; } - if (namespaces.containsKey(prefix) == false) { + if (!namespaces.containsKey(prefix)) { throw new IllegalArgumentException("Cannot find namespace for " + XmlUtil.toString(element) + ". Prefix from content is " + prefix + ". Found namespaces " + namespaces); } diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java index 39a49544a5..708f17cadb 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java @@ -46,7 +46,9 @@ public final class XmlNetconfConstants { // TODO duplicate public static final String RFC4741_TARGET_NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0"; public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0 = "urn:ietf:params:xml:ns:netconf:base:1.0"; - public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1 = "urn:ietf:params:xml:ns:netconf:base:1.1"; +// public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_1 = "urn:ietf:params:xml:ns:netconf:base:1.1"; + public static final String URN_IETF_PARAMS_NETCONF_BASE_1_0 = "urn:ietf:params:netconf:base:1.0"; + public static final String URN_IETF_PARAMS_NETCONF_BASE_1_1 = "urn:ietf:params:netconf:base:1.1"; public static final String URN_IETF_PARAMS_XML_NS_NETCONF_EXI_1_0 = "urn:ietf:params:xml:ns:netconf:exi:1.0"; public static final String URN_IETF_PARAMS_NETCONF_CAPABILITY_EXI_1_0 = "urn:ietf:params:netconf:capability:exi:1.0"; diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java index d8907424f8..1f81117ca3 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java @@ -8,12 +8,12 @@ package org.opendaylight.controller.netconf.util.xml; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; +import com.google.common.base.Charsets; +import com.google.common.base.Optional; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; import javax.xml.XMLConstants; import javax.xml.namespace.QName; @@ -23,7 +23,6 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Source; import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; @@ -33,14 +32,12 @@ import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - -import com.google.common.base.Charsets; -import com.google.common.base.Optional; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; public final class XmlUtil { @@ -81,7 +78,7 @@ public final class XmlUtil { try { dBuilder = BUILDERFACTORY.newDocumentBuilder(); } catch (ParserConfigurationException e) { - throw new RuntimeException("Failed to parse XML document", e); + throw new IllegalStateException("Failed to parse XML document", e); } Document doc = dBuilder.parse(xmlContent); @@ -96,10 +93,9 @@ public final class XmlUtil { public static Document newDocument() { try { DocumentBuilder builder = BUILDERFACTORY.newDocumentBuilder(); - Document document = builder.newDocument(); - return document; + return builder.newDocument(); } catch (ParserConfigurationException e) { - throw new RuntimeException("Failed to create document", e); + throw new IllegalStateException("Failed to create document", e); } } @@ -153,8 +149,8 @@ public final class XmlUtil { transformer.transform(source, result); return result.getWriter().toString(); - } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) { - throw new RuntimeException("Unable to serialize xml element " + xml, e); + } catch (Exception | TransformerFactoryConfigurationError e) { + throw new IllegalStateException("Unable to serialize xml element " + xml, e); } } diff --git a/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java b/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java index 07252b06f7..e95ab8095d 100644 --- a/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java +++ b/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java @@ -115,6 +115,9 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa * only subnet returned. As soon as a user-configured subnet is created this one will * vanish. */ + private static final String DISABLE_DEFAULT_SUBNET_PROP = "switchmanager.disableDefaultSubnetGateway"; + private static final String DISABLE_DEFAULT_SUBNET_PROP_VAL = System.getProperty(DISABLE_DEFAULT_SUBNET_PROP); + private static final boolean USE_DEFAULT_SUBNET_GW = !Boolean.valueOf(DISABLE_DEFAULT_SUBNET_PROP_VAL); protected static final SubnetConfig DEFAULT_SUBNETCONFIG; protected static final Subnet DEFAULT_SUBNET; protected static final String DEFAULT_SUBNET_NAME = "default (cannot be modifed)"; @@ -288,9 +291,9 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa @Override public List getSubnetsConfigList() { // if there are no subnets, return the default subnet - if(subnetsConfigList.size() == 0){ + if (USE_DEFAULT_SUBNET_GW && subnetsConfigList.isEmpty()) { return Collections.singletonList(DEFAULT_SUBNETCONFIG); - }else{ + } else { return new ArrayList(subnetsConfigList.values()); } } @@ -298,9 +301,9 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa @Override public SubnetConfig getSubnetConfig(String subnet) { // if there are no subnets, return the default subnet - if(subnetsConfigList.isEmpty() && subnet.equalsIgnoreCase(DEFAULT_SUBNET_NAME)){ + if (USE_DEFAULT_SUBNET_GW && subnetsConfigList.isEmpty() && subnet.equalsIgnoreCase(DEFAULT_SUBNET_NAME)) { return DEFAULT_SUBNETCONFIG; - }else{ + } else { return subnetsConfigList.get(subnet); } }