</prerequisites>
<properties>
+ <aopalliance.version>1.0.0</aopalliance.version>
+ <appauth.version>0.4.2-SNAPSHOT</appauth.version>
+ <!-- Controller Modules Versions -->
<arphandler.version>0.5.2-SNAPSHOT</arphandler.version>
+ <!-- Plugin Versions -->
+ <bouncycastle.version>1.50</bouncycastle.version>
<bundle.plugin.version>2.3.7</bundle.plugin.version>
<bundlescanner.version>0.4.2-SNAPSHOT</bundlescanner.version>
<checkstyle.version>2.10</checkstyle.version>
<clustering.services.version>0.5.1-SNAPSHOT</clustering.services.version>
<clustering.services_implementation.version>0.4.3-SNAPSHOT</clustering.services_implementation.version>
<clustering.stub.version>0.4.2-SNAPSHOT</clustering.stub.version>
+ <clustering.test.version>0.4.2-SNAPSHOT</clustering.test.version>
+ <commmons.northbound.version>0.4.2-SNAPSHOT</commmons.northbound.version>
+ <!-- Third Party Versions -->
+ <commons.codec.version>1.7</commons.codec.version>
+ <commons.fileupload.version>1.2.2</commons.fileupload.version>
<commons.httpclient.version>0.1.2-SNAPSHOT</commons.httpclient.version>
<commons.io.version>2.4</commons.io.version>
<commons.lang.version>3.1</commons.lang.version>
+ <commons.net.version>3.0.1</commons.net.version>
<compiler.version>2.3.2</compiler.version>
<concepts.version>0.5.2-SNAPSHOT</concepts.version>
<config.version>0.2.5-SNAPSHOT</config.version>
+ <configuration.implementation.version>0.4.3-SNAPSHOT</configuration.implementation.version>
<configuration.version>0.4.3-SNAPSHOT</configuration.version>
<connectionmanager.version>0.1.2-SNAPSHOT</connectionmanager.version>
<containermanager.it.version>0.5.2-SNAPSHOT</containermanager.it.version>
+ <containermanager.northbound.version>0.4.2-SNAPSHOT</containermanager.northbound.version>
<containermanager.version>0.5.2-SNAPSHOT</containermanager.version>
- <!--versions for bits of the controller -->
+ <controllermanager.northbound.version>0.0.2-SNAPSHOT</controllermanager.northbound.version>
<corsfilter.version>7.0.42</corsfilter.version>
+ <devices.web.version>0.4.2-SNAPSHOT</devices.web.version>
+ <eclipse.persistence.version>2.5.0</eclipse.persistence.version>
<!-- enforcer version -->
<enforcer.version>1.3.1</enforcer.version>
<enunciate.version>1.26.2</enunciate.version>
<!-- OpenEXI third party lib for netconf-->
<exi.nagasena.version>0000.0002.0038.0-SNAPSHOT</exi.nagasena.version>
<failsafe.version>2.15</failsafe.version>
+ <felix.dependencymanager.shell.version>3.0.1</felix.dependencymanager.shell.version>
+ <felix.dependencymanager.version>3.1.0</felix.dependencymanager.version>
+ <felix.fileinstall.version>3.1.6</felix.fileinstall.version>
+ <felix.webconsole.version>4.2.0</felix.webconsole.version>
+ <flowprogrammer.northbound.version>0.4.2-SNAPSHOT</flowprogrammer.northbound.version>
+ <flows.web.version>0.4.2-SNAPSHOT</flows.web.version>
<forwarding.staticrouting>0.5.2-SNAPSHOT</forwarding.staticrouting>
+ <forwarding.staticrouting.northbound.version>0.4.2-SNAPSHOT</forwarding.staticrouting.northbound.version>
+ <forwardingrulesmanager.implementation.version>0.4.2-SNAPSHOT</forwardingrulesmanager.implementation.version>
<forwardingrulesmanager.version>0.6.0-SNAPSHOT</forwardingrulesmanager.version>
<geminiweb.version>2.2.0.RELEASE</geminiweb.version>
+ <gson.version>2.2.4</gson.version>
<guava.version>14.0.1</guava.version>
<hosttracker.api.version>0.5.2-SNAPSHOT</hosttracker.api.version>
<hosttracker.implementation.version>0.5.2-SNAPSHOT</hosttracker.implementation.version>
+ <hosttracker.northbound.version>0.4.2-SNAPSHOT</hosttracker.northbound.version>
<hosttracker_new.api.version>0.4.2-SNAPSHOT</hosttracker_new.api.version>
<ietf-inet-types.version>2010.09.24.4-SNAPSHOT</ietf-inet-types.version>
<ietf-topology.version>2013.10.21.2-SNAPSHOT</ietf-topology.version>
<!-- Third party version -->
<jersey-servlet.version>1.17</jersey-servlet.version>
<jersey.version>1.17</jersey.version>
+ <jettison.version>1.3.3</jettison.version>
<jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath>
<jolokia.version>1.1.4</jolokia.version>
+ <jsr305.api.version>2.0.1</jsr305.api.version>
+ <jsr311.api.version>1.1.1</jsr311.api.version>
<junit.version>4.8.1</junit.version>
<logback.version>1.0.9</logback.version>
<logging.bridge.version>0.4.2-SNAPSHOT</logging.bridge.version>
<netconf.version>0.2.5-SNAPSHOT</netconf.version>
<netty.version>4.0.17.Final</netty.version>
<networkconfig.bridgedomain.northbound.version>0.0.3-SNAPSHOT</networkconfig.bridgedomain.northbound.version>
+ <networkconfig.neutron.implementation.version>0.4.2-SNAPSHOT</networkconfig.neutron.implementation.version>
+ <networkconfig.neutron.northbound.version>0.4.2-SNAPSHOT</networkconfig.neutron.northbound.version>
+ <networkconfig.neutron.version>0.4.2-SNAPSHOT</networkconfig.neutron.version>
<!-- ODL repository / plugin repository -->
<nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
<opendaylight-l2-types.version>2013.08.27.4-SNAPSHOT</opendaylight-l2-types.version>
+ <osgi-brandfragment.web.version>0.0.2-SNAPSHOT</osgi-brandfragment.web.version>
+ <osgi.compendium.version>5.0.0</osgi.compendium.version>
<osgi.core.version>5.0.0</osgi.core.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<projectinfo>2.6</projectinfo>
-
<propertymavenplugin.version>1.0-alpha-2</propertymavenplugin.version>
<protocol-framework.version>0.5.0-SNAPSHOT</protocol-framework.version>
- <protocol_plugin.stub.version>0.4.2-SNAPSHOT</protocol_plugin.stub.version>
+ <protocol_plugins.openflow.version>0.4.2-SNAPSHOT</protocol_plugins.openflow.version>
+ <protocol_plugins.stub.version>0.4.2-SNAPSHOT</protocol_plugins.stub.version>
<releaseplugin.version>2.3.2</releaseplugin.version>
+ <routing.dijkstra_implementation.version>0.4.2-SNAPSHOT</routing.dijkstra_implementation.version>
<sal.connection.version>0.1.2-SNAPSHOT</sal.connection.version>
+ <sal.implementation.version>0.4.2-SNAPSHOT</sal.implementation.version>
<sal.networkconfiguration.version>0.0.3-SNAPSHOT</sal.networkconfiguration.version>
<sal.version>0.8.1-SNAPSHOT</sal.version>
<salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
<samples.loadbalancer>0.5.2-SNAPSHOT</samples.loadbalancer>
+ <samples.loadbalancer.northbound.version>0.4.2-SNAPSHOT</samples.loadbalancer.northbound.version>
+ <samples.simpleforwarding.version>0.4.2-SNAPSHOT</samples.simpleforwarding.version>
<sanitytest.version>0.4.2-SNAPSHOT</sanitytest.version>
+ <security.version>0.4.2-SNAPSHOT</security.version>
<sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
<siteplugin>3.2</siteplugin>
<slf4j.version>1.7.2</slf4j.version>
<spring-osgi.version>1.2.1</spring-osgi.version>
<spring-security.version>3.1.3.RELEASE</spring-security.version>
<spring.version>3.1.3.RELEASE</spring.version>
+ <statistics.northbound.version>0.4.2-SNAPSHOT</statistics.northbound.version>
+ <statisticsmanager.implementation.version>0.4.2-SNAPSHOT</statisticsmanager.implementation.version>
<statisticsmanager.version>0.5.1-SNAPSHOT</statisticsmanager.version>
+ <subnets.northbound.version>0.4.2-SNAPSHOT</subnets.northbound.version>
<surefire.version>2.15</surefire.version>
<switchmanager.api.version>0.7.1-SNAPSHOT</switchmanager.api.version>
+ <switchmanager.implementation.version>0.4.2-SNAPSHOT</switchmanager.implementation.version>
+ <switchmanager.northbound.version>0.4.2-SNAPSHOT</switchmanager.northbound.version>
<testvm.argLine>-Xmx1024m -XX:MaxPermSize=256m</testvm.argLine>
+ <topology.northbound.version>0.4.2-SNAPSHOT</topology.northbound.version>
+ <topology.web.version>0.4.2-SNAPSHOT</topology.web.version>
<topologymanager.version>0.4.2-SNAPSHOT</topologymanager.version>
+ <troubleshoot.web.version>0.4.2-SNAPSHOT</troubleshoot.web.version>
<url.version>1.5.0</url.version>
+ <usermanager.implementation.version>0.4.2-SNAPSHOT</usermanager.implementation.version>
+ <usermanager.northbound.version>0.0.2-SNAPSHOT</usermanager.northbound.version>
<usermanager.version>0.4.2-SNAPSHOT</usermanager.version>
<virgo.version>3.6.0.RELEASE</virgo.version>
+ <web.version>0.4.2-SNAPSHOT</web.version>
<xtend.dstdir>src/main/xtend-gen</xtend.dstdir>
<xtend.version>2.4.3</xtend.version>
<yang-ext.version>2013.09.07.4-SNAPSHOT</yang-ext.version>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>${jackson.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-jaxb-annotations</artifactId>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
- <version>2.0.1</version>
+ <version>${jsr305.api.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>2.2.4</version>
+ <version>${gson.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
- <version>1.7</version>
+ <version>${commons.codec.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
- <version>1.2.2</version>
+ <version>${commons.fileupload.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
- <version>3.0.1</version>
+ <version>${commons.net.version}</version>
</dependency>
<dependency>
<groupId>eclipselink</groupId>
<artifactId>netty-common</artifactId>
<version>${netty.version}</version>
</dependency>
-
- <!--Netty-->
+ <!-- Netty -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
<artifactId>netty-transport</artifactId>
<version>${netty.version}</version>
</dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>${jsr311.api.version}</version>
+ </dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>javax.activation</artifactId>
<dependency>
<groupId>org.aopalliance</groupId>
<artifactId>com.springsource.org.aopalliance</artifactId>
- <version>1.0.0</version>
+ <version>${aopalliance.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.dependencymanager</artifactId>
- <version>3.1.0</version>
+ <version>${felix.dependencymanager.version}</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.dependencymanager.shell</artifactId>
- <version>3.0.1</version>
+ <version>${felix.dependencymanager.shell.version}</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.fileinstall</artifactId>
- <version>3.1.6</version>
+ <version>${felix.fileinstall.version}</version>
</dependency>
<!-- felix webconsole -->
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.webconsole</artifactId>
- <version>4.2.0</version>
+ <version>${felix.webconsole.version}</version>
<!-- the all bundle includes all the necessary plugins -->
<classifier>all</classifier>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
- <version>1.50</version>
+ <version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
- <version>1.50</version>
+ <version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
<version>${enunciate.version}</version>
</dependency>
-
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
- <version>1.3.3</version>
+ <version>${jettison.version}</version>
</dependency>
<!-- equinox http service bridge -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.antlr</artifactId>
- <version>2.5.0</version>
+ <version>${eclipse.persistence.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
- <version>2.5.0</version>
+ <version>${eclipse.persistence.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
- <version>2.5.0</version>
+ <version>${eclipse.persistence.version}</version>
</dependency>
<!-- md-sal -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>appauth</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${appauth.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.test</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${clustering.test.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${commmons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.3-SNAPSHOT</version>
+ <version>${configuration.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${containermanager.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>controllermanager.northbound</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>${controllermanager.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>devices.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${devices.web.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>flowprogrammer.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${flowprogrammer.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>flows.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${flows.web.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${forwarding.staticrouting.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${forwardingrulesmanager.implementation.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${hosttracker.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${networkconfig.neutron.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${networkconfig.neutron.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${networkconfig.neutron.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>osgi-brandfragment.web</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>${osgi-brandfragment.web.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.openflow</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${protocol_plugins.openflow.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.stub</artifactId>
- <version>${protocol_plugin.stub.version}</version>
+ <version>${protocol_plugins.stub.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>routing.dijkstra_implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${routing.dijkstra_implementation.version}</version>
</dependency>
<!-- SAL bundles -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${sal.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>samples.loadbalancer.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${samples.loadbalancer.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>samples.simpleforwarding</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${samples.simpleforwarding.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>security</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${security.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statistics.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${statistics.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${statisticsmanager.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>subnets.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${subnets.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${switchmanager.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${switchmanager.northbound.version}</version>
</dependency>
<!-- threadpool -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topology.northbound</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${topology.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topology.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${topology.web.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>troubleshoot.web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${troubleshoot.web.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager.implementation</artifactId>
- <version>${usermanager.version}</version>
+ <version>${usermanager.implementation.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager.northbound</artifactId>
- <version>0.0.2-SNAPSHOT</version>
+ <version>${usermanager.northbound.version}</version>
</dependency>
<!-- Web bundles -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web</artifactId>
- <version>0.4.2-SNAPSHOT</version>
+ <version>${web.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
- <version>${osgi.core.version}</version>
+ <version>${osgi.compendium.version}</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
*/
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;
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";
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new NeverReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
}
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new ReconnectImmediatelyStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
}
*/
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;
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";
@Before
public void setUp() throws Exception {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TimedReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
}
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();
}
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;
}
};
- Map<String, Map.Entry<ModuleFactory, BundleContext>> allCurrentFactories = Collections.unmodifiableMap(
+ Map<String, Map.Entry<ModuleFactory, BundleContext>> 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(
// 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;
}
}
}
// 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<String, ServiceInterfaceAnnotation> 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
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++;
*/
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;
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
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<String, Entry<ModuleFactory, BundleContext>> 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);
}
// add default modules
for (ModuleFactory moduleFactory : toBeAdded) {
+ BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
Set<? extends Module> 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);
}
}
- 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);
oldConfigBeanInfo, moduleFactory), e);
}
putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo, dependencyResolver,
- oldConfigBeanInfo.isDefaultBean());
+ oldConfigBeanInfo.isDefaultBean(), bc);
}
@Override
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);
dependencyResolverManager.put(
moduleIdentifier, module, moduleFactory,
- maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean);
+ maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean, bundleContext);
return writableON;
}
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));
}
@Override
- public ServiceReferenceWritableRegistry getWritableRegistry() {
+ public SearchableServiceReferenceWritableRegistry getWritableRegistry() {
return writableSRRegistry;
}
*/
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).
BundleContext getModuleFactoryBundleContext(String factoryName);
- ServiceReferenceWritableRegistry getWritableRegistry();
+ SearchableServiceReferenceWritableRegistry getWritableRegistry();
TransactionIdentifier getTransactionIdentifier();
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 {
private final TransactionIdentifier transactionIdentifier;
private final DeadlockMonitorRunnable thread;
@GuardedBy("this")
- private ModuleIdentifierWithNanos moduleIdentifierWithNanos = new ModuleIdentifierWithNanos();
+ private final Deque<ModuleIdentifierWithNanos> moduleIdentifierWithNanosStack = new LinkedList<>();
+ @GuardedBy("this")
+ private ModuleIdentifierWithNanos top = ModuleIdentifierWithNanos.EMPTY;
public DeadlockMonitor(TransactionIdentifier transactionIdentifier) {
this.transactionIdentifier = transactionIdentifier;
}
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() {
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) {
}
}
- 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) {
result = 31 * result + (int) (nanoTime ^ (nanoTime >>> 32));
return result;
}
+
+ @Override
+ public String toString() {
+ return "ModuleIdentifierWithNanos{" +
+ moduleIdentifier +
+ '}';
+ }
}
}
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.
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(
this.moduleJMXRegistrator = moduleJMXRegistrator;
this.orderingIdx = orderingIdx;
this.isDefaultBean = isDefaultBean;
+ this.moduleFactory = moduleFactory;
+ this.bundleContext = bundleContext;
}
public DynamicReadableWrapper getReadableModule() {
public boolean isDefaultBean() {
return isDefaultBean;
}
+
+ public ModuleFactory getModuleFactory() {
+ return moduleFactory;
+ }
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.manager.impl;
+
+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<String /* service ref */, ServiceInterfaceAnnotation> findServiceInterfaces(ModuleIdentifier moduleIdentifier);
+
+}
*/
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;
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<String, ModuleFactory> factories;
private final ServiceReferenceRegistrator serviceReferenceRegistrator;
// helper method for getting QName of SI from namespace + local name
private final Map<String /* namespace */, Map<String /* local name */, ServiceInterfaceAnnotation>> namespacesToAnnotations;
+ private final Map<String /* service qName */, ServiceInterfaceAnnotation> serviceQNamesToAnnotations;
// all Service Interface qNames for sanity checking
private final Set<String /* qName */> allQNames;
+ Map<ModuleIdentifier, Map<String /* service ref name */, ServiceInterfaceAnnotation >> modulesToServiceRef = new HashMap<>();
+
// actual reference database
private final Map<ServiceReference, ModuleIdentifier> refNames = new HashMap<>();
/**
* 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<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories) {
Map<String, Set<String /* QName */>> modifiableFactoryNamesToQNames = new HashMap<>();
Set<ServiceInterfaceAnnotation> allAnnotations = new HashSet<>();
Set<String /* qName */> allQNames = new HashSet<>();
+
+
for (Entry<String, ModuleFactory> 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<ServiceInterfaceAnnotation> siAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(entry.getValue());
- Set<String> qNames = new HashSet<>();
- for (ServiceInterfaceAnnotation sia: siAnnotations) {
- qNames.add(sia.value());
- }
+ Set<String> qNames = InterfacesHelper.getQNames(siAnnotations);
allAnnotations.addAll(siAnnotations);
allQNames.addAll(qNames);
modifiableFactoryNamesToQNames.put(entry.getKey(), Collections.unmodifiableSet(qNames));
// fill namespacesToAnnotations
Map<String /* namespace */, Map<String /* localName */, ServiceInterfaceAnnotation>> modifiableNamespacesToAnnotations =
new HashMap<>();
+ Map<String /* service qName*/, ServiceInterfaceAnnotation> modifiableServiceQNamesToAnnotations = new HashMap<>();
for (ServiceInterfaceAnnotation sia : allAnnotations) {
Map<String, ServiceInterfaceAnnotation> ofNamespace = modifiableNamespacesToAnnotations.get(sia.namespace());
if (ofNamespace == null) {
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<String /* service ref */, ServiceInterfaceAnnotation> findServiceInterfaces(ModuleIdentifier moduleIdentifier) {
+ Map<String, ServiceInterfaceAnnotation> result = modulesToServiceRef.get(moduleIdentifier);
+ if (result == null) {
+ return Collections.emptyMap();
+ }
+ return Collections.unmodifiableMap(result);
+ }
@Override
public synchronized Set<String> lookupServiceInterfaceNames(ObjectName objectName) throws InstanceNotFoundException {
public synchronized Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> getServiceMapping() {
Map<String /* serviceInterfaceName */, Map<String/* refName */, ObjectName>> result = new HashMap<>();
for (Entry<ServiceReference, ModuleIdentifier> entry: refNames.entrySet()) {
- String qName = entry.getKey().getServiceInterfaceName();
+ String qName = entry.getKey().getServiceInterfaceQName();
Map<String /* refName */, ObjectName> innerMap = result.get(qName);
if (innerMap == null) {
innerMap = new HashMap<>();
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());
}
}
// save to refNames
refNames.put(serviceReference, moduleIdentifier);
+ Map<String, ServiceInterfaceAnnotation> 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;
}
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());
}
}
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<ServiceReferenceMXBeanImpl, ServiceReferenceJMXRegistration> entry = mBeans.remove(serviceReference);
if (entry == null) {
@Override
public synchronized boolean removeServiceReferences(ObjectName moduleObjectName) throws InstanceNotFoundException {
+ lookupRegistry.checkConfigBeanExists(moduleObjectName);
+ String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
+ // check that service interface name exist
+ Set<String> serviceInterfaceQNames = factoryNamesToQNames.get(factoryName);
+ return removeServiceReferences(moduleObjectName, serviceInterfaceQNames);
+ }
+
+
+ private boolean removeServiceReferences(ObjectName moduleObjectName, Set<String> qNames) throws InstanceNotFoundException {
+ ObjectNameUtil.checkType(moduleObjectName, ObjectNameUtil.TYPE_MODULE);
assertWritable();
- Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName);
+ Set<ServiceReference> serviceReferencesLinkingTo = findServiceReferencesLinkingTo(moduleObjectName, qNames);
for (ServiceReference sr : serviceReferencesLinkingTo) {
removeServiceReference(sr);
}
return serviceReferencesLinkingTo.isEmpty() == false;
}
- private synchronized Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName) throws InstanceNotFoundException {
- lookupRegistry.checkConfigBeanExists(moduleObjectName);
+ private Set<ServiceReference> findServiceReferencesLinkingTo(ObjectName moduleObjectName, Set<String> serviceInterfaceQNames) {
String factoryName = ObjectNameUtil.getFactoryName(moduleObjectName);
- // check that service interface name exist
- Set<String> 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);
return result;
}
-
@Override
public String toString() {
return "ServiceReferenceRegistryImpl{" +
*/
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;
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
ModuleFactory moduleFactory,
ModuleInternalInfo maybeOldInternalInfo,
TransactionModuleJMXRegistration transactionModuleJMXRegistration,
- boolean isDefaultBean) {
+ boolean isDefaultBean, BundleContext bundleContext) {
transactionStatus.checkNotCommitted();
Class<? extends Module> moduleClass = Module.class;
ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo(
moduleIdentifier, proxiedModule, moduleFactory,
- maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module);
+ maybeOldInternalInfo, transactionModuleJMXRegistration, isDefaultBean, module, bundleContext);
modulesHolder.put(moduleInternalTransactionalInfo);
}
import org.opendaylight.yangtools.concepts.Identifiable;
import javax.annotation.Nullable;
+import org.osgi.framework.BundleContext;
public class ModuleInternalTransactionalInfo implements Identifiable<ModuleIdentifier> {
private final ModuleIdentifier name;
private final ModuleInternalInfo maybeOldInternalInfo;
private final TransactionModuleJMXRegistration transactionModuleJMXRegistration;
private final boolean isDefaultBean;
+ private final BundleContext bundleContext;
public ModuleInternalTransactionalInfo(ModuleIdentifier name, Module proxiedModule,
ModuleFactory moduleFactory,
ModuleInternalInfo maybeOldInternalInfo,
TransactionModuleJMXRegistration transactionModuleJMXRegistration,
- boolean isDefaultBean, Module realModule) {
+ boolean isDefaultBean, Module realModule, BundleContext bundleContext) {
this.name = name;
this.proxiedModule = proxiedModule;
this.moduleFactory = moduleFactory;
this.transactionModuleJMXRegistration = transactionModuleJMXRegistration;
this.isDefaultBean = isDefaultBean;
this.realModule = realModule;
+ this.bundleContext = bundleContext;
}
public Module getRealModule() {
return realModule;
}
+
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
}
package org.opendaylight.controller.config.manager.impl.factoriesresolver;
-import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.osgi.framework.BundleContext;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
+import javax.management.InstanceNotFoundException;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.osgi.framework.BundleContext;
/**
* Hold sorted ConfigMBeanFactories by their module names. Check that module
* @throws IllegalArgumentException
* if factory is not found
*/
- public ModuleFactory findByModuleName(String moduleName) {
+ public ModuleFactory findByModuleName(String moduleName) throws InstanceNotFoundException {
Map.Entry<ModuleFactory, BundleContext> result = moduleNamesToConfigBeanFactories.get(moduleName);
if (result == null) {
- throw new IllegalArgumentException(
+ throw new InstanceNotFoundException(
"ModuleFactory not found with module name: " + moduleName);
}
return result.getKey();
return moduleFactories;
}
- public Map<String, Entry<ModuleFactory, BundleContext>> getModuleNamesToConfigBeanFactories() {
- return moduleNamesToConfigBeanFactories;
- }
}
this.refName = refName;
}
- public String getServiceInterfaceName() {
+ public String getServiceInterfaceQName() {
return serviceInterfaceName;
}
result = 31 * result + refName.hashCode();
return result;
}
+
+ @Override
+ public String toString() {
+ return "ServiceReference{" +
+ "serviceInterfaceName='" + serviceInterfaceName + '\'' +
+ ", refName='" + refName + '\'' +
+ '}';
+ }
}
*/
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<? extends Module> configBeanClass, AutoCloseable instance,
- ModuleIdentifier moduleIdentifier, BundleContext bundleContext) {
- try {
- final Set<Class<?>> configuresInterfaces = InterfacesHelper
- .getOsgiRegistrationTypes(configBeanClass);
- checkInstanceImplementing(instance, configuresInterfaces);
-
- // bundleContext.registerService blows up with empty 'clazzes'
- if (configuresInterfaces.isEmpty() == false) {
- final Dictionary<String, ?> 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<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+ return new OsgiRegistration(instance, moduleIdentifier, bundleContext, serviceNamesToAnnotations);
}
- private static String[] classesToNames(Set<Class<?>> cfgs) {
- String[] result = new String[cfgs.size()];
- int i = 0;
- for (Class<?> cfg : cfgs) {
- result[i] = cfg.getName();
- i++;
- }
+ private static Dictionary<String, String> createProps(String serviceName) {
+ Hashtable<String, String> result = new Hashtable<>();
+ result.put(SERVICE_NAME_OSGI_PROP, serviceName);
return result;
}
- private void checkInstanceImplementing(AutoCloseable instance,
- Set<Class<?>> configures) {
- Set<Class<?>> 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<String, ?> getPropertiesForOsgi(
- ModuleIdentifier moduleIdentifier) {
- Hashtable<String, String> 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<ServiceRegistration<?>> serviceRegistrations;
+ @GuardedBy("this")
+ private final Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations;
+
+ public OsgiRegistration(AutoCloseable instance, ModuleIdentifier moduleIdentifier,
+ BundleContext bundleContext,
+ Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+ this.instance = instance;
+ this.moduleIdentifier = moduleIdentifier;
+ this.serviceNamesToAnnotations = serviceNamesToAnnotations;
+ this.serviceRegistrations = registerToSR(instance, bundleContext, serviceNamesToAnnotations);
}
- public OsgiRegistration() {
- this.serviceRegistration = null;
+ private static Set<ServiceRegistration<?>> registerToSR(AutoCloseable instance, BundleContext bundleContext,
+ Map<String, ServiceInterfaceAnnotation> serviceNamesToAnnotations) {
+ Set<ServiceRegistration<?>> serviceRegistrations = new HashSet<>();
+ for (Entry<String, ServiceInterfaceAnnotation> entry : serviceNamesToAnnotations.entrySet()) {
+ Class<?> requiredInterface = entry.getValue().osgiRegistrationType();
+ checkState(requiredInterface.isInstance(instance), instance.getClass().getName() +
+ " instance should implement " + requiredInterface.getName());
+ Dictionary<String, String> 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<String, ServiceInterfaceAnnotation> 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<ServiceRegistration<?>> newRegs = registerToSR(instance, bundleContext, newAnnotationMapping);
+ serviceRegistrations.clear();
+ serviceRegistrations.addAll(newRegs);
+ }
+ }
+ }
}
return result;
}
+ public static Set<String> getQNames(Set<ServiceInterfaceAnnotation> siAnnotations) {
+ Set<String> qNames = new HashSet<>();
+ for (ServiceInterfaceAnnotation sia: siAnnotations) {
+ qNames.add(sia.value());
+ }
+ return Collections.unmodifiableSet(qNames);
+ }
public static Set<ServiceInterfaceAnnotation> getServiceInterfaceAnnotations(ModuleFactory factory) {
Set<Class<? extends AbstractServiceInterface>> implementedServiceIntefaces = Collections.unmodifiableSet(factory.getImplementedServiceIntefaces());
result.add(annotation);
}
}
- return result;
+ return Collections.unmodifiableSet(result);
}
static Set<Class<? extends AbstractServiceInterface>> getAllAbstractServiceInterfaceClasses(
*/
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;
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
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,
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;
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;
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<RegistrationHolder> registrations = new LinkedList<>();
@Override
- public void handleServiceRegistration(Object serviceInstance) {}
- };
+ public void handleServiceRegistration(Class<?> clazz, Object serviceInstance, Dictionary<String, ?> props) {
+
+ registrations.add(new RegistrationHolder(clazz, serviceInstance, props));
+ }
+
+ public List<RegistrationHolder> getRegistrations() {
+ return registrations;
+ }
+
+ protected static class RegistrationHolder {
+ protected final Class<?> clazz;
+ protected final Object instance;
+ protected final Dictionary<String, ?> props;
+
+ public RegistrationHolder(Class<?> clazz, Object instance, Dictionary<String, ?> 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);
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.<Dictionary<String, ?>>any());
- doAnswer(answer).when(mockedContext).registerService(Matchers.<Class<Closeable>>any(), any(Closeable.class),
- Matchers.<Dictionary<String, ?>>any());
- }
-
-
- public Collection<InputStream> getFilesAsInputStreams(List<String> paths) {
- final Collection<InputStream> resources = new ArrayList<>();
- List<String> 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.<String>emptyList(), failedToFind);
-
- return resources;
+ doAnswer(answer).when(mockedContext).registerService(Matchers.<String>any(), any(), Matchers.<Dictionary<String, ?>>any());
+ doAnswer(answer).when(mockedContext).registerService(Matchers.<Class>any(), any(), Matchers.<Dictionary<String, ?>>any());
}
@After
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());
.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
public static interface BundleContextServiceRegistrationHandler {
- void handleServiceRegistration(Object serviceInstance);
+ void handleServiceRegistration(Class<?> clazz, Object serviceInstance, Dictionary<String, ?> props);
}
Object serviceTypeRaw = args[0];
Object serviceInstance = args[1];
+ Dictionary<String, ?> 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<String, ?> 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<String, ?> props) {
BundleContextServiceRegistrationHandler serviceRegistrationHandler = getBundleContextServiceRegistrationHandler(serviceType);
if (serviceRegistrationHandler != null) {
- serviceRegistrationHandler.handleServiceRegistration(serviceType.cast(serviceInstance));
+ serviceRegistrationHandler.handleServiceRegistration(serviceType, serviceInstance, props);
}
}
}
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;
}
}, currentlyRegisteredFactories);
- ServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
+ SearchableServiceReferenceWritableRegistry writableRegistry = ServiceReferenceRegistryImpl.createSRWritableRegistry(
ServiceReferenceRegistryImpl.createInitialSRLookupRegistry(), txLookupRegistry, currentlyRegisteredFactories);
@Before
public void setUp() {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver());
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext));
}
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;
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;
import javax.management.MBeanException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
-
+import java.util.List;
import java.util.Map;
import java.util.Set;
@Before
public void setUp() {
super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ mockedContext,
new TestingFixedThreadPoolModuleFactory(),
new TestingParallelAPSPModuleFactory(),
new TestingScheduledThreadPoolModuleFactory()));
// 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<RegistrationHolder> registrations =
+ ((RecordingBundleContextServiceRegistrationHandler) currentBundleContextServiceRegistrationHandler).getRegistrations();
+ assertEquals(1, registrations.size());
+ RegistrationHolder record = registrations.get(0);
+ assertEquals(TestingThreadPoolIfc.class, record.clazz);
+ assertEquals(ImmutableMap.of("name","ref"), (Map<String, String>) record.props);
// switch reference to scheduled
ConfigTransactionJMXClient transaction2 = configRegistryClient.createTransaction();
*/
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;
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 {
moduleFactory,
maybeOldInternalInfo,
transactionModuleJMXRegistration,
- isDefaultBean);
+ isDefaultBean, mock(BundleContext.class));
}
private static Module mockedModule() {
}
}
- public HardcodedModuleFactoriesResolver(ModuleFactory... list) {
- this(mockBundleContext(),list);
- }
-
private static BundleContext mockBundleContext() {
BundleContext bundleContext = Mockito.mock(BundleContext.class);
ServiceRegistration<ModuleFactory> serviceRegistration = mock(ServiceRegistration.class);
@Before
public void setUp() {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingFixedThreadPoolModuleFactory(),
new TestingParallelAPSPModuleFactory()));
}
*/
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;
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";
ClassBasedModuleFactory mockedThreadPoolConfigFactory = new ClassBasedModuleFactory(
threadPoolImplementationName, MockedThreadPoolModule.class);
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingParallelAPSPModuleFactory(),
mockedThreadPoolConfigFactory));
}
*/
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";
public final void setUp() {
assertEquals(0,
TestingScheduledThreadPoolImpl.getNumberOfCloseMethodCalls());
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingScheduledThreadPoolModuleFactory(),
new TestingFixedThreadPoolModuleFactory(),
new TestingParallelAPSPModuleFactory()));
@Override
public void close() throws IOException {
executorService.shutdown();
+ allExecutors.remove(executorService);
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.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<String, Entry<ModuleFactory, BundleContext>> allFactories = ImmutableMap.of(
+ testingFixedThreadPoolModuleFactory.getImplementationName(),
+ Maps.<ModuleFactory, BundleContext>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());
+ }
+}
* 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<ObjectName> emptyONs = Collections
@Before
public void setUp() {
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
new TestingFixedThreadPoolModuleFactory()));
}
return fixed1names;
}
- private ObjectName createFixedThreadPool(
+ static ObjectName createFixedThreadPool(
ConfigTransactionJMXClient transaction)
throws InstanceAlreadyExistsException, InstanceNotFoundException {
transaction.assertVersion(0, 1);
// 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 {
// commit
transaction.commit();
// check that first threadpool is closed
- checkThreadPools(2, numberOfThreads2);
+ checkThreadPools(1, numberOfThreads2);
}
private void checkThreadPools(int expectedTotalNumberOfExecutors,
// 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);
}
platformMBeanServer.getMBeanInfo(transaction.getObjectName());
fail();
}catch(InstanceNotFoundException e){
+ assertEquals("org.opendaylight.controller:TransactionName=ConfigTransaction-0-1,type=ConfigTransaction", e.getMessage());
}
}
* @return prefix + key as used in getProperty method.
*/
String getFullKeyForReporting(String key);
+
+ String getPrefix();
+ String getPropertyWithoutPrefix(String fullKey);
}
public String getFullKeyForReporting(String key) {
return null;
}
+
+ @Override
+ public String getPrefix() {
+ return null;
+ }
+
+ @Override
+ public String getPropertyWithoutPrefix(String fullKey) {
+ return null;
+ }
}
public void setUp() throws Exception {
factory = new LogbackModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
public void setUp() throws IOException, ClassNotFoundException {
factory = new LogbackModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
/**
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();
@Before
public void setUp() {
factory = new GlobalEventExecutorModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
@Before
public void setUp() {
factory = new NettyThreadgroupModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
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) {
try {
// wait so that JMX response is received
Thread.sleep(1000);
- // first try to stop config-manager
- Bundle configManager = findConfigManager();
- if (configManager != null){
- logger.debug("Stopping config-manager");
- configManager.stop();
- Thread.sleep(1000);
- }
logger.debug("Stopping system bundle");
systemBundle.stop();
} catch (BundleException e) {
logger.warn("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 {
*/
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;
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
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();
private void assertStopped() throws Exception {
Thread.sleep(3000); // happens on another thread
- verify(mockedConfigManager).stop();
verify(mockedSysBundle).stop();
}
}
TestingScheduledThreadPoolModule.class, poolImplName);
factory = new AsyncEventBusModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
scheduledThreadPoolConfigFactory));
}
*/
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;
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;
public void setUp() {
factory = new EventBusModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
}
@Test
@Before
public void setUp() {
factory = new FixedThreadPoolModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
new NamingThreadFactoryModuleFactory()));
}
public void setUp() {
flexibleFactory = new FlexibleThreadPoolModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(flexibleFactory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,flexibleFactory,
new NamingThreadFactoryModuleFactory()));
}
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;
public void setUp() {
factory = new NamingThreadFactoryModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory));
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory));
}
@Test
public void setUp() {
factory = new ScheduledThreadPoolModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory,
new NamingThreadFactoryModuleFactory()));
}
*/
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;
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
public void setUp() {
factory = new TestImplModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
factory));
}
</dependencies>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>3.1</version>
- <configuration>
- <compilerId>groovy-eclipse-compiler</compilerId>
- <verbose>false</verbose>
- </configuration>
- <dependencies>
-
- <dependency>
- <groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy-eclipse-batch</artifactId>
- <version>2.1.8-01</version>
- </dependency>
- <dependency>
- <groupId>org.codehaus.groovy</groupId>
- <artifactId>groovy-eclipse-compiler</artifactId>
- <version>2.8.0-01</version>
- </dependency>
- </dependencies>
- </plugin>
-
- </plugins>
- </build>
</project>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.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<String> copyright) {
- FullyQualifiedName absFactoryFQN = new FullyQualifiedName(mbe.packageName, mbe.abstractFactoryName)
- FullyQualifiedName moduleFQN = new FullyQualifiedName(mbe.packageName, mbe.stubModuleName)
- Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription())
-
- AbstractFactoryTemplate abstractFactoryTemplate = TemplateFactory.abstractFactoryTemplateFromMbe(mbe)
- Optional<String> header = abstractFactoryTemplate.headerString;
- List<FullyQualifiedName> 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<String> copyright,
- Optional<String> header, Optional<String> classJavaDoc, QName yangModuleQName,
- String globallyUniqueName,
- List<FullyQualifiedName> providedServices,
- FullyQualifiedName moduleFQN,
- List<Field> 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<Class<? extends ${AbstractServiceInterface.canonicalName}>> 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<Field> 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<FullyQualifiedName> providedServices) {
- String generic = "Class<? extends ${AbstractServiceInterface.canonicalName}>"
-
- 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<? extends ${AbstractServiceInterface.canonicalName}> serviceInterface) {
- for (Class<?> ifc: serviceIfcs) {
- if (serviceInterface.isAssignableFrom(ifc)){
- return true;
- }
- }
- return false;
- }
-
- @Override
- public java.util.Set<Class<? extends ${AbstractServiceInterface.canonicalName}>> getImplementedServiceIntefaces() {
- return serviceIfcs;
- }
- """
-
- return result
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.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<String> copyright) {
+ FullyQualifiedName absFactoryFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractFactoryName());
+ FullyQualifiedName moduleFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getStubModuleName());
+ Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription());
+
+ AbstractFactoryTemplate abstractFactoryTemplate = TemplateFactory.abstractFactoryTemplateFromMbe(mbe);
+ Optional<String> header = abstractFactoryTemplate.getHeaderString();
+
+ List<FullyQualifiedName> 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<String> copyright,
+ Optional<String> header, Optional<String> classJavaDoc, QName yangModuleQName,
+ String globallyUniqueName,
+ List<FullyQualifiedName> providedServices,
+ FullyQualifiedName moduleFQN,
+ List<Field> 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<Class<? extends %s>> 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<Field> 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<FullyQualifiedName> providedServices) {
+ String generic = format("Class<? extends %s>", 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<? extends %1$s> 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<Class<? extends %1$s>> getImplementedServiceIntefaces() {\n"+
+ "return serviceIfcs;\n"+
+ "}\n", AbstractServiceInterface.class.getCanonicalName());
+
+ return result;
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.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<String> copyright) {
- FullyQualifiedName abstractFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractModuleName())
- Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription())
- AbstractModuleTemplate abstractModuleTemplate = TemplateFactory.abstractModuleTemplateFromMbe(mbe)
- Optional<String> header = abstractModuleTemplate.headerString;
- List<FullyQualifiedName> implementedInterfaces = abstractModuleTemplate.getTypeDeclaration().getImplemented().collect {
- FullyQualifiedName.fromString(it)
- }
- Optional<FullyQualifiedName> 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<String> copyright,
- Optional<String> header,
- Optional<String> classJavaDoc,
- List<FullyQualifiedName> implementedInterfaces,
- List<ModuleField> moduleFields,
- Optional<FullyQualifiedName> maybeRegistratorType,
- List<Method> 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<Method> 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<ModuleField> 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<ModuleField> 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<ModuleField, String> 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<ModuleField, String> 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<ModuleField, String> 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<ModuleField, String> 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<ModuleField> moduleFields) {
- return moduleFields.findAll { it.isIdentityRef() }.collect { IdentityRefModuleField field ->
- "private ${field.identityClassType} ${field.identityClassName};"
- }.join("\n")
- }
-
- private static String getCachesOfResolvedDependencies(List<ModuleField> 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<FullyQualifiedName> 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<ModuleField> moduleFields) {
- String result = """
- @Override
- public void validate() {
- """
- // validate each mandatory dependency
- List<String> 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<String, String> 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<String, String> 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<String, String> parameters = [
- (ModuleIdentifier.canonicalName): "identifier",
- (DependencyResolver.canonicalName): "dependencyResolver",
- (abstractFQN.typeName): "oldModule",
- (AutoCloseable.canonicalName): "oldInstance"
- ]
- return getConstructorStart(abstractFQN, parameters, "")
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.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<String> copyright) {
+ FullyQualifiedName abstractFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractModuleName());
+ Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription());
+ AbstractModuleTemplate abstractModuleTemplate = TemplateFactory.abstractModuleTemplateFromMbe(mbe);
+ Optional<String> header = abstractModuleTemplate.getHeaderString();
+
+ List<FullyQualifiedName> implementedInterfaces = new ArrayList<>();
+ for(String implemented: abstractModuleTemplate.getTypeDeclaration().getImplemented()) {
+ implementedInterfaces.add(FullyQualifiedName.fromString(implemented));
+ }
+ Optional<FullyQualifiedName> 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<String> copyright,
+ Optional<String> header,
+ Optional<String> classJavaDoc,
+ List<FullyQualifiedName> implementedInterfaces,
+ List<ModuleField> moduleFields,
+ Optional<FullyQualifiedName> maybeRegistratorType,
+ List<? extends Method> 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<? extends Method> 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<ModuleField> 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<ModuleField> 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<ModuleField, String> 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<ModuleField, String> 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<ModuleField> 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<ModuleField> 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<FullyQualifiedName> 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<ModuleField> 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<String, String> 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<String, String> 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<String, String> 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, "");
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.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<String> 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();
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.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<String> 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();
+ }
+}
*
* 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
*/
*
* 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
*/
*
* 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
*/
*
* 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
*/
public void setUp() {
factory = new NetconfTestImplModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(factory,
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory,
new DepTestImplModuleFactory(), new IdentityTestModuleFactory()));
}
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;
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();
</provider>
</instance>
</service>
+
<service>
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
binding:binding-broker-osgi-registry
</provider>
</instance>
</service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+ <instance>
+ <name>binding-rpc-broker</name>
+ <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+ </instance>
+ </service>
<service>
<type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
binding-impl:binding-dom-mapping-service
@Override
public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
- return listener.sendRequest(toRpcMessage(rpc, input, getSchemaContext()));
+ return listener.sendRequest(toRpcMessage(rpc, input, getSchemaContext()), rpc);
}
@Override
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;
private static final class Request {
final UncancellableFuture<RpcResult<CompositeNode>> future;
final NetconfMessage request;
+ final QName rpc;
- private Request(UncancellableFuture<RpcResult<CompositeNode>> future, NetconfMessage request) {
+ private Request(UncancellableFuture<RpcResult<CompositeNode>> future, NetconfMessage request, final QName rpc) {
this.future = future;
this.request = request;
+ this.rpc = rpc;
}
}
return;
}
- r.future.set(Rpcs.getRpcResult(true, NetconfMapping.toNotificationNode(message, device.getSchemaContext()),
- Collections.<RpcError>emptyList()));
+ r.future.set(NetconfMapping.toRpcResult(message, r.rpc, device.getSchemaContext()));
} else {
LOG.warn("Ignoring unsolicited message", message);
}
}
- synchronized ListenableFuture<RpcResult<CompositeNode>> sendRequest(final NetconfMessage message) {
+ synchronized ListenableFuture<RpcResult<CompositeNode>> sendRequest(final NetconfMessage message, final QName rpc) {
if (session == null) {
LOG.debug("Session to {} is disconnected, failing RPC request {}", device.getName(), message);
return Futures.<RpcResult<CompositeNode>>immediateFuture(new RpcResult<CompositeNode>() {
});
}
- final Request req = new Request(new UncancellableFuture<RpcResult<CompositeNode>>(true), message);
+ final Request req = new Request(new UncancellableFuture<RpcResult<CompositeNode>>(true), message, rpc);
requests.add(req);
session.sendMessage(req.request).addListener(new FutureListener<Void>() {
public void operationComplete(final Future<Void> 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);