From: Ed Warnicke Date: Tue, 29 Apr 2014 15:08:14 +0000 (+0000) Subject: Merge "Statistics-Manager - Performance Improvement 1) Introduced statistics request... X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~161 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=386d8f0ac5fa09ee5514d48284f1a4012f408b52;hp=aae447eb2ce6272e1bfd2517a6493bf2ea40ed7a Merge "Statistics-Manager - Performance Improvement 1) Introduced statistics request scheduler, to schedule request based on the current transaction load on MD-SAL DataStore. Each node submit all individual statistics request to schedular for execution 2) Send statistics request if there is no MD-SAL trasaction pending. It just keep tracks of the MD-SAL trasaction triggered by statistics-manager 3) Removal of stale statistics is now done based on counter rather then time values. Time based removal will break in case of clustered environment. 4) Code clean up Change-Id: Ie7522d0c60f2c7051dbfcdf9a6657843ef4da743 Signed-off-by: Anil Vishnoi " --- 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/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..ae6ae67584 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 @@ -10,7 +10,7 @@ * * 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 +* Generated at: Fri Apr 25 11:50:32 CEST 2014 * * Do not modify this file unless it is present under src/main directory */ 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..07012263e1 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 @@ -10,7 +10,7 @@ * * 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 +* Generated at: Fri Apr 25 11:50:32 CEST 2014 * * Do not modify this file unless it is present under src/main directory */ 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..3baee6c132 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 @@ -10,7 +10,7 @@ * * 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 +* Generated at: Fri Apr 25 11:50:32 CEST 2014 * * Do not modify this file unless it is present under src/main directory */ 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..6f9118bf92 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 @@ -10,7 +10,7 @@ * * 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 +* Generated at: Fri Apr 25 11:50:32 CEST 2014 * * Do not modify this file unless it is present under src/main directory */ 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/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-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/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..857cc3e2e5 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 @@ -96,7 +96,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(); 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..6ddc8ebb55 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 @@ -38,9 +38,9 @@ public class AuthProvider implements AuthProviderInterface { } @Override - public boolean authenticated(String username, String password) throws Exception { + public boolean authenticated(String username, String password) { if (AuthProvider.um == null) { - throw new Exception("No usermanager service available."); + throw new IllegalStateException("No usermanager service available."); } AuthResultEnum authResult = AuthProvider.um.authenticate(username, password); return authResult.equals(AuthResultEnum.AUTH_ACCEPT) || authResult.equals(AuthResultEnum.AUTH_ACCEPT_LOC); 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..5b8803001c 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 @@ -45,7 +45,7 @@ public class NetconfSSHActivator implements BundleActivator{ private IUserManager iUserManager; private BundleContext context = null; - 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,19 +72,19 @@ 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 (server != null){ server.stop(); logger.trace("Netconf SSH bridge is down ..."); } } - private void startSSHServer() throws Exception { + private void startSSHServer() throws IllegalStateException, IOException { logger.trace("Starting netconf SSH bridge."); Optional sshSocketAddressOptional = NetconfConfigUtil.extractSSHNetconfAddress(context, EXCEPTION_MESSAGE); InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfAddress(context, @@ -94,14 +94,18 @@ public class NetconfSSHActivator implements BundleActivator{ String path = NetconfConfigUtil.getPrivateKeyPath(context); path = path.replace("\\", "/"); // FIXME: shouldn't this convert lines to system dependent path separator? 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 occured while generating PEM string {}",e); + } } else { // read from file try (FileInputStream fis = new FileInputStream(path)) { @@ -111,7 +115,12 @@ 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 { + 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 +129,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..b23a2d6697 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 @@ -54,7 +54,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(); 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); } }