From: Tony Tkacik Date: Tue, 15 Apr 2014 10:40:30 +0000 (+0000) Subject: Merge "Bug 714 - Fixed creating DOM Document's element with namespace" X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~226 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=1745f92957146128e8a4a111adb7ed830f737e0a;hp=c16bb7d2401d0f013e6dae3d0d877e3b7a208e46;p=controller.git Merge "Bug 714 - Fixed creating DOM Document's element with namespace" --- diff --git a/.gitignore b/.gitignore index 175ab5f0a0..6fc003be27 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ opendaylight/northbound/integrationtest/logs/* *.iws .idea xtend-gen +yang-gen-config +yang-gen-sal classes out/ .externalToolBuilders diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 1e8d3d26b5..d5d7e8e5c4 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -115,7 +115,9 @@ 1.3.1 2.4.3 - ${project.build.directory}/generated-sources/xtend-gen + src/main/xtend-gen + src/main/yang-gen-config + src/main/yang-gen-sal @@ -1717,7 +1719,7 @@ true ${project.basedir} **\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat - **\/target\/,**\/bin\/,**\/target-ide\/ + **\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/ @@ -1784,6 +1786,10 @@ + + org.codehaus.mojo + build-helper-maven-plugin + @@ -2005,6 +2011,52 @@ + + maven-clean-plugin + + + + ${xtend.dstdir} + + ** + + + + ${jmxGeneratorPath} + + ** + + + + ${salGeneratorPath} + + ** + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.8 + + + add-source + generate-sources + + add-source + + + + ${jmxGeneratorPath} + ${salGeneratorPath} + ${xtend.dstdir} + + + + + diff --git a/opendaylight/commons/protocol-framework/pom.xml b/opendaylight/commons/protocol-framework/pom.xml index 650d2dd35b..1a1a2561cc 100644 --- a/opendaylight/commons/protocol-framework/pom.xml +++ b/opendaylight/commons/protocol-framework/pom.xml @@ -25,11 +25,6 @@ 3.0.4 - - ${project.build.directory}/generated-sources/config - ${project.build.directory}/generated-sources/sal - - io.netty diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java index fb0718a721..e914162671 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java @@ -283,6 +283,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe int orderingIdx = 0; for (ModuleIdentifier moduleIdentifier : orderedModuleIdentifiers) { + logger.trace("Registering {}", moduleIdentifier); ModuleInternalTransactionalInfo entry = commitInfo.getCommitted() .get(moduleIdentifier); if (entry == null) { diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java index 6b7251c302..bc4de5cc15 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigTransactionControllerImpl.java @@ -44,6 +44,7 @@ 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; /** @@ -380,7 +381,8 @@ class ConfigTransactionControllerImpl implements try { logger.debug("About to commit {} in transaction {}", name, getTransactionIdentifier()); - module.getInstance(); + AutoCloseable instance = module.getInstance(); + checkNotNull(instance, "Instance is null:{} in transaction {}", name, getTransactionIdentifier()); } catch (Exception e) { logger.error("Commit failed on {} in transaction {}", name, getTransactionIdentifier(), e); diff --git a/opendaylight/config/config-module-archetype/src/main/resources/archetype-resources/pom.xml b/opendaylight/config/config-module-archetype/src/main/resources/archetype-resources/pom.xml index 21b1a5590b..80abd87262 100644 --- a/opendaylight/config/config-module-archetype/src/main/resources/archetype-resources/pom.xml +++ b/opendaylight/config/config-module-archetype/src/main/resources/archetype-resources/pom.xml @@ -8,8 +8,6 @@ bundle - ${project.build.directory}/generated-sources/config - ${project.build.directory}/generated-sources/sal ${config-api-version} ${yang-maven-plugin-version} ${maven-bundle-plugin-version} @@ -78,26 +76,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${jmxGeneratorPath} - - - - - - org.apache.felix maven-bundle-plugin diff --git a/opendaylight/config/config-plugin-parent/pom.xml b/opendaylight/config/config-plugin-parent/pom.xml index e382c33871..2c607f81d0 100644 --- a/opendaylight/config/config-plugin-parent/pom.xml +++ b/opendaylight/config/config-plugin-parent/pom.xml @@ -14,10 +14,6 @@ 3.0.4 - - ${project.build.directory}/generated-sources/config - - @@ -56,28 +52,6 @@ - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${jmxGeneratorPath} - ${salGeneratorPath} - - - - - diff --git a/opendaylight/config/logback-config/pom.xml b/opendaylight/config/logback-config/pom.xml index fbebda526a..2fe515c312 100644 --- a/opendaylight/config/logback-config/pom.xml +++ b/opendaylight/config/logback-config/pom.xml @@ -89,6 +89,7 @@ org.opendaylight.yangtools yang-maven-plugin + diff --git a/opendaylight/config/netty-threadgroup-config/pom.xml b/opendaylight/config/netty-threadgroup-config/pom.xml index 54143355f4..332426faa5 100644 --- a/opendaylight/config/netty-threadgroup-config/pom.xml +++ b/opendaylight/config/netty-threadgroup-config/pom.xml @@ -68,8 +68,6 @@ org.opendaylight.yangtools yang-maven-plugin - - org.apache.felix maven-bundle-plugin diff --git a/opendaylight/config/pom.xml b/opendaylight/config/pom.xml index d700075e95..8efed2d9f6 100644 --- a/opendaylight/config/pom.xml +++ b/opendaylight/config/pom.xml @@ -62,7 +62,6 @@ 5.0.0 0.6.2.201302030002 1.7.2 - ${project.build.directory}/generated-sources/sal @@ -305,26 +304,6 @@ - - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${salGeneratorPath} - - - - - org.apache.maven.plugins maven-jar-plugin diff --git a/opendaylight/config/yang-jmx-generator-plugin/pom.xml b/opendaylight/config/yang-jmx-generator-plugin/pom.xml index a8119b81ae..c934530067 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/pom.xml +++ b/opendaylight/config/yang-jmx-generator-plugin/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 config-subsystem @@ -30,6 +31,14 @@ binding-type-provider + + net.sourceforge.pmd + pmd + 5.1.0 + test + + + org.eclipse.jdt core @@ -53,12 +62,6 @@ - - org.freemarker - freemarker - 2.3.20 - - ${project.groupId} config-api @@ -110,14 +113,45 @@ org.apache.commons commons-lang3 + + + org.codehaus.gmaven.runtime + gmaven-runtime-2.0 + 1.5 + + + org.sonatype.gossip + gossip + + + + - org.apache.maven.plugins - maven-jar-plugin + maven-compiler-plugin + 3.1 + + groovy-eclipse-compiler + false + + + + org.codehaus.groovy + groovy-eclipse-compiler + 2.8.0-01 + + + + org.codehaus.groovy + groovy-eclipse-batch + 2.1.8-01 + + + diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/CodeWriter.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/CodeWriter.java index 13d828a430..dd2b504da9 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/CodeWriter.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/CodeWriter.java @@ -7,17 +7,155 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin; +import com.google.common.base.Optional; +import com.google.common.collect.Lists; +import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; +import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry; +import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.GeneralClassTemplate; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.GeneralInterfaceTemplate; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.RuntimeRegistratorFtlTemplate; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.StubFactoryTemplate; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory.AbsFactoryGeneratedObjectFactory; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory.AbsModuleGeneratedObjectFactory; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory.ConcreteModuleGeneratedObjectFactory; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory.GenericGeneratedObjectFactory; +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.util.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; -import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; -import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry; +final class CodeWriter { + + private static final Logger logger = LoggerFactory.getLogger(CodeWriter.class); + private static final Optional copyright = StringUtil.loadCopyright(); + + public File writeSie(ServiceInterfaceEntry sie, File outputBaseDir) { + try { + GeneralInterfaceTemplate generalInterfaceTemplate = TemplateFactory.serviceInterfaceFromSie(sie); + GeneratedObject go = new GenericGeneratedObjectFactory().toGeneratedObject(generalInterfaceTemplate, copyright); + return go.persist(outputBaseDir).get().getValue(); + } catch (Exception e) { + String message = "An error occurred during Service interface generating, sie:" + + sie.getTypeName() + ", " + sie.getFullyQualifiedName(); + logger.error(message, e); + throw new RuntimeException(message, e); + } + } + + public List writeMbe(ModuleMXBeanEntry mbe, File targetBaseDir, + File mainBaseDir) { + try { + List generatedFiles = Lists.newArrayList(); + + + Map gos = new HashMap<>(); + + // generate mx interface and abstract factory + + // TOs + Map tosFromMbe = TemplateFactory.tOsFromMbe(mbe); + for(GeneralClassTemplate template: tosFromMbe.values()) { + gos.put(new GenericGeneratedObjectFactory().toGeneratedObject(template, copyright), true); + } + + // MXBean interface + GeneralInterfaceTemplate ifcTemplate = TemplateFactory.mXBeanInterfaceTemplateFromMbe(mbe); + gos.put(new GenericGeneratedObjectFactory().toGeneratedObject(ifcTemplate, copyright), true); + + + // generate abstract factory + gos.put(new AbsFactoryGeneratedObjectFactory().toGeneratedObject(mbe, copyright), true); + + // generate abstract module + gos.put(new AbsModuleGeneratedObjectFactory().toGeneratedObject(mbe, copyright), true); + + // generate concrete factory + StubFactoryTemplate concreteFactory = TemplateFactory.stubFactoryTemplateFromMbe(mbe); + gos.put(new GenericGeneratedObjectFactory().toGeneratedObject(concreteFactory, copyright), false); + + + // generate concrete module + + gos.put(new ConcreteModuleGeneratedObjectFactory().toGeneratedObject(mbe, copyright, Optional.absent()), false); + + // write runtime bean MXBeans and registrators + List allFtlFiles = getRuntimeBeanFtlTemplates(mbe.getRuntimeBeans()); + for(FtlTemplate template: allFtlFiles) { + gos.put(new GenericGeneratedObjectFactory().toGeneratedObject(template, copyright), true); + } + + generatedFiles.addAll(persistGeneratedObjects(targetBaseDir, mainBaseDir, gos)); + + // purge nulls + for (Iterator it = generatedFiles.iterator(); it.hasNext(); ) { + if (it.next() == null) { + it.remove(); + } + } + + return generatedFiles; + + } catch (Exception e) { + String message = "An error occurred during Module generating, mbe:" + + mbe.getJavaNamePrefix(); + logger.error(message, e); + throw new RuntimeException(message, e); + } + } -public interface CodeWriter { + private List persistGeneratedObjects(File targetBaseDir, File mainBaseDir, Map gos) throws IOException { + List generatedFiles = new ArrayList<>(); + for (Entry entry : gos.entrySet()) { + boolean overwrite = entry.getValue(); + File dst; + if (overwrite) { + dst = targetBaseDir; + } else { + dst = mainBaseDir; + } + Optional> maybePersistEntry = entry.getKey().persist(dst, overwrite); - File writeSie(ServiceInterfaceEntry sie, File targetBaseDir); + if (maybePersistEntry.isPresent()) { + generatedFiles.add(maybePersistEntry.get().getValue()); + } + } + return generatedFiles; + } - List writeMbe(ModuleMXBeanEntry mbe, File targetBaseDir, - File mainBaseDir, File resourceBaseDir); + private List getRuntimeBeanFtlTemplates(Collection runtimeBeans) { + if (runtimeBeans.isEmpty()) { + return Collections.emptyList(); + } + List allFtlFiles = new ArrayList<>(); + { // registrators + Map registratorNamesToFtls = RuntimeRegistratorFtlTemplate + .create(RuntimeRegistratorFtlTemplate.findRoot(runtimeBeans)); + allFtlFiles.addAll(registratorNamesToFtls.values()); + } + { // TOs, MXBean interfaces + for (RuntimeBeanEntry runtimeBeanEntry : runtimeBeans) { + Collection ftlFiles = TemplateFactory + .getTOAndMXInterfaceFtlFiles(runtimeBeanEntry) + .values(); + allFtlFiles.addAll(ftlFiles); + } + } + return allFtlFiles; + } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/FreeMarkerCodeWriterImpl.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/FreeMarkerCodeWriterImpl.java deleted file mode 100644 index 2b84ed1d45..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/FreeMarkerCodeWriterImpl.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; -import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry; -import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlFilePersister; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.RuntimeRegistratorFtlTemplate; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.Lists; - -final class FreeMarkerCodeWriterImpl implements CodeWriter { - - private static final Logger logger = LoggerFactory - .getLogger(FreeMarkerCodeWriterImpl.class); - - private final FtlFilePersister ftlFilePersister = new FtlFilePersister(); - - public FreeMarkerCodeWriterImpl() { - } - - @Override - public File writeSie(ServiceInterfaceEntry sie, File outputBaseDir) { - try { - Collection values = TemplateFactory.getFtlTemplates( - sie).values(); - return ftlFilePersister.persist(values, outputBaseDir, true).get(0); - } catch (Exception e) { - String message = "An error occurred during Service interface generating, sie:" - + sie.getTypeName() + ", " + sie.getFullyQualifiedName(); - logger.error(message, e); - throw new RuntimeException(message, e); - } - } - - @Override - public List writeMbe(ModuleMXBeanEntry mbe, File targetBaseDir, - File mainBaseDir, File resourceBaseDir) { - try { - List generatedFiles = Lists.newArrayList(); - - generatedFiles.addAll(ftlFilePersister.persist(TemplateFactory - .getFtlTemplates(mbe).values(), targetBaseDir, true)); - generatedFiles.addAll(ftlFilePersister.persist(TemplateFactory - .getFtlStubTemplates(mbe).values(), mainBaseDir, false)); - - // write runtime bean MXBeans and registrators - Collection runtimeBeans = mbe.getRuntimeBeans(); - if (runtimeBeans.size() > 0) { - List allFtlFiles = new ArrayList<>(); - { // registrators - Map registratorNamesToFtls = RuntimeRegistratorFtlTemplate - .create(RuntimeRegistratorFtlTemplate.findRoot(runtimeBeans)); - - allFtlFiles.addAll(registratorNamesToFtls.values()); - } - { // TOs, MXBean interfaces - for (RuntimeBeanEntry runtimeBeanEntry : runtimeBeans) { - Collection ftlFiles = TemplateFactory - .getTOAndMXInterfaceFtlFiles(runtimeBeanEntry) - .values(); - allFtlFiles.addAll(ftlFiles); - } - } - boolean overwrite = true; - - FtlFilePersister ftlFilePersister = new FtlFilePersister(); - List persisted = ftlFilePersister.persist(allFtlFiles, - targetBaseDir, overwrite); - // FIXME: check for intersection - generatedFiles.addAll(persisted); - } - - // purge nulls - for (Iterator it = generatedFiles.iterator(); it.hasNext();) { - if (it.next() == null) { - it.remove(); - } - } - - return generatedFiles; - - } catch (Exception e) { - String message = "An error occurred during Module generating, mbe:" - + mbe.getJavaNamePrefix(); - logger.error(message, e); - throw new RuntimeException(message, e); - } - } - -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGenerator.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGenerator.java index e41ac66952..1b8905b987 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGenerator.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGenerator.java @@ -12,16 +12,6 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import java.io.File; -import java.io.IOException; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.apache.commons.io.FileUtils; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; @@ -40,6 +30,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.impl.StaticLoggerBinder; +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * This class interfaces with yang-maven-plugin. Gets parsed yang modules in * {@link SchemaContext}, and parameters form the plugin configuration, and @@ -61,7 +62,7 @@ public class JMXGenerator implements CodeGenerator { private boolean generateModuleFactoryFile = true; public JMXGenerator() { - this.codeWriter = new FreeMarkerCodeWriterImpl(); + this.codeWriter = new CodeWriter(); } public JMXGenerator(CodeWriter codeWriter) { @@ -139,7 +140,7 @@ public class JMXGenerator implements CodeGenerator { ModuleMXBeanEntry mbe = mbeEntry.getValue(); try { List files1 = codeWriter.writeMbe(mbe, outputBaseDir, - mainBaseDir, resourceBaseDir); + mainBaseDir); generatedFiles.addFile(files1); } catch (Exception e) { throw new RuntimeException( diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractFactoryTemplate.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractFactoryTemplate.java index 35dc7a3600..c3e51d6550 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractFactoryTemplate.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractFactoryTemplate.java @@ -8,94 +8,26 @@ package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl; import com.google.common.collect.Lists; -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.spi.Module; import org.opendaylight.controller.config.spi.ModuleFactory; -import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; 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.Header; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDefinition; -import org.osgi.framework.BundleContext; import java.util.Collections; import java.util.List; -/** - * - */ public class AbstractFactoryTemplate extends GeneralClassTemplate { private static final List implementedIfcs = Lists .newArrayList(ModuleFactory.class.getCanonicalName()); - private final String globallyUniqueName, moduleInstanceType; - private final List providedServices; - private final ModuleMXBeanEntry mbe; - public AbstractFactoryTemplate(Header header, String packageName, - String abstractFactoryName, String globallyUniqueName, - String moduleInstanceType, List fields, - List providedServices, ModuleMXBeanEntry mbe) { + String abstractFactoryName, + List fields) { super(header, packageName, abstractFactoryName, Collections . emptyList(), implementedIfcs, fields, Collections . emptyList(), true, false, Collections . emptyList()); - this.globallyUniqueName = globallyUniqueName; - this.moduleInstanceType = moduleInstanceType; - this.providedServices = providedServices; - this.mbe = mbe; - } - - public String getGloballyUniqueName() { - return globallyUniqueName; - } - - public String getInstanceType() { - return AutoCloseable.class.getCanonicalName(); - } - - public String getModuleNameType() { - return ModuleIdentifier.class.getCanonicalName(); - } - - public String getModuleInstanceType() { - return moduleInstanceType; - } - - public String getAbstractServiceInterfaceType() { - return AbstractServiceInterface.class.getCanonicalName(); - } - - public List getProvidedServices() { - return providedServices; - } - - public String getModuleType() { - return Module.class.getCanonicalName(); - } - - public String getDependencyResolverType() { - return DependencyResolver.class.getCanonicalName(); - } - - public String getDynamicMBeanWithInstanceType() { - return DynamicMBeanWithInstance.class.getCanonicalName(); - } - - public String getBundleContextType() { - return BundleContext.class.getCanonicalName(); - } - - @Override - public String getFtlTempleteLocation() { - return "factory_abs_template.ftl"; - } - - public ModuleMXBeanEntry getMbe() { - return mbe; } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractFtlTemplate.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractFtlTemplate.java index 7f80299f00..a9599783e6 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractFtlTemplate.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractFtlTemplate.java @@ -7,17 +7,18 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl; -import java.io.File; -import java.util.List; - +import com.google.common.base.Optional; +import com.google.common.collect.Lists; 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.Header; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Method; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.TypeDeclaration; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper; -import com.google.common.collect.Lists; +import java.util.Collections; +import java.util.List; public abstract class AbstractFtlTemplate implements FtlTemplate { private final String packageName; @@ -44,6 +45,15 @@ public abstract class AbstractFtlTemplate implements FtlTemplate { return header; } + @Override + public Optional getHeaderString() { + if (header == null) { + return Optional.absent(); + } else { + return Optional.of(header.toString()); + } + } + @Override public String getFullyQualifiedName() { return FullyQualifiedNameHelper.getFullyQualifiedName(getPackageName(), @@ -60,9 +70,14 @@ public abstract class AbstractFtlTemplate implements FtlTemplate { return typeDeclaration; } + @Override - public String getJavadoc() { - return javadoc; + public Optional getMaybeJavadoc() { + if (javadoc == null) { + return Optional.absent(); + } else { + return Optional.of(javadoc); + } } public void setJavadoc(String javadoc) { @@ -84,15 +99,10 @@ public abstract class AbstractFtlTemplate implements FtlTemplate { return methods; } - @Override - public File getRelativeFile() { - return new File(packageName.replace(".", File.separator), - getTypeDeclaration().getName() + ".java"); - } @Override - public String getFtlTempleteLocation() { - return "abstract_ftl_file.ftl"; + public List getConstructors() { + return Collections.emptyList(); } @Override diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractModuleTemplate.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractModuleTemplate.java index c40bfdfb9f..92a71c2530 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractModuleTemplate.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/AbstractModuleTemplate.java @@ -7,26 +7,15 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl; -import java.util.Collections; -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.runtime.RootRuntimeBeanRegistrator; -import org.opendaylight.controller.config.spi.Module; 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.Header; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDefinition; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -/** - * - */ +import java.util.Collections; +import java.util.List; + public class AbstractModuleTemplate extends GeneralClassTemplate { private final List moduleFields; @@ -50,22 +39,6 @@ public class AbstractModuleTemplate extends GeneralClassTemplate { return moduleFields; } - public String getInstanceType() { - return AutoCloseable.class.getCanonicalName(); - } - - public String getModuleNameType() { - return ModuleIdentifier.class.getCanonicalName(); - } - - public String getAbstractServiceInterfaceType() { - return AbstractServiceInterface.class.getCanonicalName(); - } - - public String getModuleType() { - return Module.class.getCanonicalName(); - } - public String getRegistratorType() { return registratorType; } @@ -74,29 +47,4 @@ public class AbstractModuleTemplate extends GeneralClassTemplate { return runtime; } - public String getDependencyResolverType() { - return DependencyResolver.class.getCanonicalName(); - } - - public String getDynamicMBeanWithInstanceType() { - return DynamicMBeanWithInstance.class.getCanonicalName(); - } - - public String getRootRuntimeRegistratorType() { - return RootRuntimeBeanRegistrator.class.getCanonicalName(); - } - - @Override - public String getFtlTempleteLocation() { - return "module_abs_template_new.ftl"; - } - - public String getLoggerType() { - return Logger.class.getCanonicalName(); - } - - public String getLoggerFactoryType() { - return LoggerFactory.class.getCanonicalName(); - } - } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersister.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersister.java deleted file mode 100644 index 37d5e6bd3f..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersister.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl; - -import com.google.common.annotations.VisibleForTesting; -import freemarker.template.Configuration; -import freemarker.template.Template; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.AnnotationsDirective; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.ConstructorsDirective; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.FieldsDirectiveProg; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.HeaderDirective; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.JavadocDirective; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.MethodsDirective; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.ModuleFieldsDirective; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.TypeDeclarationDirective; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives.UnimplementedExceptionDirective; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.regex.Pattern; - -public class FtlFilePersister { - private static final Logger logger = LoggerFactory - .getLogger(FtlFilePersister.class); - - private static final Pattern TRAILING_WHITESPACES = Pattern.compile(" +$", Pattern.MULTILINE); - - @VisibleForTesting - public Map serializeFtls( - Collection ftlFiles) { - Map result = new HashMap<>(); - for (FtlTemplate ftlFile : ftlFiles) { - - try (Writer writer = new StringWriter()) { - Template template = getCfg().getTemplate( - ftlFile.getFtlTempleteLocation()); - try { - template.process(ftlFile, writer); - } catch (Exception e) { - throw new IllegalStateException( - "Template error while generating " + ftlFile, e); - } - String fileContent = writer.toString(); - // remove trailing spaces - fileContent = TRAILING_WHITESPACES.matcher(fileContent).replaceAll(""); - result.put(ftlFile, fileContent); - } catch (IOException e) { - throw new IllegalStateException( - "Exception while processing template", e); - } - } - - return result; - } - - public List persist(Collection ftlFiles, - File dstFolder, boolean overwrite) throws IOException { - Map ftlFileStringMap = serializeFtls(ftlFiles); - List result = new ArrayList<>(); - for (Entry entry : ftlFileStringMap.entrySet()) { - FtlTemplate ftlFile = entry.getKey(); - File targetFile = new File(dstFolder, ftlFile.getRelativeFile() - .getPath()); - File pathToFile = targetFile.getParentFile(); - if (pathToFile.exists() == false) { - pathToFile.mkdirs(); - } - if (targetFile.exists() && overwrite == false) { - logger.trace("Skipping {} since it already exists", targetFile); - } else { - try (Writer fileWriter = new FileWriter(targetFile)) { - fileWriter.write(entry.getValue()); - } - logger.trace("{}: File {} generated successfully", - JMXGenerator.class.getCanonicalName(), targetFile); - result.add(targetFile); - } - } - return result; - } - - private Configuration getCfg() { - Configuration cfg = new Configuration(); - cfg.setClassForTemplateLoading(getClass(), "/freeMarker/"); - cfg.setSharedVariable("javadocD", new JavadocDirective()); - cfg.setSharedVariable("annotationsD", new AnnotationsDirective()); - cfg.setSharedVariable("typeDeclarationD", - new TypeDeclarationDirective()); - cfg.setSharedVariable("constructorsD", new ConstructorsDirective()); - cfg.setSharedVariable("fieldsD", new FieldsDirectiveProg()); - cfg.setSharedVariable("moduleFieldsD", new ModuleFieldsDirective()); - cfg.setSharedVariable("methodsD", new MethodsDirective()); - cfg.setSharedVariable("headerD", new HeaderDirective()); - cfg.setSharedVariable("unimplementedExceptionD", - new UnimplementedExceptionDirective()); - return cfg; - } - -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlTemplate.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlTemplate.java index 8172a58af6..d01f3f9223 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlTemplate.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlTemplate.java @@ -7,22 +7,24 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl; -import java.io.File; -import java.util.List; - +import com.google.common.base.Optional; 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.Header; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Method; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.TypeDeclaration; +import java.util.List; + public interface FtlTemplate { Header getHeader(); + Optional getHeaderString(); String getPackageName(); - String getJavadoc(); + Optional getMaybeJavadoc(); public List getAnnotations(); @@ -34,14 +36,5 @@ public interface FtlTemplate { List getMethods(); - /** - * @return relative path to file to be created. - */ - public File getRelativeFile(); - - /** - * - * @return ftl template location - */ - public String getFtlTempleteLocation(); + List getConstructors(); } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/StubFactoryTemplate.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/StubFactoryTemplate.java index be49f93bca..5d2d6644b0 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/StubFactoryTemplate.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/StubFactoryTemplate.java @@ -7,33 +7,21 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl; -import java.util.Collections; - -import org.opendaylight.controller.config.api.DynamicMBeanWithInstance; +import com.google.common.collect.Lists; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Header; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDefinition; -import com.google.common.collect.Lists; +import java.util.Collections; public class StubFactoryTemplate extends GeneralClassTemplate { - private final String moduleInstanceType; - public StubFactoryTemplate(Header header, String packageName, String name, - String extendedClass, String moduleInstanceType) { + String extendedClass) { super(header, packageName, name, Lists.newArrayList(extendedClass), Collections. emptyList(), Collections . emptyList(), Collections . emptyList()); - this.moduleInstanceType = moduleInstanceType; - } - - public String getModuleInstanceType() { - return moduleInstanceType; } - public String getDynamicMBeanWithInstanceType() { - return DynamicMBeanWithInstance.class.getCanonicalName(); - } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/StubModuleTemplate.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/StubModuleTemplate.java deleted file mode 100644 index f49bbbacab..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/StubModuleTemplate.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl; - -import java.util.Collections; - -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.spi.Module; -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.Header; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDefinition; - -import com.google.common.collect.Lists; - -/** - * - */ -public class StubModuleTemplate extends GeneralClassTemplate { - - private final String extendedClass; - - public StubModuleTemplate(Header header, String packageName, - String stubModuleName, String extendedClass) { - super(header, packageName, stubModuleName, Lists - .newArrayList(extendedClass), Collections. emptyList(), - Collections. emptyList(), Collections - . emptyList(), false, true, - Collections. emptyList()); - this.extendedClass = extendedClass; - } - - public String getExtendedClass() { - return extendedClass; - } - - public String getInstanceType() { - return AutoCloseable.class.getCanonicalName(); - } - - public String getModuleNameType() { - return ModuleIdentifier.class.getCanonicalName(); - } - - public String getAbstractServiceInterfaceType() { - return AbstractServiceInterface.class.getCanonicalName(); - } - - public String getModuleType() { - return Module.class.getCanonicalName(); - } - - public String getDependencyResolverType() { - return DependencyResolver.class.getCanonicalName(); - } - - public String getDynamicMBeanWithInstanceType() { - return DynamicMBeanWithInstance.class.getCanonicalName(); - } - - @Override - public String getFtlTempleteLocation() { - return "module_stub_template.ftl"; - } -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java index fea9a79616..7b7aab8559 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java @@ -7,9 +7,7 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl; -import com.google.common.base.Function; import com.google.common.base.Preconditions; -import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.opendaylight.controller.config.api.DependencyResolver; @@ -45,12 +43,10 @@ import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQual import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil; import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType; import org.opendaylight.yangtools.sal.binding.model.api.Type; -import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition; import javax.management.openmbean.SimpleType; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -59,49 +55,6 @@ import java.util.Map.Entry; public class TemplateFactory { - public static Map getFtlTemplates( - ModuleMXBeanEntry entry) { - Map result = new HashMap<>(); - - result.putAll(TemplateFactory.tOsFromMbe(entry)); - - // IFC - result.put(entry.getMXBeanInterfaceName() + ".java", - TemplateFactory.mXBeanInterfaceTemplateFromMbe(entry)); - - // ABS fact - result.put(entry.getAbstractFactoryName() + ".java", - TemplateFactory.abstractFactoryTemplateFromMbe(entry)); - - // ABS module - result.put(entry.getAbstractModuleName() + ".java", - TemplateFactory.abstractModuleTemplateFromMbe(entry)); - - return result; - } - - public static Map getFtlStubTemplates( - ModuleMXBeanEntry entry) { - Map result = new HashMap<>(); - // STUB fact - result.put(entry.getStubFactoryName() + ".java", - TemplateFactory.stubFactoryTemplateFromMbe(entry)); - - result.put(entry.getStubModuleName() + ".java", - TemplateFactory.stubModuleTemplateFromMbe(entry)); - return result; - } - - public static Map getFtlTemplates( - ServiceInterfaceEntry entry) { - - Map result = new HashMap<>(); - result.put(entry.getTypeName() + ".java", - TemplateFactory.serviceInterfaceFromSie(entry)); - - return result; - } - /** * Get map of file name as key, FtlFile instance representing runtime mx * bean as value that should be persisted from this instance. @@ -183,11 +136,6 @@ public class TemplateFactory { return serializeType(type, false); } - private static boolean isIdentityRefType(Type type) { - return type instanceof IdentityrefTypeDefinition; - } - - private static String getReturnType(AttributeIfc attributeIfc) { String returnType; if (attributeIfc instanceof TypedAttribute) { @@ -234,28 +182,17 @@ public class TemplateFactory { attrProcessor.processAttributes(mbe.getAttributes(), mbe.getPackageName()); - Collection transformed = Collections2.transform(mbe - .getProvidedServices().keySet(), - new Function() { - @Override - public String apply(String input) { - return input + ".class"; - } - }); return new AbstractFactoryTemplate(getHeaderFromEntry(mbe), mbe.getPackageName(), mbe.getAbstractFactoryName(), - mbe.getGloballyUniqueName(), mbe.getFullyQualifiedName(mbe - .getStubModuleName()), attrProcessor.getFields(), - Lists.newArrayList(transformed), mbe); + attrProcessor.getFields() + ); } public static AbstractModuleTemplate abstractModuleTemplateFromMbe( ModuleMXBeanEntry mbe) { - AbstractModuleAttributesProcessor attrProcessor = new AbstractModuleAttributesProcessor(); - attrProcessor.processAttributes(mbe.getAttributes(), - mbe.getPackageName()); + AbstractModuleAttributesProcessor attrProcessor = new AbstractModuleAttributesProcessor(mbe.getAttributes()); List moduleFields = attrProcessor.getModuleFields(); List implementedIfcs = Lists.newArrayList( @@ -298,15 +235,8 @@ public class TemplateFactory { ModuleMXBeanEntry mbe) { return new StubFactoryTemplate(getHeaderFromEntry(mbe), mbe.getPackageName(), mbe.getStubFactoryName(), - mbe.getFullyQualifiedName(mbe.getAbstractFactoryName()), - mbe.getStubModuleName()); - } - - public static StubModuleTemplate stubModuleTemplateFromMbe( - ModuleMXBeanEntry mbe) { - return new StubModuleTemplate(getHeaderFromEntry(mbe), - mbe.getPackageName(), mbe.getStubModuleName(), - mbe.getFullyQualifiedName(mbe.getAbstractModuleName())); + mbe.getFullyQualifiedName(mbe.getAbstractFactoryName()) + ); } public static GeneralInterfaceTemplate mXBeanInterfaceTemplateFromMbe( @@ -612,12 +542,26 @@ public class TemplateFactory { } private static class AbstractModuleAttributesProcessor { + private static class Holder { + private final List moduleFields; + private final List methods; + + private Holder(List moduleFields, List methods) { + this.moduleFields = Collections.unmodifiableList(moduleFields); + this.methods = Collections.unmodifiableList(methods); + } + } - private final List moduleFields = Lists.newArrayList(); - private final List methods = Lists.newArrayList(); + private final Holder holder; - void processAttributes(Map attributes, - String packageName) { + + private AbstractModuleAttributesProcessor(Map attributes) { + this.holder = processAttributes(attributes); + } + + private static Holder processAttributes(Map attributes) { + List moduleFields = new ArrayList<>(); + List methods = new ArrayList<>(); for (Entry attrEntry : attributes.entrySet()) { String type, nullableDefaultWrapped = null; AttributeIfc attributeIfc = attrEntry.getValue(); @@ -661,7 +605,7 @@ public class TemplateFactory { String varName = BindingGeneratorUtil .parseToValidParamName(attrEntry.getKey()); - + { ModuleField field; if (isIdentity) { @@ -695,7 +639,7 @@ public class TemplateFactory { nullableDefaultWrapped, isDependency, dependency, isListOfDependencies, needsDepResolver); } moduleFields.add(field); - + } String getterName = "get" + attributeIfc.getUpperCaseCammelCase(); MethodDefinition getter = new MethodDefinition(type, @@ -727,14 +671,15 @@ public class TemplateFactory { methods.add(setter); } + return new Holder(moduleFields, methods); } List getModuleFields() { - return moduleFields; + return holder.moduleFields; } List getMethods() { - return methods; + return holder.methods; } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/AnnotationsDirective.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/AnnotationsDirective.java deleted file mode 100644 index 4a34a1f294..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/AnnotationsDirective.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives; - -import java.io.IOException; -import java.io.Writer; -import java.util.List; -import java.util.Map; - -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.Annotation.Parameter; - -import com.google.common.collect.Lists; - -import freemarker.core.Environment; -import freemarker.template.SimpleSequence; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; - -/** - * Add annotations to freemarker template. - */ -public class AnnotationsDirective implements TemplateDirectiveModel { - - private static final String OBJECT = "object"; - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - Object object = params.get(OBJECT); - List annotations = Lists.newArrayList(); - - if (object != null) { - if (object instanceof SimpleSequence) - annotations = ((SimpleSequence) object).toList(); - else if (object instanceof FtlTemplate) { - annotations = ((FtlTemplate) object).getAnnotations(); - } else - throw new IllegalArgumentException( - "Object must be a SimpleSequence or instance of " - + FtlTemplate.class + "but was " - + object.getClass()); - } - - Writer out = env.getOut(); - StringBuilder build = new StringBuilder(); - writeAnnotations(annotations, build, ""); - - if (!annotations.isEmpty()) - out.write(build.toString().toCharArray()); - } - - static void writeAnnotations(List annotations, - StringBuilder build, String linePrefix) { - for (Annotation annotation : annotations) { - build.append(linePrefix + "@"); - build.append(annotation.getName()); - if (!annotation.getParams().isEmpty()) { - build.append("("); - for (Parameter param : annotation.getParams()) { - build.append(param.getKey()); - build.append(" = "); - build.append(fixString(param.getValue())); - build.append(", "); - } - build.setCharAt(build.length() - 2, ')'); - } - build.append(System.lineSeparator()); - } - } - - private static String fixString(String value) { - // TODO replace with compress single line if possible - return value.replaceAll("\\r\\n|\\r|\\n", " ").replaceAll(" +", " "); - } - -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/ConstructorsDirective.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/ConstructorsDirective.java deleted file mode 100644 index 56b7286eb5..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/ConstructorsDirective.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives; - -import java.io.IOException; -import java.io.Writer; -import java.util.List; -import java.util.Map; - -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.GeneralClassTemplate; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Constructor; - -import com.google.common.collect.Lists; - -import freemarker.core.Environment; -import freemarker.template.SimpleSequence; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; - -/** - * Add annotations to freemarker template. - */ -public class ConstructorsDirective implements TemplateDirectiveModel { - - private static final String OBJECT = "object"; - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - Object object = params.get(OBJECT); - List constructors = Lists.newArrayList(); - - if (object != null) { - if (object instanceof SimpleSequence) - constructors = ((SimpleSequence) object).toList(); - else if (object instanceof GeneralClassTemplate) { - constructors = ((GeneralClassTemplate) object) - .getConstructors(); - } else - throw new IllegalArgumentException( - "Object must be a SimpleSequence or instance of " - + GeneralClassTemplate.class + "but was " - + object.getClass()); - } - - Writer out = env.getOut(); - StringBuilder build = new StringBuilder(); - for (Constructor constr : constructors) { - build.append(" "); - if (constr.isPublic()) - build.append("public "); - build.append(constr.getTypeName() + " "); - build.append("() {"); - build.append(System.lineSeparator()); - build.append(" "); - build.append(" "); - build.append(constr.getBody()); - build.append(System.lineSeparator()); - build.append(" "); - build.append("}"); - build.append(System.lineSeparator()); - build.append(System.lineSeparator()); - } - - if (!constructors.isEmpty()) - out.write(build.toString().toCharArray()); - } - -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/FieldsDirectiveProg.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/FieldsDirectiveProg.java deleted file mode 100644 index 7dd0f8e992..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/FieldsDirectiveProg.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives; - -import java.io.IOException; -import java.io.Writer; -import java.util.List; -import java.util.Map; - -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field; - -import com.google.common.collect.Lists; - -import freemarker.core.Environment; -import freemarker.template.SimpleSequence; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; - -/** - * Add fields to freemarker template. - */ -public class FieldsDirectiveProg implements TemplateDirectiveModel { - - private static final String OBJECT = "object"; - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - Object object = params.get(OBJECT); - List fields = Lists.newArrayList(); - - if (object != null) { - if (object instanceof SimpleSequence) - fields = ((SimpleSequence) object).toList(); - else if (object instanceof FtlTemplate) { - fields = ((FtlTemplate) object).getFields(); - } else - throw new IllegalArgumentException( - "Object must be a SimpleSequence or instance of " - + FtlTemplate.class + "but was " - + object.getClass()); - } - - Writer out = env.getOut(); - StringBuilder build = new StringBuilder(); - for (Field field : fields) { - build.append(" private "); - for (String mod : field.getModifiers()) { - build.append(mod + " "); - } - build.append(field.getType() + " "); - build.append(field.getName()); - if (field.getDefinition() != null) - build.append(" = " + field.getDefinition()); - build.append(";"); - build.append(System.lineSeparator()); - } - - if (!fields.isEmpty()) - out.write(build.toString().toCharArray()); - } - - // String templateStr = "Hello ${user}"; - // Template t = new Template("name", new StringReader(templateStr), new - // Configuration()); -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/FieldsDirectiveTemplate.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/FieldsDirectiveTemplate.java deleted file mode 100644 index 268d898477..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/FieldsDirectiveTemplate.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives; - -import java.io.IOException; -import java.io.StringReader; -import java.io.Writer; -import java.util.Map; - -import com.google.common.collect.Maps; - -import freemarker.core.Environment; -import freemarker.template.Configuration; -import freemarker.template.Template; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; - -/** - * Add fields to freemarker template. - */ -public class FieldsDirectiveTemplate implements TemplateDirectiveModel { - - private static final String OBJECT = "object"; - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - Object object = params.get(OBJECT); - - // TODO check type - - String templateStr = " <#list fields as field>" - + "private <#if field.final==true>final <#if field.static==true>static " - + "${field.type} ${field.name}<#if field.definition??> = ${field.definition};" - + System.lineSeparator() + " "; - Template t = new Template("name", new StringReader(templateStr), - new Configuration()); - - try { - Map map = Maps.newHashMap(); - map.put("fields", object); - Writer out = env.getOut(); - t.process(map, out); - } catch (TemplateException e) { - throw new IllegalStateException( - "Template error while generating fields" + e); - } - } - -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/HeaderDirective.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/HeaderDirective.java deleted file mode 100644 index 93fde59e96..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/HeaderDirective.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives; - -import java.io.IOException; -import java.io.Writer; -import java.util.Date; -import java.util.Map; - -import org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Header; - -import com.google.common.base.Preconditions; - -import freemarker.core.Environment; -import freemarker.ext.beans.StringModel; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; - -/** - * Add annotations to freemarker template. - */ -public class HeaderDirective implements TemplateDirectiveModel { - - private static final String GENERATOR_CLASS = JMXGenerator.class - .getCanonicalName(); - private static final String OBJECT = "header"; - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - - // FIXME do not allow null header - // Preconditions.checkNotNull(object, "Null type declaration"); - Object object = params.get(OBJECT); - Header header = null; - if (object != null) { - object = ((StringModel) object).getWrappedObject(); - Preconditions.checkArgument(object instanceof Header, - "Template header should be instance of " + Header.class - + " but was " + object.getClass()); - - header = (Header) object; - } - - Writer out = env.getOut(); - StringBuilder build = new StringBuilder(); - build.append("/**"); - build.append(System.lineSeparator()); - build.append("* "); - build.append("Generated file"); - build.append(System.lineSeparator()); - build.append(System.lineSeparator()); - build.append("* "); - build.append("Generated from: "); - build.append(header != null ? header.toString() : ""); - build.append(System.lineSeparator()); - build.append("* "); - build.append("Generated by: " + GENERATOR_CLASS); - build.append(System.lineSeparator()); - build.append("* "); - build.append("Generated at: " + new Date()); - build.append(System.lineSeparator()); - build.append("* "); - build.append(System.lineSeparator()); - build.append("* "); - build.append("Do not modify this file unless it is present under src/main directory "); - build.append(System.lineSeparator()); - build.append("*/"); - build.append(System.lineSeparator()); - - out.write(build.toString().toCharArray()); - } -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/JavadocDirective.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/JavadocDirective.java deleted file mode 100644 index 9817be3ea3..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/JavadocDirective.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives; - -import java.io.IOException; -import java.io.Writer; -import java.util.Map; - -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate; - -import freemarker.core.Environment; -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; - -/** - * Add javadoc to freemarker template as String. - */ -public class JavadocDirective implements TemplateDirectiveModel { - - private static final String OBJECT = "object"; - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - Object object = params.get(OBJECT); - String javadoc = ""; - - if (object != null) { - if (object instanceof SimpleScalar) - javadoc = ((SimpleScalar) object).getAsString(); - else if (object instanceof FtlTemplate) { - javadoc = ((FtlTemplate) object).getJavadoc(); - } else - throw new IllegalArgumentException( - "Object must be a String or instance of " - + FtlTemplate.class + "but was " - + object.getClass()); - } - - Writer out = env.getOut(); - StringBuilder build = new StringBuilder(); - writeJavadoc(build, javadoc, ""); - out.write(build.toString().toCharArray()); - } - - static void writeJavadoc(StringBuilder build, String javadoc, - String linePrefix) { - build.append(linePrefix + "/**"); - build.append(System.lineSeparator()); - build.append(linePrefix + "* "); - build.append(javadoc == null ? "" : javadoc); - build.append(System.lineSeparator()); - build.append(linePrefix + "*/"); - build.append(System.lineSeparator()); - } - -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/MethodsDirective.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/MethodsDirective.java deleted file mode 100644 index 975d8fd620..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/MethodsDirective.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives; - -import java.io.IOException; -import java.io.Writer; -import java.util.List; -import java.util.Map; - -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate; -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.ftl.model.MethodDeclaration; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDefinition; - -import com.google.common.collect.Lists; - -import freemarker.core.Environment; -import freemarker.template.SimpleSequence; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; - -/** - * Add annotations to freemarker template. - */ -public class MethodsDirective implements TemplateDirectiveModel { - - private static final String OBJECT = "object"; - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - Object object = params.get(OBJECT); - List methods = Lists.newArrayList(); - - if (object != null) { - if (object instanceof SimpleSequence) - methods = ((SimpleSequence) object).toList(); - else if (object instanceof FtlTemplate) { - methods = ((FtlTemplate) object).getMethods(); - } else - throw new IllegalArgumentException( - "Object must be a SimpleSequence or instance of " - + FtlTemplate.class + "but was " - + object.getClass()); - } - - Writer out = env.getOut(); - StringBuilder build = new StringBuilder(); - for (Method method : methods) { - if (method.getJavadoc() != null) - JavadocDirective.writeJavadoc(build, method.getJavadoc(), " "); - - if (!method.getAnnotations().isEmpty()) { - AnnotationsDirective.writeAnnotations(method.getAnnotations(), - build, " "); - } - - build.append(" " + "public "); - for (String mod : method.getModifiers()) { - build.append(mod + " "); - } - build.append(method.getReturnType() + " "); - - build.append(method.getName() + "("); - for (Field param : method.getParameters()) { - for (String mod : param.getModifiers()) { - build.append(mod + " "); - } - build.append(param.getType() + " "); - build.append(param.getName() + ", "); - } - if (method.getParameters().isEmpty()) - build.append(")"); - else { - build.deleteCharAt(build.length() - 1); - build.deleteCharAt(build.length() - 1); - build.append(')'); - } - - if (method instanceof MethodDeclaration) { - build.append(";"); - build.append(System.lineSeparator()); - } else if (method instanceof MethodDefinition) { - if (!((MethodDefinition) method).getThrowsExceptions() - .isEmpty()) - build.append(" throws "); - for (String ex : ((MethodDefinition) method) - .getThrowsExceptions()) { - build.append(ex + " "); - } - build.append(" {"); - build.append(System.lineSeparator()); - build.append(" "); - build.append(((MethodDefinition) method).getBody()); - build.append(System.lineSeparator()); - build.append(" "); - build.append("}"); - build.append(System.lineSeparator()); - } - build.append(System.lineSeparator()); - - } - - if (!methods.isEmpty()) - out.write(build.toString().toCharArray()); - } -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/ModuleFieldsDirective.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/ModuleFieldsDirective.java deleted file mode 100644 index 144419e8ae..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/ModuleFieldsDirective.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives; - -import java.io.IOException; -import java.io.Writer; -import java.util.List; -import java.util.Map; - -import org.opendaylight.controller.config.api.JmxAttribute; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractModuleTemplate; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField; - -import com.google.common.collect.Lists; - -import freemarker.core.Environment; -import freemarker.template.SimpleSequence; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; - -/** - * Add annotations to freemarker template. - */ -public class ModuleFieldsDirective implements TemplateDirectiveModel { - - private static final String OBJECT = "moduleFields"; - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - Object object = params.get(OBJECT); - List fields = Lists.newArrayList(); - - if (object != null) { - if (object instanceof SimpleSequence) - fields = ((SimpleSequence) object).toList(); - else if (object instanceof AbstractModuleTemplate) { - fields = ((AbstractModuleTemplate) object).getModuleFields(); - } else - throw new IllegalArgumentException( - "Object must be a SimpleSequence or instance of " - + AbstractModuleTemplate.class + "but was " - + object.getClass()); - } - - Writer out = env.getOut(); - StringBuilder build = new StringBuilder(); - for (ModuleField field : fields) { - build.append(" "); - build.append("protected final " - + JmxAttribute.class.getCanonicalName() + " " - + field.getName() + "JmxAttribute = new " - + JmxAttribute.class.getCanonicalName() + "(\"" - + field.getAttributeName() + "\");"); - build.append(System.lineSeparator()); - - build.append(" private "); - for (String mod : field.getModifiers()) { - build.append(mod + " "); - } - build.append(field.getType() + " "); - build.append(field.getName()); - if (field.getNullableDefault() != null) - build.append(" = " + field.getNullableDefault()); - build.append(";"); - - if (field.isDependent()) { - String comment = field.getDependency().isMandatory() ? "mandatory" - : "optional"; - build.append(" // " + comment); - } - build.append(System.lineSeparator()); - - build.append(System.lineSeparator()); - - } - - if (!fields.isEmpty()) - out.write(build.toString().toCharArray()); - } -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/TypeDeclarationDirective.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/TypeDeclarationDirective.java deleted file mode 100644 index 42556c243e..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/TypeDeclarationDirective.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives; - -import java.io.IOException; -import java.io.Writer; -import java.util.Collection; -import java.util.Map; - -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.TypeDeclaration; - -import com.google.common.base.Preconditions; - -import freemarker.core.Environment; -import freemarker.ext.beans.StringModel; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; - -/** - * Add type declaration to freemarker template. - */ -public class TypeDeclarationDirective implements TemplateDirectiveModel { - - private static final String OBJECT = "object"; - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - Object object = params.get(OBJECT); - Preconditions.checkNotNull(object, "Null type declaration"); - - object = ((StringModel) object).getWrappedObject(); - Preconditions.checkArgument( - object instanceof TypeDeclaration, - "Type declaration should be instance of " - + TypeDeclaration.class + " but was " - + object.getClass()); - - TypeDeclaration type = (TypeDeclaration) object; - - Writer out = env.getOut(); - StringBuilder build = new StringBuilder("public "); - if (type.isAbstract()) - build.append("abstract "); - if (type.isFinal()) - build.append("final "); - build.append(type.getType() + " "); - build.append(type.getName() + " "); - - generateExtendOrImplement(build, "extends", type.getExtended()); - - generateExtendOrImplement(build, "implements", type.getImplemented()); - - build.append(System.lineSeparator()); - out.write(build.toString().toCharArray()); - } - - private void generateExtendOrImplement(StringBuilder build, String prefix, - Collection elements) { - if (elements.isEmpty()) - return; - - build.append(prefix + " "); - - for (String extended : elements) { - build.append(extended); - build.append(", "); - } - build.deleteCharAt(build.length() - 1); - build.deleteCharAt(build.length() - 1); - } - -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/UnimplementedExceptionDirective.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/UnimplementedExceptionDirective.java deleted file mode 100644 index 5175ade438..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/directives/UnimplementedExceptionDirective.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives; - -import java.io.IOException; -import java.io.Writer; -import java.util.Map; - -import freemarker.core.Environment; -import freemarker.template.TemplateDirectiveBody; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateException; -import freemarker.template.TemplateModel; - -/** - * Add annotations to freemarker template. - */ -public class UnimplementedExceptionDirective implements TemplateDirectiveModel { - - @Override - public void execute(Environment env, Map params, TemplateModel[] loopVars, - TemplateDirectiveBody body) throws TemplateException, IOException { - - Writer out = env.getOut(); - StringBuilder build = new StringBuilder(); - build.append(" "); - build.append("throw new " - + UnsupportedOperationException.class.getCanonicalName() - + "(\"Unimplemented stub method\");"); - build.append(System.lineSeparator()); - - out.write(build.toString().toCharArray()); - } -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Annotation.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Annotation.java index 7cf241725d..a8ddabc4cf 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Annotation.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Annotation.java @@ -7,18 +7,21 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import org.opendaylight.controller.config.api.annotations.Description; import org.opendaylight.controller.config.api.annotations.RequireInterface; import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation; -import org.opendaylight.yangtools.yang.binding.annotations.ModuleQName; import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry; +import org.opendaylight.yangtools.yang.binding.annotations.ModuleQName; +import org.opendaylight.yangtools.yang.common.QName; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; public class Annotation { final String name; @@ -37,6 +40,14 @@ public class Annotation { return params; } + public static Annotation createFromMap(Class annotationClass, Map parameters) { + List parameterList = new ArrayList<>(); + for(Entry entry: parameters.entrySet()) { + parameterList.add(new Parameter(entry.getKey(), entry.getValue())); + } + return new Annotation(annotationClass.getCanonicalName(), parameterList); + } + public static Annotation createDescriptionAnnotation(String description) { Preconditions.checkNotNull(description, "Cannot create annotation from null description"); @@ -44,6 +55,14 @@ public class Annotation { Lists.newArrayList(new Parameter("value", q(description)))); } + public static Annotation createModuleQNameANnotation(QName qName) { + Map parameters = new HashMap<>(); + parameters.put("namespace", q(qName.getNamespace().toString())); + parameters.put("revision", q(qName.getFormattedRevision())); + parameters.put("name", q(qName.getLocalName())); + return Annotation.createFromMap(ModuleQName.class, parameters); + } + public static Collection createSieAnnotations(ServiceInterfaceEntry sie){ String exportedClassName = sie.getExportedOsgiClassName(); @@ -85,7 +104,7 @@ public class Annotation { private static final String quote = "\""; - private static String q(String nullableDescription) { + public static String q(String nullableDescription) { return nullableDescription == null ? null : quote + nullableDescription + quote; } @@ -107,4 +126,8 @@ public class Annotation { } } + @Override + public String toString() { + return AnnotationSerializer.toString(this); + } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/AnnotationSerializer.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/AnnotationSerializer.java new file mode 100644 index 0000000000..6b4ce38621 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/AnnotationSerializer.java @@ -0,0 +1,38 @@ +/* + * 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.ftl.model; + +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation.Parameter; + +class AnnotationSerializer { + + static String toString(Annotation annotation) { + StringBuilder builder = new StringBuilder(); + builder.append("@"); + builder.append(annotation.getName()); + if (!annotation.getParams().isEmpty()) { + builder.append("("); + for (Parameter param : annotation.getParams()) { + builder.append(param.getKey()); + builder.append(" = "); + builder.append(fixString(param.getValue())); + builder.append(", "); + } + builder.setCharAt(builder.length() - 2, ')'); + } + builder.append("\n"); + return builder.toString(); + } + + private static String fixString(String value) { + // TODO replace with compress single line if possible + return value.replaceAll("\\r\\n|\\r|\\n", " ").replaceAll(" +", " "); + } + +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Constructor.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Constructor.java index 1aeb86d25d..91c1cc3966 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Constructor.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Constructor.java @@ -37,4 +37,8 @@ public class Constructor { return isPublic; } + @Override + public String toString() { + return ConstructorSerializer.toString(this); + } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ConstructorSerializer.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ConstructorSerializer.java new file mode 100644 index 0000000000..c257aa6dda --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ConstructorSerializer.java @@ -0,0 +1,32 @@ +/* + * 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.ftl.model; + +public class ConstructorSerializer { + + public static String toString(Constructor constr) { + StringBuilder build = new StringBuilder(); + build.append(" "); + if (constr.isPublic()) { + build.append("public "); + } + build.append(constr.getTypeName() + " "); + build.append("() {"); + build.append("\n"); + build.append(" "); + build.append(" "); + build.append(constr.getBody()); + build.append("\n"); + build.append(" "); + build.append("}"); + build.append("\n"); + build.append("\n"); + return build.toString(); + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Field.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Field.java index ad5cbb287c..3639b6d727 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Field.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Field.java @@ -11,6 +11,8 @@ import com.google.common.collect.Lists; import java.util.List; +import static com.google.common.base.Preconditions.checkNotNull; + public class Field { private final String type; private final String name; @@ -36,11 +38,11 @@ public class Field { } public Field(List modifiers, String type, String name, - String definition, boolean needsDepResolver) { - this.modifiers = modifiers; - this.type = type; - this.name = name; - this.definition = definition; + String nullableDefinition, boolean needsDepResolver) { + this.modifiers = checkNotNull(modifiers); + this.type = checkNotNull(type); + this.name = checkNotNull(name); + this.definition = nullableDefinition; this.needsDepResolver = needsDepResolver; } @@ -56,6 +58,10 @@ public class Field { return type; } + public String getGenericInnerType() { + return type.substring(type.indexOf("<") + 1, type.indexOf(">")); + } + public List getModifiers() { return modifiers; } @@ -71,4 +77,9 @@ public class Field { public boolean isArray() { return type.endsWith("[]"); } + + @Override + public String toString() { + return FieldSerializer.toString(this); + } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/FieldSerializer.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/FieldSerializer.java new file mode 100644 index 0000000000..90a2b5694c --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/FieldSerializer.java @@ -0,0 +1,28 @@ +/* + * 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.ftl.model; + +public class FieldSerializer { + + public static String toString(Field field) { + StringBuilder build = new StringBuilder(); + build.append("private "); + for (String mod : field.getModifiers()) { + build.append(mod + " "); + } + build.append(field.getType() + " "); + build.append(field.getName()); + if (field.getDefinition() != null) { + build.append(" = " + field.getDefinition()); + } + build.append(";"); + build.append("\n"); + return build.toString(); + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Header.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Header.java index 047e87a3dc..b9a628495d 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Header.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/Header.java @@ -26,8 +26,7 @@ public class Header { @Override public String toString() { - return "yang module name: " + yangModuleName + " " - + " yang module local name: " + yangModuleLocalName; + return HeaderSerializer.toString(this); } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/HeaderSerializer.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/HeaderSerializer.java new file mode 100644 index 0000000000..eb07c80e15 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/HeaderSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.ftl.model; + +import org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator; + +import java.util.Date; + +public class HeaderSerializer { + private static final String GENERATOR_CLASS = JMXGenerator.class.getCanonicalName(); + + public static String toString(Header header) { + StringBuilder build = new StringBuilder(); + + + build.append("Generated file"); + build.append("\n"); + build.append("\n"); + build.append("Generated from: "); + //build.append(header.toString()); + + build.append("yang module name: "); + build.append(header.getYangModuleName()); + build.append(" yang module local name: "); + build.append(header.getYangModuleLocalName()); + + build.append("\n"); + build.append("Generated by: " + GENERATOR_CLASS); + build.append("\n"); + build.append("Generated at: " + new Date()); + build.append("\n"); + build.append("\n"); + build.append("Do not modify this file unless it is present under src/main directory "); + + return build.toString(); + } + +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodDeclaration.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodDeclaration.java index bd4e22e084..be6b23e879 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodDeclaration.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodDeclaration.java @@ -63,4 +63,9 @@ public class MethodDeclaration implements Method { public List getModifiers() { return Collections.emptyList(); } + + @Override + public String toString() { + return MethodSerializer.toString(this); + } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodDefinition.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodDefinition.java index bf453ac135..9af011fe71 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodDefinition.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodDefinition.java @@ -93,4 +93,9 @@ public class MethodDefinition implements Method { public List getModifiers() { return modifiers; } + + @Override + public String toString() { + return MethodSerializer.toString(this); + } } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodSerializer.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodSerializer.java new file mode 100644 index 0000000000..7d2b9fcdaf --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/MethodSerializer.java @@ -0,0 +1,71 @@ +/* + * 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.ftl.model; + +import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.StringUtil; + +class MethodSerializer { + + static String toString(Method method) { + StringBuilder build = new StringBuilder(); + if (method.getJavadoc() != null) { + build.append(StringUtil.writeComment(method.getJavadoc(), true)); + } + + for(Annotation a: method.getAnnotations()) { + build.append(a); + } + + build.append(" " + "public "); + for (String mod : method.getModifiers()) { + build.append(mod + " "); + } + build.append(method.getReturnType() + " "); + + build.append(method.getName() + "("); + for (Field param : method.getParameters()) { + for (String mod : param.getModifiers()) { + build.append(mod + " "); + } + build.append(param.getType() + " "); + build.append(param.getName() + ", "); + } + if (method.getParameters().isEmpty()) { + build.append(")"); + } else { + build.deleteCharAt(build.length() - 1); + build.deleteCharAt(build.length() - 1); + build.append(')'); + } + + if (method instanceof MethodDeclaration) { + build.append(";"); + build.append("\n"); + } else if (method instanceof MethodDefinition) { + if (!((MethodDefinition) method).getThrowsExceptions() + .isEmpty()) { + build.append(" throws "); + } + for (String ex : ((MethodDefinition) method) + .getThrowsExceptions()) { + build.append(ex + " "); + } + build.append(" {"); + build.append("\n"); + build.append(" "); + build.append(((MethodDefinition) method).getBody()); + build.append("\n"); + build.append(" "); + build.append("}"); + build.append("\n"); + } + build.append("\n"); + return build.toString(); + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java index 74e5bb0490..37d660353f 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java @@ -44,6 +44,11 @@ public class ModuleField extends Field { return false; } + @Override + public String toString() { + return ModuleFieldSerializer.toString(this); + } + public Dependency getDependency() { return dependency; } @@ -64,4 +69,9 @@ public class ModuleField extends Field { return attributeName; } + + public boolean isList() { + return getType().startsWith("java.util.List"); + } + } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleFieldSerializer.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleFieldSerializer.java new file mode 100644 index 0000000000..c0e3bc1ad8 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleFieldSerializer.java @@ -0,0 +1,48 @@ +/* + * 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.ftl.model; + +import org.opendaylight.controller.config.api.JmxAttribute; + +public class ModuleFieldSerializer { + + + public static String toString(ModuleField moduleField) { + StringBuilder builder = new StringBuilder(); + builder.append(" "); + builder.append("protected final " + + JmxAttribute.class.getCanonicalName() + " " + + moduleField.getName() + "JmxAttribute = new " + + JmxAttribute.class.getCanonicalName() + "(\"" + + moduleField.getAttributeName() + "\");"); + builder.append("\n"); + + builder.append(" private "); + for (String mod : moduleField.getModifiers()) { + builder.append(mod + " "); + } + builder.append(moduleField.getType() + " "); + builder.append(moduleField.getName()); + if (moduleField.getNullableDefault() != null) { + builder.append(" = " + moduleField.getNullableDefault()); + } + builder.append(";"); + + if (moduleField.isDependent()) { + String comment = moduleField.getDependency().isMandatory() ? "mandatory" + : "optional"; + builder.append(" // " + comment); + } + builder.append("\n"); + + builder.append("\n"); + + return builder.toString(); + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/TypeDeclaration.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/TypeDeclaration.java index ee0aa2ff5c..a5bb987fd3 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/TypeDeclaration.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/TypeDeclaration.java @@ -7,6 +7,8 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.TypeName; + import java.util.List; public class TypeDeclaration { @@ -54,6 +56,24 @@ public class TypeDeclaration { return implemented; } + public TypeName toTypeName() { + if ("interface".equals(type)) { + return TypeName.interfaceType; + } else if ("class".equals(type)) { + if (isAbstract) { + return TypeName.absClassType; + } else if (isFinal) { + return TypeName.finalClassType; + } else { + return TypeName.classType; + } + } else if ("enum".equals(type)) { + return TypeName.enumType; + } else { + throw new IllegalStateException("Type not supported: " + type); + } + } + @Override public String toString() { return "TypeDeclaration{" + "type='" + type + '\'' + ", name='" + name diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.groovy b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.groovy new file mode 100644 index 0000000000..baff88c8f3 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsFactoryGeneratedObjectFactory.groovy @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory +import com.google.common.base.Optional +import org.opendaylight.controller.config.api.DependencyResolver +import org.opendaylight.controller.config.api.DynamicMBeanWithInstance +import org.opendaylight.controller.config.api.ModuleIdentifier +import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface +import org.opendaylight.controller.config.api.annotations.Description +import org.opendaylight.controller.config.spi.Module +import org.opendaylight.controller.config.spi.ModuleFactory +import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractFactoryTemplate +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.* +import org.opendaylight.yangtools.yang.common.QName +import org.osgi.framework.BundleContext + +public class AbsFactoryGeneratedObjectFactory { + + public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional copyright) { + FullyQualifiedName absFactoryFQN = new FullyQualifiedName(mbe.packageName, mbe.abstractFactoryName) + FullyQualifiedName moduleFQN = new FullyQualifiedName(mbe.packageName, mbe.stubModuleName) + Optional classJavaDoc = Optional.fromNullable(mbe.getNullableDescription()) + + AbstractFactoryTemplate abstractFactoryTemplate = TemplateFactory.abstractFactoryTemplateFromMbe(mbe) + Optional header = abstractFactoryTemplate.headerString; + List providedServices = mbe.providedServices.keySet().collect { + FullyQualifiedName.fromString(it) + } + + + return toGeneratedObject(absFactoryFQN, copyright, + header, classJavaDoc, mbe.yangModuleQName, + mbe.globallyUniqueName, + providedServices, + moduleFQN, + abstractFactoryTemplate.fields) + } + + public GeneratedObject toGeneratedObject(FullyQualifiedName absFactoryFQN, Optional copyright, + Optional header, Optional classJavaDoc, QName yangModuleQName, + String globallyUniqueName, + List providedServices, + FullyQualifiedName moduleFQN, + List moduleFields) { + JavaFileInputBuilder b = new JavaFileInputBuilder() + Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName) + b.addClassAnnotation(moduleQNameAnnotation) + + b.setFqn(absFactoryFQN) + b.setTypeName(TypeName.absClassType) + + b.setCopyright(copyright); + b.setHeader(header); + b.setClassJavaDoc(classJavaDoc); + b.addImplementsFQN(new FullyQualifiedName(ModuleFactory)) + if (classJavaDoc.isPresent()) { + b.addClassAnnotation("@${Description.canonicalName}(value=\"${classJavaDoc.get()}\")") + } + + b.addToBody("public static final java.lang.String NAME = \"${globallyUniqueName}\";") + b.addToBody("private static final java.util.Set> serviceIfcs;") + + b.addToBody("@Override\n public final String getImplementationName() { \n return NAME; \n}") + + b.addToBody(getServiceIfcsInitialization(providedServices)) + + // createModule + b.addToBody(""" + @Override + public ${Module.canonicalName} createModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${BundleContext.canonicalName} bundleContext) { + return instantiateModule(instanceName, dependencyResolver, bundleContext); + } + """) + + b.addToBody(getCreateModule(moduleFQN, moduleFields)) + + b.addToBody(""" + public ${moduleFQN} instantiateModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${moduleFQN} oldModule, ${AutoCloseable.canonicalName} oldInstance, ${BundleContext.canonicalName} bundleContext) { + return new ${moduleFQN}(new ${ModuleIdentifier.canonicalName}(NAME, instanceName), dependencyResolver, oldModule, oldInstance); + } + """) + + b.addToBody(""" + public ${moduleFQN} instantiateModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${BundleContext.canonicalName} bundleContext) { + return new ${moduleFQN}(new ${ModuleIdentifier.canonicalName}(NAME, instanceName), dependencyResolver); + } + """) + + b.addToBody(""" + public ${moduleFQN} handleChangedClass(${DynamicMBeanWithInstance.canonicalName} old) throws Exception { + throw new UnsupportedOperationException("Class reloading is not supported"); + } + """) + + b.addToBody(""" + @Override + public java.util.Set<${moduleFQN}> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory, ${BundleContext.canonicalName} bundleContext) { + return new java.util.HashSet<${moduleFQN}>(); + } + """) + + return new GeneratedObjectBuilder(b.build()).toGeneratedObject() + } + + private static String getCreateModule(FullyQualifiedName moduleFQN, List moduleFields) { + String result = """ + @Override + public ${Module.canonicalName} createModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${DynamicMBeanWithInstance.canonicalName} old, ${BundleContext.canonicalName} bundleContext) throws Exception { + ${moduleFQN} oldModule = null; + try { + oldModule = (${moduleFQN}) old.getModule(); + } catch(Exception e) { + return handleChangedClass(old); + } + ${moduleFQN} module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext); + """ + result += moduleFields.collect{"module.set${it.name}(oldModule.get${it.name}());"}.join("\n") + result += """ + return module; + } + """ + return result + } + + private static String getServiceIfcsInitialization(List providedServices) { + String generic = "Class" + + String result = """static { + java.util.Set<${generic}> serviceIfcs2 = new java.util.HashSet<${generic}>(); + """ + result += providedServices.collect{"serviceIfcs2.add(${it}.class);"}.join("\n") + result += """serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2); + } + """ + + // add isModuleImplementingServiceInterface and getImplementedServiceIntefaces methods + + result += """ + @Override + public final boolean isModuleImplementingServiceInterface(Class serviceInterface) { + for (Class ifc: serviceIfcs) { + if (serviceInterface.isAssignableFrom(ifc)){ + return true; + } + } + return false; + } + + @Override + public java.util.Set> getImplementedServiceIntefaces() { + return serviceIfcs; + } + """ + + return result + } + +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.groovy b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.groovy new file mode 100644 index 0000000000..930acff7bc --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/AbsModuleGeneratedObjectFactory.groovy @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory +import com.google.common.base.Optional +import org.opendaylight.controller.config.api.DependencyResolver +import org.opendaylight.controller.config.api.ModuleIdentifier +import org.opendaylight.controller.config.api.annotations.Description +import org.opendaylight.controller.config.api.runtime.RootRuntimeBeanRegistrator +import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractModuleTemplate +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.IdentityRefModuleField +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Method +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.* +import org.opendaylight.yangtools.yang.common.QName +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +public class AbsModuleGeneratedObjectFactory { + + public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional copyright) { + FullyQualifiedName abstractFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractModuleName()) + Optional classJavaDoc = Optional.fromNullable(mbe.getNullableDescription()) + AbstractModuleTemplate abstractModuleTemplate = TemplateFactory.abstractModuleTemplateFromMbe(mbe) + Optional header = abstractModuleTemplate.headerString; + List implementedInterfaces = abstractModuleTemplate.getTypeDeclaration().getImplemented().collect { + FullyQualifiedName.fromString(it) + } + Optional maybeRegistratorType + if (abstractModuleTemplate.isRuntime()) { + maybeRegistratorType = Optional.of(FullyQualifiedName.fromString(abstractModuleTemplate.getRegistratorType())) + } else { + maybeRegistratorType = Optional.absent() + } + + return toGeneratedObject(abstractFQN, copyright, header, classJavaDoc, implementedInterfaces, + abstractModuleTemplate.getModuleFields(), maybeRegistratorType, abstractModuleTemplate.getMethods(), + mbe.yangModuleQName + ) + } + + public GeneratedObject toGeneratedObject(FullyQualifiedName abstractFQN, + Optional copyright, + Optional header, + Optional classJavaDoc, + List implementedInterfaces, + List moduleFields, + Optional maybeRegistratorType, + List methods, + QName yangModuleQName) { + JavaFileInputBuilder b = new JavaFileInputBuilder() + + Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName) + b.addClassAnnotation(moduleQNameAnnotation) + + b.setFqn(abstractFQN) + b.setTypeName(TypeName.absClassType) + + b.setCopyright(copyright); + b.setHeader(header); + b.setClassJavaDoc(classJavaDoc); + implementedInterfaces.each { b.addImplementsFQN(it) } + if (classJavaDoc.isPresent()) { + b.addClassAnnotation("@${Description.canonicalName}(value=\"${classJavaDoc.get()}\")") + } + + // add logger: + b.addToBody(getLogger(abstractFQN)); + + b.addToBody("//attributes start"); + + b.addToBody(moduleFields.collect { it.toString() }.join("\n")) + + b.addToBody("//attributes end"); + + + b.addToBody(getCommonFields(abstractFQN)); + + + b.addToBody(getNewConstructor(abstractFQN)) + b.addToBody(getCopyFromOldConstructor(abstractFQN)) + + b.addToBody(getRuntimeRegistratorCode(maybeRegistratorType)) + b.addToBody(getValidationMethods(moduleFields)) + + b.addToBody(getCachesOfResolvedDependencies(moduleFields)) + b.addToBody(getCachesOfResolvedIdentityRefs(moduleFields)) + b.addToBody(getGetInstance(moduleFields)) + b.addToBody(getReuseLogic(moduleFields, abstractFQN)) + b.addToBody(getEqualsAndHashCode(abstractFQN)) + + b.addToBody(getMethods(methods)) + + return new GeneratedObjectBuilder(b.build()).toGeneratedObject() + } + + private static String getMethods(List methods) { + String result = """ + // getters and setters + """ + result += methods.collect{it.toString()}.join("\n") + return result + } + + private static String getEqualsAndHashCode(FullyQualifiedName abstractFQN) { + return """ + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ${abstractFQN.typeName} that = (${abstractFQN.typeName}) o; + return identifier.equals(that.identifier); + } + + @Override + public int hashCode() { + return identifier.hashCode(); + } + """ + } + + private static String getReuseLogic(List moduleFields, FullyQualifiedName abstractFQN) { + String result = """ + public boolean canReuseInstance(${abstractFQN.typeName} oldModule){ + // allow reusing of old instance if no parameters was changed + return isSame(oldModule); + } + + public ${AutoCloseable.canonicalName} reuseInstance(${AutoCloseable.canonicalName} oldInstance){ + // implement if instance reuse should be supported. Override canReuseInstance to change the criteria. + return oldInstance; + } + """ + // isSame method that detects changed fields + result += """ + public boolean isSame(${abstractFQN.typeName} other) { + if (other == null) { + throw new IllegalArgumentException("Parameter 'other' is null"); + } + """ + // loop through fields, do deep equals on each field + result += moduleFields.collect { field -> + if (field.isListOfDependencies()) { + return """ + if (${field.name}Dependency.equals(other.${field.name}Dependency) == false) { + return false; + } + for (int idx = 0; idx < ${field.name}Dependency.size(); idx++) { + if (${field.name}Dependency.get(idx) != other.${field.name}Dependency.get(idx)) { + return false; + } + } + """ + } else if (field.isDependent()) { + return """ + if (${field.name}Dependency != other.${field.name}Dependency) { // reference to dependency must be same + return false; + } + """ + } else { + return """ + if (java.util.Objects.deepEquals(${field.name}, other.${field.name}) == false) { + return false; + } + """ + } + }.join("\n") + + + result += """ + return true; + } + """ + + return result + } + + private static String getGetInstance(List moduleFields) { + String result = """ + @Override + public final ${AutoCloseable.canonicalName} getInstance() { + if(instance==null) { + """ + // create instance start + + // loop through dependent fields, use dependency resolver to instantiate dependencies. Do it in loop in case field represents list of dependencies. + Map resolveDependenciesMap = moduleFields.findAll { + it.isDependent() + }.collectEntries { ModuleField field -> + [field, field.isList() ? + """ + ${field.name}Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>(); + for(javax.management.ObjectName dep : ${field.name}) { + ${field.name}Dependency.add(dependencyResolver.resolveInstance(${ + field.dependency.sie.exportedOsgiClassName + }.class, dep, ${field.name}JmxAttribute)); + } + """ + : + """ + ${field.name}Dependency = dependencyResolver.resolveInstance(${ + field.dependency.sie.exportedOsgiClassName + }.class, ${field.name}, ${field.name}JmxAttribute); + """ + ] + } + // wrap each field resolvation statement with if !=null when dependency is not mandatory + def wrapWithNullCheckClosure = {Map map, predicate -> map.collect { ModuleField key, String value -> + predicate(key) ? """ + if(${key.name}!=null) { + ${value} + } + """ : value + }.join("\n") + } + + result += wrapWithNullCheckClosure(resolveDependenciesMap, {ModuleField key -> + key.getDependency().isMandatory() == false} ) + + // add code to inject dependency resolver to fields that support it + Map injectDepsMap = moduleFields.findAll { it.needsDepResolver }.collectEntries { field -> + if (field.isList()) { + return [field,""" + for(${field.genericInnerType} candidate : ${field.name}) { + candidate.injectDependencyResolver(dependencyResolver); + } + """] + } else { + return [field, "${field.name}.injectDependencyResolver(dependencyResolver);"] + } + } + + result += wrapWithNullCheckClosure(injectDepsMap, {true}) + + // identity refs need to be injected with dependencyResolver and base class + Map resolveIdentityMap = moduleFields.findAll { it.isIdentityRef() }.collectEntries { IdentityRefModuleField field -> + [field, + "set${field.attributeName}(${field.name}.resolveIdentity(dependencyResolver, ${field.identityBaseClass}.class));"] + } + + result += wrapWithNullCheckClosure(resolveIdentityMap, {true}) + + // create instance end: reuse and recreate logic + result += """ + if(oldInstance!=null && canReuseInstance(oldModule)) { + instance = reuseInstance(oldInstance); + } else { + if(oldInstance!=null) { + try { + oldInstance.close(); + } catch(Exception e) { + logger.error("An error occurred while closing old instance " + oldInstance, e); + } + } + instance = createInstance(); + if (instance == null) { + throw new IllegalStateException("Error in createInstance - null is not allowed as return value"); + } + } + } + return instance; + } + public abstract ${AutoCloseable.canonicalName} createInstance(); + """ + return result + } + + private static String getCommonFields(FullyQualifiedName abstractFQN) { + return """ + private final ${abstractFQN.typeName} oldModule; + private final ${AutoCloseable.canonicalName} oldInstance; + private ${AutoCloseable.canonicalName} instance; + private final ${DependencyResolver.canonicalName} dependencyResolver; + private final ${ModuleIdentifier.canonicalName} identifier; + @Override + public ${ModuleIdentifier.canonicalName} getIdentifier() { + return identifier; + } + """ + } + + private static String getCachesOfResolvedIdentityRefs(List moduleFields) { + return moduleFields.findAll { it.isIdentityRef() }.collect { IdentityRefModuleField field -> + "private ${field.identityClassType} ${field.identityClassName};" + }.join("\n") + } + + private static String getCachesOfResolvedDependencies(List moduleFields) { + return moduleFields.findAll { it.dependent }.collect { field -> + if (field.isList()) { + return """ + private java.util.List<${field.dependency.sie.exportedOsgiClassName}> ${ + field.name + }Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>(); + protected final java.util.List<${field.dependency.sie.exportedOsgiClassName}> get${ + field.attributeName + }Dependency(){ + return ${field.name}Dependency; + } + """ + } else { + return """ + private ${field.dependency.sie.exportedOsgiClassName} ${field.name}Dependency; + protected final ${field.dependency.sie.exportedOsgiClassName} get${field.attributeName}Dependency(){ + return ${field.name}Dependency; + } + """ + } + }.join("\n") + } + + private static String getRuntimeRegistratorCode(Optional maybeRegistratorType) { + if (maybeRegistratorType.isPresent()) { + String registratorType = maybeRegistratorType.get() + + return """ + private ${registratorType} rootRuntimeBeanRegistratorWrapper; + + public ${registratorType} getRootRuntimeBeanRegistratorWrapper(){ + return rootRuntimeBeanRegistratorWrapper; + } + + @Override + public void setRuntimeBeanRegistrator(${RootRuntimeBeanRegistrator.canonicalName} rootRuntimeRegistrator){ + this.rootRuntimeBeanRegistratorWrapper = new ${registratorType}(rootRuntimeRegistrator); + } + """ + } else { + return "" + } + } + + private static String getValidationMethods(List moduleFields) { + String result = """ + @Override + public void validate() { + """ + // validate each mandatory dependency + List lines = moduleFields.findAll{(it.dependent && it.dependency.mandatory)}.collect { field -> + if (field.isList()) { + return "" + + "for(javax.management.ObjectName dep : ${field.name}) {\n" + + " dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, dep, ${field.name}JmxAttribute);\n" + + "}\n" + } else { + return "dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, ${field.name}, ${field.name}JmxAttribute);" + } + } + result += lines.findAll { it.isEmpty() == false }.join("\n") + result += """ + customValidation(); + } + + protected void customValidation(){ + } + """ + return result + } + + private static String getLogger(FullyQualifiedName fqn) { + return "private static final ${Logger.canonicalName} logger = ${LoggerFactory.canonicalName}.getLogger(${fqn.toString()}.class);" + } + + // assumes that each parameter name corresponds to an field in this class, constructs lines setting this.field = field; + private static String getConstructorStart(FullyQualifiedName fqn, + LinkedHashMap parameters, String after) { + return "public ${fqn.typeName}(" + + parameters.collect { it.key + " " + it.value }.join(",") + + ") {\n" + + parameters.values().collect { "this.${it}=${it};\n" }.join() + + after + + "}\n" + } + + private static String getNewConstructor(FullyQualifiedName abstractFQN) { + LinkedHashMap parameters = [ + (ModuleIdentifier.canonicalName): "identifier", + (DependencyResolver.canonicalName): "dependencyResolver" + ] + String setToNulls = ["oldInstance", "oldModule"].collect { "this.${it}=null;\n" }.join() + return getConstructorStart(abstractFQN, parameters, setToNulls) + } + + private static String getCopyFromOldConstructor(FullyQualifiedName abstractFQN) { + LinkedHashMap parameters = [ + (ModuleIdentifier.canonicalName): "identifier", + (DependencyResolver.canonicalName): "dependencyResolver", + (abstractFQN.typeName): "oldModule", + (AutoCloseable.canonicalName): "oldInstance" + ] + return getConstructorStart(abstractFQN, parameters, "") + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/ConcreteModuleGeneratedObjectFactory.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/ConcreteModuleGeneratedObjectFactory.java new file mode 100644 index 0000000000..fbc507d0b4 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/ConcreteModuleGeneratedObjectFactory.java @@ -0,0 +1,101 @@ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory; + +import com.google.common.base.Joiner; +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.yangjmxgenerator.ModuleMXBeanEntry; +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 java.util.LinkedHashMap; + +public class ConcreteModuleGeneratedObjectFactory { + + public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional copyright, Optional header) { + FullyQualifiedName concreteFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getStubModuleName()); + FullyQualifiedName abstractFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractModuleName()); + Optional classJavaDoc = Optional.fromNullable(mbe.getNullableDescription()); + return toGeneratedObject(concreteFQN, abstractFQN, copyright, header, classJavaDoc); + } + + GeneratedObject toGeneratedObject(FullyQualifiedName concreteFQN, + FullyQualifiedName abstractFQN, + Optional copyright, + Optional header, + Optional classJavaDoc) { + // there are two constructors and two methods + JavaFileInputBuilder builder = new JavaFileInputBuilder(); + builder.setTypeName(TypeName.classType); + builder.setFqn(concreteFQN); + builder.addExtendsFQN(abstractFQN); + + builder.setCopyright(copyright); + builder.setHeader(header); + builder.setClassJavaDoc(classJavaDoc); + + builder.addToBody(getNewCtor(concreteFQN)); + builder.addToBody(getCopyCtor(concreteFQN)); + builder.addToBody(getCustomValidationStub()); + builder.addToBody(getCreateInstanceStub()); + + return new GeneratedObjectBuilder(builder.build()).toGeneratedObject(); + } + + private static String getNewCtor(FullyQualifiedName fqn) { + LinkedHashMap parameters = new LinkedHashMap(){ + { + put(ModuleIdentifier.class.getCanonicalName(), "identifier"); + put(DependencyResolver.class.getCanonicalName(), "dependencyResolver"); + } + }; + StringBuilder stringBuilder = getCtor(fqn, parameters); + return stringBuilder.toString(); + } + + private static StringBuilder getCtor(FullyQualifiedName fqn , LinkedHashMap parameters) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("public ").append(fqn.getTypeName()).append("("); + // parameters + stringBuilder.append(Joiner.on(", ").withKeyValueSeparator(" ").join(parameters)); + stringBuilder.append(") {\n"); + if (parameters.isEmpty() == false) { + stringBuilder.append("super("); + stringBuilder.append(Joiner.on(", ").join(parameters.values())); + stringBuilder.append(");\n"); + } + stringBuilder.append("}"); + return stringBuilder; + } + + private static String getCopyCtor(final FullyQualifiedName fqn) { + LinkedHashMap parameters = new LinkedHashMap(){ + { + put(ModuleIdentifier.class.getCanonicalName(), "identifier"); + put(DependencyResolver.class.getCanonicalName(), "dependencyResolver"); + put(fqn.toString(), "oldModule"); + put(AutoCloseable.class.getCanonicalName(), "oldInstance"); + } + }; + StringBuilder stringBuilder = getCtor(fqn, parameters); + return stringBuilder.toString(); + } + + private static String getCustomValidationStub() { + return "@Override\n" + + "public void customValidation() {\n" + + "// add custom validation form module attributes here.\n" + + "}"; + } + + private static String getCreateInstanceStub() { + return "@Override\n" + + "public " + AutoCloseable.class.getCanonicalName() + " createInstance() {\n" + + "// TODO:implement\n" + + "throw new " + UnsupportedOperationException.class.getCanonicalName() + "();\n"+ + "}"; + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.groovy b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.groovy new file mode 100644 index 0000000000..6504aac7d4 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/gofactory/GenericGeneratedObjectFactory.groovy @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory + +import com.google.common.base.Optional +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder + +public class GenericGeneratedObjectFactory { + + public GeneratedObject toGeneratedObject(FtlTemplate template, Optional copyright) { + JavaFileInputBuilder b = new JavaFileInputBuilder(); + b.setHeader(template.headerString) + b.setFqn(new FullyQualifiedName(template.packageName, template.typeDeclaration.name)) + b.setClassJavaDoc(template.maybeJavadoc) + template.annotations.each { b.addClassAnnotation(it) } + // type declaration + template.typeDeclaration.extended.each { b.addExtendsFQN(FullyQualifiedName.fromString(it)) } + template.typeDeclaration.implemented.each { b.addImplementsFQN(FullyQualifiedName.fromString(it)) } + b.setCopyright(copyright); + b.setTypeName(template.typeDeclaration.toTypeName()) + // fields + template.fields.each { b.addToBody(it.toString()) } + // constructors + template.constructors.each { b.addToBody(it.toString()) } + // methods + template.methods.each { b.addToBody(it.toString()) } + + return new GeneratedObjectBuilder(b.build()).toGeneratedObject(); + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/FullyQualifiedName.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/FullyQualifiedName.java new file mode 100644 index 0000000000..f72551a377 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/FullyQualifiedName.java @@ -0,0 +1,81 @@ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.java; + +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class FullyQualifiedName { + + private final String packageName; + private final String typeName; + + public FullyQualifiedName(String packageName, String typeName) { + this.packageName = checkNotNull(packageName); + this.typeName = checkNotNull(typeName); + } + + public FullyQualifiedName(Class clazz) { + this(clazz.getPackage().getName(), clazz.getSimpleName()); + } + + public static FullyQualifiedName fromString(String fqn) { + Matcher m = Pattern.compile("(.*)\\.([^\\.]+)$").matcher(fqn); + if (m.matches()) { + return new FullyQualifiedName(m.group(1), m.group(2)); + } else { + return new FullyQualifiedName("", fqn); + } + } + + public String getPackageName() { + return packageName; + } + + public String getTypeName() { + return typeName; + } + + public File toFile(File srcDirectory) { + String directory = packageName.replace(".", File.separator); + return new File(srcDirectory, directory + File.separator + typeName + ".java"); + } + + + @Override + public String toString() { + if (packageName.isEmpty()){ + return typeName; + } + return packageName + "." + typeName; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + FullyQualifiedName that = (FullyQualifiedName) o; + + if (!packageName.equals(that.packageName)) { + return false; + } + if (!typeName.equals(that.typeName)) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result = packageName.hashCode(); + result = 31 * result + typeName.hashCode(); + return result; + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/GeneratedObject.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/GeneratedObject.java new file mode 100644 index 0000000000..4ad080c6f5 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/GeneratedObject.java @@ -0,0 +1,75 @@ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.java; + +import com.google.common.base.Optional; +import com.google.common.collect.Maps; +import org.apache.commons.io.FileUtils; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.StringUtil; + +import java.io.File; +import java.io.IOException; +import java.util.Map.Entry; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class GeneratedObject { + + private final FullyQualifiedName fqn; + private final String content; + + public GeneratedObject(FullyQualifiedName fqn, String content) { + this.fqn = checkNotNull(fqn); + this.content = StringUtil.formatJavaSource(checkNotNull(content)); + } + + public FullyQualifiedName getFQN(){ + return fqn; + } + + public String getContent() { + return content; + } + + public Optional> persist(File srcDirectory, boolean overwrite) throws IOException { + File dstFile = fqn.toFile(srcDirectory); + if (overwrite == true || dstFile.exists() == false) { + FileUtils.write(dstFile, content); + return Optional.of(Maps.immutableEntry(fqn, dstFile)); + } else { + return Optional.absent(); + } + } + + public Optional> persist(File srcDirectory) throws IOException { + return persist(srcDirectory, true); + } + + @Override + public String toString() { + return getClass().getSimpleName() + "{" + + "fqn=" + fqn + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + GeneratedObject that = (GeneratedObject) o; + + if (!fqn.equals(that.fqn)) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + return fqn.hashCode(); + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/GeneratedObjectBuilder.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/GeneratedObjectBuilder.java new file mode 100644 index 0000000000..72819db9cf --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/GeneratedObjectBuilder.java @@ -0,0 +1,68 @@ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.java; + +import com.google.common.base.Optional; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.StringUtil; + +import static org.opendaylight.controller.config.yangjmxgenerator.plugin.util.StringUtil.prefixAndJoin; + +public class GeneratedObjectBuilder { + private final JavaFileInput input; + + public GeneratedObjectBuilder(JavaFileInput input) { + this.input = input; + } + + + public GeneratedObject toGeneratedObject() { + FullyQualifiedName fqn = input.getFQN(); + StringBuilder content = new StringBuilder(); + + + content.append(maybeAddComment(input.getCopyright())); + content.append(maybeAddComment(input.getHeader())); + + if (input.getFQN().getPackageName().isEmpty() == false) { + content.append("package "); + content.append(input.getFQN().getPackageName()); + content.append(";\n"); + } + content.append(maybeAddComment(input.getClassJavaDoc(), true)); + + for (String classAnnotation : input.getClassAnnotations()) { + content.append(classAnnotation); + content.append("\n"); + } + + content.append("public "); + content.append(input.getType()); + content.append(" "); + content.append(input.getFQN().getTypeName()); + content.append(prefixAndJoin(input.getExtends(), "extends")); + content.append(prefixAndJoin(input.getImplements(), "implements")); + content.append(" {\n"); + + for (String method : input.getBodyElements()) { + content.append(method); + content.append("\n"); + } + + content.append("\n}\n"); + + return new GeneratedObject(fqn, content.toString()); + } + + private static String maybeAddComment(Optional comment) { + return maybeAddComment(comment, false); + } + + private static String maybeAddComment(Optional comment, boolean isJavadoc) { + + if (comment.isPresent()) { + String input = comment.get(); + return StringUtil.writeComment(input, isJavadoc); + } else { + return ""; + } + } + +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/JavaFileInput.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/JavaFileInput.java new file mode 100644 index 0000000000..ba8537bea0 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/JavaFileInput.java @@ -0,0 +1,27 @@ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.java; + +import com.google.common.base.Optional; + +import java.util.List; + +public interface JavaFileInput { + + FullyQualifiedName getFQN(); + + Optional getCopyright(); + + Optional getHeader(); + + TypeName getType(); + + Optional getClassJavaDoc(); + + List getClassAnnotations(); + + List getExtends(); + + List getImplements(); + + List getBodyElements(); + +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/JavaFileInputBuilder.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/JavaFileInputBuilder.java new file mode 100644 index 0000000000..c739f57730 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/JavaFileInputBuilder.java @@ -0,0 +1,164 @@ +/* + * 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.java; + +import com.google.common.base.Optional; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class JavaFileInputBuilder { + + private Optional copyright = Optional.absent(), header = Optional.absent(), classJavaDoc = Optional.absent(); + + private TypeName typeName = TypeName.classType; + + private FullyQualifiedName fqn; + + private final List classAnnotations = new ArrayList<>(); + + private final List extendsFQNs = new ArrayList<>(); + + private final List implementsFQNs = new ArrayList<>(); + + private final List bodyElements = new ArrayList<>(); + + public void addToBody(String element) { + bodyElements.add(element + "\n"); + } + + public void addClassAnnotation(Annotation annotation) { + addClassAnnotation(annotation.toString()); + } + + public void addClassAnnotation(String annotation) { + classAnnotations.add(checkNotNull(annotation)); + } + + public void addExtendsFQN(FullyQualifiedName fqn) { + extendsFQNs.add(fqn); + } + + public void addImplementsFQN(FullyQualifiedName fqn) { + implementsFQNs.add(fqn); + } + + public Optional getCopyright() { + return copyright; + } + + public void setCopyright(Optional copyright) { + this.copyright = checkNotNull(copyright); + } + + public Optional getHeader() { + return header; + } + + public void setHeader(Optional header) { + this.header = checkNotNull(header); + } + + + public Optional getClassJavaDoc() { + return classJavaDoc; + } + + public void setClassJavaDoc(Optional classJavaDoc) { + this.classJavaDoc = checkNotNull(classJavaDoc); + } + + + public FullyQualifiedName getFqn() { + return fqn; + } + + public void setFqn(FullyQualifiedName fqn) { + this.fqn = fqn; + } + + public List getExtendsFQNs() { + return extendsFQNs; + } + + + public List getImplementsFQNs() { + return implementsFQNs; + } + + + public TypeName getTypeName() { + return typeName; + } + + public void setTypeName(TypeName typeName) { + this.typeName = typeName; + } + + + public JavaFileInput build() { + checkNotNull(copyright); + checkNotNull(header); + checkNotNull(classJavaDoc); + checkNotNull(typeName); + checkNotNull(fqn); + + return new JavaFileInput() { + + @Override + public FullyQualifiedName getFQN() { + return fqn; + } + + @Override + public Optional getCopyright() { + return copyright; + } + + @Override + public Optional getHeader() { + return header; + } + + @Override + public Optional getClassJavaDoc() { + return classJavaDoc; + } + + @Override + public TypeName getType() { + return typeName; + } + + @Override + public List getExtends() { + return Collections.unmodifiableList(extendsFQNs); + } + + @Override + public List getImplements() { + return Collections.unmodifiableList(implementsFQNs); + } + + @Override + public List getClassAnnotations() { + return Collections.unmodifiableList(classAnnotations); + } + + @Override + public List getBodyElements() { + return Collections.unmodifiableList(bodyElements); + } + }; + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/TypeName.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/TypeName.java new file mode 100644 index 0000000000..d6ed12dbfe --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/java/TypeName.java @@ -0,0 +1,17 @@ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.java; + +public enum TypeName { + + classType("class"), interfaceType("interface"), enumType("enum"), absClassType("abstract class"), finalClassType("final class"); + + private final String value; + + TypeName(String value) { + this.value = value; + } + + @Override + public String toString() { + return value; + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/util/StringUtil.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/util/StringUtil.java new file mode 100644 index 0000000000..265aea10c5 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/util/StringUtil.java @@ -0,0 +1,101 @@ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.util; + +import com.google.common.base.Joiner; +import com.google.common.base.Optional; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.regex.Pattern; + +public class StringUtil { + private static final Logger logger = LoggerFactory.getLogger(StringUtils.class); + + /** + * @param list of strings to be joined by ',' + * @param prefix e.g. 'extends' or 'implements' + */ + public static String prefixAndJoin(List list, String prefix) { + if (list.isEmpty()) { + return ""; + } + Joiner joiner = Joiner.on(","); + return " " + prefix + " " + joiner.join(list); + } + + public static String addAsterixAtEachLineStart(String input) { + String s = Pattern.compile("^", Pattern.MULTILINE).matcher(input).replaceAll("* "); + // remove trailing spaces + s = Pattern.compile("\\s+$", Pattern.MULTILINE).matcher(s).replaceAll(""); + s = ensureEndsWithSingleNewLine(s); + return s; + } + + private static String ensureEndsWithSingleNewLine(String s) { + // .split Only trailing empty strings are skipped. + String[] split = s.split("\n"); + s = Joiner.on("\n").join(split); + s = s + "\n"; + return s; + } + + public static String writeComment(String input, boolean isJavadoc) { + StringBuilder content = new StringBuilder(); + content.append("/*"); + if (isJavadoc) { + content.append("*"); + } + content.append("\n"); + + content.append(addAsterixAtEachLineStart(input)); + content.append("*/\n"); + return content.toString(); + } + + + public static Optional loadCopyright() { + try (InputStream in = StringUtil.class.getResourceAsStream("/copyright.txt")) { + if (in != null) { + return Optional.of(IOUtils.toString(in)); + } + } catch (IOException e) { + logger.warn("Cannot load copyright.txt", e); + } + return Optional.absent(); + } + + public static String formatJavaSource(String input) { + Iterable split = Splitter.on("\n").trimResults().split(input); + + int basicIndent = 4; + StringBuilder sb = new StringBuilder(); + int intends = 0, empty = 0; + for (String line : split) { + intends -= StringUtils.countMatches(line, "}"); + if (intends < 0) { + intends = 0; + } + if (line.isEmpty() == false) { + sb.append(Strings.repeat(" ", basicIndent * intends)); + sb.append(line); + sb.append("\n"); + empty = 0; + } else { + empty++; // one empty line is allowed + if (empty < 2) { + sb.append("\n"); + } + } + intends += StringUtils.countMatches(line, "{"); + } + return ensureEndsWithSingleNewLine(sb.toString()); + } + +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/copyright.txt b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/copyright.txt new file mode 100644 index 0000000000..4a0c355685 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/copyright.txt @@ -0,0 +1,5 @@ +Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + +This program and the accompanying materials are made available under the +terms of the Eclipse Public License v1.0 which accompanies this distribution, +and is available at http://www.eclipse.org/legal/epl-v10.html diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/abstract_ftl_file.ftl b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/abstract_ftl_file.ftl deleted file mode 100644 index 0c6bf839fa..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/abstract_ftl_file.ftl +++ /dev/null @@ -1,15 +0,0 @@ -<@headerD header=header/> -package ${packageName}; - -<@javadocD object=javadoc/> -<@annotationsD object=annotations/> -<#-- class/interface --> -<@typeDeclarationD object=typeDeclaration/> -{ - -<@constructorsD object=constructors> - -<@fieldsD object=fields/> - -<@methodsD object=methods/> -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/factory_abs_template.ftl b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/factory_abs_template.ftl deleted file mode 100644 index b9bbf1f1b5..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/factory_abs_template.ftl +++ /dev/null @@ -1,82 +0,0 @@ -<@headerD header=header/> -package ${packageName}; - -<@javadocD object=javadoc/> -@org.opendaylight.yangtools.yang.binding.annotations.ModuleQName(namespace="${mbe.getYangModuleQName().getNamespace().toString()}",revision="${mbe.getYangModuleQName().getFormattedRevision()}",name="${mbe.getYangModuleQName().getLocalName()}") -<@typeDeclarationD object=typeDeclaration/> -{ - - public static final java.lang.String NAME = "${globallyUniqueName}"; - private static final java.util.Set> serviceIfcs; - <#if providedServices??> - static { - java.util.Set> serviceIfcs2 = new java.util.HashSet>(); - <#list providedServices as refId> - serviceIfcs2.add(${refId}); - - serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2); - } - - - @Override - public final boolean isModuleImplementingServiceInterface(Class serviceInterface) { - for (Class ifc: serviceIfcs) { - if (serviceInterface.isAssignableFrom(ifc)){ - return true; - } - } - return false; - } - - @Override - public java.util.Set> getImplementedServiceIntefaces() { - return serviceIfcs; - } - - - @Override - public ${moduleType} createModule(String instanceName, ${dependencyResolverType} dependencyResolver, ${bundleContextType} bundleContext) { - return instantiateModule(instanceName, dependencyResolver, bundleContext); - } - - @Override - public ${moduleType} createModule(String instanceName, ${dependencyResolverType} dependencyResolver, ${dynamicMBeanWithInstanceType} old, ${bundleContextType} bundleContext) throws Exception { - ${moduleInstanceType} oldModule = null; - try { - oldModule = (${moduleInstanceType}) old.getModule(); - } catch(Exception e) { - return handleChangedClass(old); - } - ${moduleInstanceType} module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext); - - <#list fields as attr> - module.set${attr.name}(oldModule.get${attr.name}()); - - - return module; - } - - public ${moduleInstanceType} instantiateModule(String instanceName, ${dependencyResolverType} dependencyResolver, ${moduleInstanceType} oldModule, ${instanceType} oldInstance, ${bundleContextType} bundleContext) { - return new ${moduleInstanceType}(new ${moduleNameType}(NAME, instanceName), dependencyResolver, oldModule, oldInstance); - } - - public ${moduleInstanceType} instantiateModule(String instanceName, ${dependencyResolverType} dependencyResolver, ${bundleContextType} bundleContext) { - return new ${moduleInstanceType}(new ${moduleNameType}(NAME, instanceName), dependencyResolver); - } - - @Override - public final String getImplementationName() { - return NAME; - } - - - public ${moduleInstanceType} handleChangedClass(${dynamicMBeanWithInstanceType} old) throws Exception { - throw new UnsupportedOperationException("Class reloading is not supported"); - } - - @Override - public java.util.Set<${moduleInstanceType}> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory, ${bundleContextType} bundleContext) { - return new java.util.HashSet<${moduleInstanceType}>(); - } - -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl deleted file mode 100644 index 848fcfe5fc..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl +++ /dev/null @@ -1,223 +0,0 @@ -<@headerD header=header/> -package ${packageName}; - -<@javadocD object=javadoc/> -<@annotationsD object=annotations/> -<@typeDeclarationD object=typeDeclaration/> -{ - // attributes - <@moduleFieldsD moduleFields=moduleFields/> - //attributes end - - private static final ${loggerType} logger = ${loggerFactoryType}.getLogger(${typeDeclaration.name}.class); - - private final ${typeDeclaration.name} oldModule; - private final ${instanceType} oldInstance; - private ${instanceType} instance; - private final ${dependencyResolverType} dependencyResolver; - private final ${moduleNameType} identifier; - <#if runtime=true> - private ${registratorType} rootRuntimeBeanRegistratorWrapper; - - - public ${typeDeclaration.name}(${moduleNameType} identifier, ${dependencyResolverType} dependencyResolver) { - this.identifier = identifier; - this.dependencyResolver = dependencyResolver; - this.oldInstance = null; - this.oldModule = null; - } - - public ${typeDeclaration.name}(${moduleNameType} identifier, ${dependencyResolverType} dependencyResolver, ${typeDeclaration.name} oldModule, ${instanceType} oldInstance) { - this.identifier = identifier; - this.dependencyResolver = dependencyResolver; - this.oldInstance = oldInstance; - this.oldModule = oldModule; - } - - // getters and setters exported into MXBean - <@methodsD object=methods/> - - <#if runtime=true> - public ${registratorType} getRootRuntimeBeanRegistratorWrapper(){ - return rootRuntimeBeanRegistratorWrapper; - } - - @Override - public void setRuntimeBeanRegistrator(${rootRuntimeRegistratorType} rootRuntimeRegistrator){ - this.rootRuntimeBeanRegistratorWrapper = new ${registratorType}(rootRuntimeRegistrator); - } - - - @Override - public void validate(){ - <#list moduleFields as field> - <#if field.dependent==true && field.dependency.mandatory==true> - <#if field.type?starts_with("java.util.List")> - for(javax.management.ObjectName dep : ${field.name}) { - dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, dep, ${field.name}JmxAttribute); - } - <#else> - dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, ${field.name}, ${field.name}JmxAttribute); - - - - customValidation(); - } - - protected void customValidation(){ - - } - - // caches of resolved dependencies - <#list moduleFields as field> - <#if field.dependent==true> - <#if field.type?starts_with("java.util.List")> - 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> - private ${field.dependency.sie.exportedOsgiClassName} ${field.name}Dependency; - protected final ${field.dependency.sie.exportedOsgiClassName} get${field.attributeName}Dependency(){ - return ${field.name}Dependency; - } - - - - - // caches of resolved IdentityRefs - <#list moduleFields as field> - <#if field.identityRef==true> - private ${field.identityClassType} ${field.identityClassName}; - - - - @Override - public final ${instanceType} getInstance(){ - if(instance==null) { - - <#list moduleFields as field> - <#if field.dependent==true> - <#if field.dependency.mandatory==false> - if(${field.name}!=null) { - - - <#if field.type?starts_with("java.util.List")> - ${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)); - } - <#else> - ${field.name}Dependency = dependencyResolver.resolveInstance(${field.dependency.sie.exportedOsgiClassName}.class, ${field.name}, ${field.name}JmxAttribute); - - - <#if field.dependency.mandatory==false> - } - - - - <#if field.needsDepResolver==true> - if(${field.name} != null) { - <#if field.type?starts_with("java.util.List")> - for(${field.type?substring(field.type?index_of("<") + 1, field.type?index_of(">"))} candidate : ${field.name}) { - candidate.injectDependencyResolver(dependencyResolver); - } - <#else> - ${field.name}.injectDependencyResolver(dependencyResolver); - - } - - - <#if field.identityRef==true> - if(${field.name} != null) { - set${field.attributeName}(${field.name}.resolveIdentity(dependencyResolver, ${field.identityBaseClass}.class)); - } - - - - 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(); - } - } - return instance; - } - - @Override - public ${moduleNameType} getIdentifier() { - return identifier; - } - - public boolean canReuseInstance(${typeDeclaration.name} oldModule){ - // allow reusing of old instance if no parameters was changed - return isSame(oldModule); - } - - public ${instanceType} reuseInstance(${instanceType} oldInstance){ - // implement if instance reuse should be supported. Override canReuseInstance to change the criteria. - return oldInstance; - } - - public abstract ${instanceType} createInstance(); - - public boolean isSame(${typeDeclaration.name} other) { - if (other == null) { - throw new IllegalArgumentException("Parameter 'other' is null"); - } - <#list moduleFields as field> - <#if field.dependent==true && field.listOfDependencies == false> - if (${field.name}Dependency != other.${field.name}Dependency) { // reference to dependency must be same - return false; - } - <#elseif field.listOfDependencies> - 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.name} == null) { - if (other.${field.name} != null) { - return false; - } - } else if - <#if field.array == false> - (${field.name}.equals(other.${field.name}) == false) - <#else> - (java.util.Arrays.equals(${field.name},other.${field.name}) == false) - - { - return false; - } - - - - return true; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - ${typeDeclaration.name} that = (${typeDeclaration.name}) o; - - return identifier.equals(that.identifier); - } - - @Override - public int hashCode() { - return identifier.hashCode(); - } -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_stub_template.ftl b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_stub_template.ftl deleted file mode 100644 index 2db505e54e..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_stub_template.ftl +++ /dev/null @@ -1,27 +0,0 @@ -<@headerD header=header/> -package ${packageName}; - -<@javadocD object=javadoc/> -<@typeDeclarationD object=typeDeclaration/> { - - public ${typeDeclaration.name}(${moduleNameType} identifier, ${dependencyResolverType} dependencyResolver) { - super(identifier, dependencyResolver); - } - - public ${typeDeclaration.name}(${moduleNameType} identifier, ${dependencyResolverType} dependencyResolver, - ${typeDeclaration.name} oldModule, ${instanceType} oldInstance) { - - super(identifier, dependencyResolver, oldModule, oldInstance); - } - - @Override - protected void customValidation(){ - // Add custom validation for module attributes here. - } - - @Override - public ${instanceType} createInstance() { - //TODO:implement - <@unimplementedExceptionD/> - } -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/AbstractGeneratorTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/AbstractGeneratorTest.java index 9e2f334dac..1dde94b482 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/AbstractGeneratorTest.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/AbstractGeneratorTest.java @@ -7,12 +7,12 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin; -import java.io.File; - import org.apache.commons.io.FileUtils; import org.junit.Before; import org.opendaylight.controller.config.yangjmxgenerator.AbstractYangTest; +import java.io.File; + public abstract class AbstractGeneratorTest extends AbstractYangTest { private static final File GENERATOR_OUTPUT_PATH_ROOT = new File( "target/testgen"); diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java index 3ef406694a..0fd9720f79 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java @@ -119,7 +119,7 @@ public class JMXGeneratorTest extends AbstractGeneratorTest { + JMXGenerator.NAMESPACE_TO_PACKAGE_DIVIDER + PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX); map.put(JMXGenerator.MODULE_FACTORY_FILE_BOOLEAN, "false"); - jmxGenerator = new JMXGenerator(new FreeMarkerCodeWriterImpl()); + jmxGenerator = new JMXGenerator(new CodeWriter()); jmxGenerator.setAdditionalConfig(map); File targetDir = new File(generatorOutputPath, "target"); generatedResourcesDir = new File(targetDir, "generated-resources"); diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ModuleMXBeanEntryTemplatesTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ModuleMXBeanEntryTemplatesTest.java index 48d5b30eb2..3c01cc00d4 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ModuleMXBeanEntryTemplatesTest.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ModuleMXBeanEntryTemplatesTest.java @@ -34,7 +34,7 @@ public class ModuleMXBeanEntryTemplatesTest { assertNotNull(template); } - private ModuleMXBeanEntry mockMbe(String packageName) { + public static ModuleMXBeanEntry mockMbe(String packageName) { ModuleMXBeanEntry mbe = mock(ModuleMXBeanEntry.class); Map a = Maps.newHashMap(); JavaAttribute attr = mockJavaAttr(); @@ -52,7 +52,7 @@ public class ModuleMXBeanEntryTemplatesTest { return mbe; } - private JavaAttribute mockJavaAttr() { + public static JavaAttribute mockJavaAttr() { JavaAttribute attr = mock(JavaAttribute.class); Type typeA = mock(Type.class); doReturn("package").when(typeA).getName(); diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/RuntimeRegistratorFtlFileTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/RuntimeRegistratorFtlFileTest.java index b12ee5023f..f21765e536 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/RuntimeRegistratorFtlFileTest.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/RuntimeRegistratorFtlFileTest.java @@ -7,26 +7,21 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.junit.internal.matchers.StringContains.containsString; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; - import org.junit.Test; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeRegistratorTest; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlFilePersister; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.RuntimeRegistratorFtlTemplate; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FormattingUtil; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; public class RuntimeRegistratorFtlFileTest extends RuntimeRegistratorTest { - private final FtlFilePersister ftlFilePersister = new FtlFilePersister(); @Test public void testRootWithoutAnything() { @@ -40,9 +35,7 @@ public class RuntimeRegistratorFtlFileTest extends RuntimeRegistratorTest { FtlTemplate rootFtlFile = createdFtls.get(rootRegistratorName); assertNotNull(rootFtlFile); - Map serializedFtls = ftlFilePersister - .serializeFtls(createdFtls.values()); - assertThat(serializedFtls.size(), is(2)); + assertThat(createdFtls.values().size(), is(2)); } @Test @@ -55,29 +48,6 @@ public class RuntimeRegistratorFtlFileTest extends RuntimeRegistratorTest { Map createdFtls = RuntimeRegistratorFtlTemplate .create(rootRB); - Map serializedFtls = ftlFilePersister - .serializeFtls(createdFtls.values()); - assertThat(serializedFtls.size(), is(4)); - - assertThat( - findRegistrationOutput(createdFtls, grandChildRB, - serializedFtls), not(containsString(" register("))); - - FtlTemplate registrator = createdFtls.get(RuntimeRegistratorFtlTemplate - .getJavaNameOfRuntimeRegistrator(rootRB)); - FormattingUtil.cleanUpEmptyLinesAndIndent(serializedFtls - .get(registrator)); - + assertThat(createdFtls.values().size(), is(4)); } - - private String findRegistrationOutput(Map createdFtls, - RuntimeBeanEntry rb, Map serializedFtls) { - RuntimeRegistratorFtlTemplate rbFtlFile = (RuntimeRegistratorFtlTemplate) createdFtls - .get(RuntimeRegistratorFtlTemplate.getJavaNameOfRuntimeRegistration(rb.getJavaNamePrefix())); - assertNotNull(rbFtlFile); - String unformatted = serializedFtls.get(rbFtlFile); - assertNotNull(unformatted); - return FormattingUtil.cleanUpEmptyLinesAndIndent(unformatted); - } - } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersisterTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersisterTest.java deleted file mode 100644 index 2582a602b3..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersisterTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl; - -import static org.junit.Assert.assertEquals; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.MockitoAnnotations; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.MethodDeclaration; -import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FormattingUtil; - -import com.google.common.collect.Lists; - -public class FtlFilePersisterTest { - private final FtlFilePersister tested = new FtlFilePersister(); - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testGeneralInterface() { - String packageName = "pa.cka.ge"; - String name = "GeneralClassImpl"; - List extendedInterfaces = Arrays.asList("List", "Set"); - List methods = new ArrayList<>(); - methods.add(new MethodDeclaration("String", "executeOperation", - Collections. emptyList())); - - List mods = Lists.newArrayList(); - List mods2 = Lists.newArrayList("final"); - methods.add(new MethodDeclaration("String", "executeOperation", Arrays - .asList(new Field(mods, "int", "param1"), new Field(mods2, "long", "param2")))); - - GeneralInterfaceTemplate generalInterface = new GeneralInterfaceTemplate( - null, packageName, name, extendedInterfaces, methods); - - Map abstractFtlFileStringMap = tested - .serializeFtls(Arrays.asList(generalInterface)); - String content = FormattingUtil - .cleanUpEmptyLinesAndIndent(abstractFtlFileStringMap.get(generalInterface)); - - // skip header - content = content.substring(content.indexOf("package")); - - String expected = "package pa.cka.ge;\n" - + "/**\n" - + "*\n" - + "*/\n" - + "public interface GeneralClassImpl extends List, Set\n{\n" - + "public String executeOperation();\n" - + "public String executeOperation(int param1, final long param2);\n" - + "}\n"; - - assertEquals(expected, content); - } - -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/module/AbstractGeneratedObjectTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/module/AbstractGeneratedObjectTest.java new file mode 100644 index 0000000000..957fbf5251 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/module/AbstractGeneratedObjectTest.java @@ -0,0 +1,44 @@ +/* + * 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.module; + +import net.sourceforge.pmd.lang.Parser; +import net.sourceforge.pmd.lang.ParserOptions; +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.java.Java17Parser; +import org.apache.commons.io.FileUtils; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.AbstractGeneratorTest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class AbstractGeneratedObjectTest extends AbstractGeneratorTest { + private static final Logger logger = LoggerFactory.getLogger(AbstractGeneratedObjectTest.class); + + protected void assertHasMethodNamed(Node c, String method) { + assertTrue(c.hasDescendantMatchingXPath("//MethodDeclaration[MethodDeclarator[@Image='" + + method + + "']]")); + } + + protected Node parse(File dstFile) throws IOException { + assertNotNull(dstFile); + logger.debug(FileUtils.readFileToString(dstFile)); + Parser parser = new Java17Parser(new ParserOptions()); + return parser.parse(dstFile.toString(), new FileReader(dstFile)); + } + + +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/module/abs/AbsModuleGeneratedObjectFactoryTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/module/abs/AbsModuleGeneratedObjectFactoryTest.java new file mode 100644 index 0000000000..164d1a5f58 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/module/abs/AbsModuleGeneratedObjectFactoryTest.java @@ -0,0 +1,45 @@ +/* + * 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.module.abs; + +import com.google.common.base.Optional; +import org.junit.Test; +import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; +import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory.AbsModuleGeneratedObjectFactory; +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.module.AbstractGeneratedObjectTest; +import org.opendaylight.yangtools.yang.common.QName; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.Map.Entry; + +public class AbsModuleGeneratedObjectFactoryTest extends AbstractGeneratedObjectTest { + + @Test + public void test() throws IOException { + Map serviceInterfaceEntryMap = loadThreadsServiceInterfaceEntries("packages.sis"); + Map namesToMBEs = loadThreadsJava(serviceInterfaceEntryMap, "packages.pack2"); + ModuleMXBeanEntry dynamicThreadPool = namesToMBEs.get(THREADPOOL_DYNAMIC_MXB_NAME); + parseGeneratedFile(dynamicThreadPool); + + } + + private void parseGeneratedFile(ModuleMXBeanEntry moduleMXBeanEntry) throws IOException { + Optional copyright = Optional.absent(); + GeneratedObject generatedObject = new AbsModuleGeneratedObjectFactory().toGeneratedObject(moduleMXBeanEntry, copyright); + Entry entry = generatedObject.persist(generatorOutputPath).get(); + + File dstFile = entry.getValue(); + parse(dstFile); + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/module/concrete/ConcreteModuleGeneratedObjectFactoryTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/module/concrete/ConcreteModuleGeneratedObjectFactoryTest.java new file mode 100644 index 0000000000..519b0edf42 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/module/concrete/ConcreteModuleGeneratedObjectFactoryTest.java @@ -0,0 +1,52 @@ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.module.concrete; + +import com.google.common.base.Optional; +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; +import org.junit.Test; +import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory.ConcreteModuleGeneratedObjectFactory; +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.module.AbstractGeneratedObjectTest; + +import java.io.File; +import java.util.Map.Entry; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +public class ConcreteModuleGeneratedObjectFactoryTest extends AbstractGeneratedObjectTest { + + @Test + public void test() throws Exception { + FullyQualifiedName fqn = new FullyQualifiedName("foo.bar", "Baz"); + FullyQualifiedName abstractFQN = new FullyQualifiedName("foo.bar", "AbstractBaz"); + String nullableDescription = null; + + ModuleMXBeanEntry moduleMXBeanEntry = mockModuleMXBeanEntry(fqn, abstractFQN, nullableDescription); + Optional copyright = Optional.absent(); + Optional header = Optional.absent(); + GeneratedObject go = new ConcreteModuleGeneratedObjectFactory().toGeneratedObject(moduleMXBeanEntry, copyright, header); + Entry entry = go.persist(generatorOutputPath).get(); + + File dstFile = entry.getValue(); + Node c = parse(dstFile); + assertEquals(fqn.getPackageName(), ((ASTCompilationUnit) c).getPackageDeclaration().getPackageNameImage()); + assertEquals(fqn.getTypeName(), c.getFirstDescendantOfType(ASTClassOrInterfaceDeclaration.class).getImage()); + assertHasMethodNamed(c, "customValidation"); + assertHasMethodNamed(c, "createInstance"); + } + + static ModuleMXBeanEntry mockModuleMXBeanEntry(FullyQualifiedName fqn, FullyQualifiedName abstractFQN, String nullableDescription) { + ModuleMXBeanEntry mock = mock(ModuleMXBeanEntry.class); + assertEquals(fqn.getPackageName(), abstractFQN.getPackageName()); + doReturn(fqn.getPackageName()).when(mock).getPackageName(); + doReturn(fqn.getTypeName()).when(mock).getStubModuleName(); + doReturn(nullableDescription).when(mock).getNullableDescription(); + doReturn(abstractFQN.getTypeName()).when(mock).getAbstractModuleName(); + return mock; + } +} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/util/FormattingUtil.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/util/FormattingUtil.java deleted file mode 100644 index e62cb7c002..0000000000 --- a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/util/FormattingUtil.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.config.yangjmxgenerator.plugin.util; - -import java.util.Scanner; - -public class FormattingUtil { - - public static String cleanUpEmptyLinesAndIndent(String input) { - StringBuffer output = new StringBuffer(); - Scanner scanner = new Scanner(input); - while (scanner.hasNextLine()) { - String line = scanner.nextLine(); - line = line.replaceAll("\t", " "); - while (line.contains(" ")) { - line = line.replaceAll(" ", " "); - } - line = line.trim(); - if (line.length() > 0) { - output.append(line); - output.append("\n"); - } - } - - return output.toString(); - } -} diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/util/StringUtilTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/util/StringUtilTest.java new file mode 100644 index 0000000000..b0217a4ba9 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/util/StringUtilTest.java @@ -0,0 +1,60 @@ +package org.opendaylight.controller.config.yangjmxgenerator.plugin.util; + +import org.junit.Test; +import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName; + +import java.io.IOException; + +import static java.util.Arrays.asList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class StringUtilTest { + @Test + public void testPrefixAndJoin() { + assertEquals(" extends p1.Foo,Bar", StringUtil.prefixAndJoin(asList( + new FullyQualifiedName("p1", "Foo"), new FullyQualifiedName("", "Bar")), "extends")); + } + + @Test + public void testAddAsterixAtEachLineStart() { + String input = "foo \nbar"; + String expectedOutput = "* foo\n* bar\n"; + assertEquals(expectedOutput, StringUtil.addAsterixAtEachLineStart(input)); + } + + @Test + public void testCopyright() throws IOException { + assertTrue(StringUtil.loadCopyright().isPresent()); + } + + @Test + public void testFormatting() { + { + String input = " \tpack;\n" + + "class Bar{ \n" + + " method() {\n" + + " body\n" + + "}\n" + + " }"; + String expected = "pack;\n" + + "class Bar{\n" + + " method() {\n" + + " body\n" + + " }\n" + + "}\n"; + assertEquals(expected, StringUtil.formatJavaSource(input)); + } + { + String input = "{\n" + + "bar\n" + + "}\n" + + "\n\nbaz\n\n\n\n"; + String expected = "{\n" + + " bar\n" + + "}\n\n" + + "baz\n"; + assertEquals(expected, StringUtil.formatJavaSource(input)); + } + } +} diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java index 1100b35437..76d97703af 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java @@ -7,25 +7,29 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.format; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - +import com.google.common.base.Preconditions; +import com.google.common.collect.Sets; +import org.junit.Assert; import org.junit.Before; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.YangModelSearchUtils; +import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; -import com.google.common.base.Preconditions; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.format; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; public abstract class AbstractYangTest { protected SchemaContext context; @@ -35,6 +39,14 @@ public abstract class AbstractYangTest { threadsJavaModule, bgpListenerJavaModule, ietfInetTypesModule, jmxModule, jmxImplModule, testFilesModule, testFiles1Module; + public static final String EVENTBUS_MXB_NAME = "eventbus"; + public static final String ASYNC_EVENTBUS_MXB_NAME = "async-eventbus"; + public static final String THREADFACTORY_NAMING_MXB_NAME = "threadfactory-naming"; + public static final String THREADPOOL_DYNAMIC_MXB_NAME = "threadpool-dynamic"; + public static final String THREADPOOL_REGISTRY_IMPL_NAME = "threadpool-registry-impl"; + + public static final String BGP_LISTENER_IMPL_MXB_NAME = "bgp-listener-impl"; + @Before public void loadYangFiles() throws Exception { List yangISs = new ArrayList<>(); @@ -97,4 +109,22 @@ public abstract class AbstractYangTest { } return result; } + + protected Map loadThreadsServiceInterfaceEntries(String packageName) { + Map identitiesToSIs = new HashMap<>(); + return ServiceInterfaceEntry.create(threadsModule, packageName,identitiesToSIs); + } + + protected Map loadThreadsJava(Map modulesToSIEs, String packageName) { + Map namesToMBEs = ModuleMXBeanEntry + .create(threadsJavaModule, modulesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl + (context)), packageName); + Assert.assertNotNull(namesToMBEs); + Set expectedMXBeanNames = Sets.newHashSet(EVENTBUS_MXB_NAME, + ASYNC_EVENTBUS_MXB_NAME, THREADFACTORY_NAMING_MXB_NAME, + THREADPOOL_DYNAMIC_MXB_NAME, THREADPOOL_REGISTRY_IMPL_NAME); + assertThat(namesToMBEs.keySet(), is(expectedMXBeanNames)); + return namesToMBEs; + } + } diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java index 8ca2bb5bc9..dd44246867 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java @@ -8,7 +8,6 @@ package org.opendaylight.controller.config.yangjmxgenerator; import com.google.common.collect.Sets; -import java.util.HashMap; import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; @@ -36,6 +35,7 @@ import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -52,13 +52,6 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; public class ModuleMXBeanEntryTest extends AbstractYangTest { - public static final String EVENTBUS_MXB_NAME = "eventbus"; - public static final String ASYNC_EVENTBUS_MXB_NAME = "async-eventbus"; - public static final String THREADFACTORY_NAMING_MXB_NAME = "threadfactory-naming"; - public static final String THREADPOOL_DYNAMIC_MXB_NAME = "threadpool-dynamic"; - public static final String THREADPOOL_REGISTRY_IMPL_NAME = "threadpool-registry-impl"; - - public static final String BGP_LISTENER_IMPL_MXB_NAME = "bgp-listener-impl"; public static final String PACKAGE_NAME = "pack2"; @@ -82,23 +75,15 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest { protected Map modulesToSIEs; - protected Map loadThreadsJava() { - Map namesToMBEs = ModuleMXBeanEntry - .create(threadsJavaModule, modulesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl - (context)), PACKAGE_NAME); - assertNotNull(namesToMBEs); - Set expectedMXBeanNames = Sets.newHashSet(EVENTBUS_MXB_NAME, - ASYNC_EVENTBUS_MXB_NAME, THREADFACTORY_NAMING_MXB_NAME, - THREADPOOL_DYNAMIC_MXB_NAME, THREADPOOL_REGISTRY_IMPL_NAME); - assertThat(namesToMBEs.keySet(), is(expectedMXBeanNames)); - return namesToMBEs; - } @Before public void setUp() { - Map identitiesToSIs = new HashMap<>(); - modulesToSIEs = ServiceInterfaceEntry.create(threadsModule, - "packages.sis",identitiesToSIs); + modulesToSIEs = loadThreadsServiceInterfaceEntries("packages.sis"); + } + + + protected Map loadThreadsJava() { + return loadThreadsJava(modulesToSIEs, PACKAGE_NAME); } @Test diff --git a/opendaylight/config/yang-test-plugin/pom.xml b/opendaylight/config/yang-test-plugin/pom.xml index 0b4fc8b1b5..a4306c15c4 100644 --- a/opendaylight/config/yang-test-plugin/pom.xml +++ b/opendaylight/config/yang-test-plugin/pom.xml @@ -22,5 +22,9 @@ maven-plugin-api 3.0.5 + + commons-io + commons-io + \ No newline at end of file diff --git a/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java b/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java index dbb9ddb363..f2a56f2b1b 100644 --- a/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java +++ b/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/ProcessSources.java @@ -7,18 +7,14 @@ */ package org.opendaylight.controller.config.yang.test.plugin; +import org.apache.commons.io.FileUtils; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; +import java.util.regex.Pattern; /** * Add implementation code from stub.txt @@ -45,55 +41,25 @@ public class ProcessSources extends AbstractMojo{ if (!sourceDirectory.exists()) { super.getLog().error("Source directory does not exists " + sourceDirectory.getPath()); } - String header = ""; - try { - header = Util.loadHeader(); - } catch (IOException e) { - super.getLog().error("Header.txt not found."); - } + File[] sourceFiles = sourceDirectory.listFiles(); for (File sourceFile: sourceFiles) { if(sourceFile.getName().endsWith("Module.java") || sourceFile.getName().endsWith("ModuleFactory.java")) { File stubFile = new File(sourceFile.getPath().replace(".java", "Stub.txt")); - String stubLines = null; - try { - if (stubFile.exists()) { - stubLines = Util.loadStubFile(stubFile.getPath()); - } - - InputStream javaIn = new FileInputStream(sourceFile.getPath()); - BufferedReader javaBuf = new BufferedReader(new InputStreamReader(javaIn)); - StringBuffer output = new StringBuffer(); - String line = javaBuf.readLine(); - boolean writeLine = false; - while ((line = javaBuf.readLine()) != null) { - if(!writeLine && line.contains("*/")) { - line = header; - writeLine = true; - } else { - if (line.contains("TODO")) { - writeLine = false; - } else { - if (stubLines != null && line.contains("throw new")) { - line = stubLines.toString(); - writeLine = true; - } - } - } - if(writeLine) { - output.append(line).append(System.lineSeparator()); - } + if (stubFile.exists()) { + try { + rewrite(sourceFile, FileUtils.readFileToString(stubFile)); + } catch (IOException e) { + getLog().error("Error while reading/writing to files.", e); } - javaBuf.close(); - - OutputStream javaOut = new FileOutputStream(sourceFile.getPath()); - javaOut.write(output.toString().getBytes()); - javaOut.close(); - } catch (IOException e) { - getLog().error("Error while reading/writing to files.", e); } - } } } + + private static void rewrite(File sourceFile, String replaceTODOWith) throws IOException { + String source = FileUtils.readFileToString(sourceFile); + String target = Pattern.compile("^.*TODO.*\n.*throw new java.lang.UnsupportedOperationException.*$", Pattern.MULTILINE).matcher(source).replaceFirst(replaceTODOWith); + FileUtils.write(sourceFile, target); + } } diff --git a/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/Util.java b/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/Util.java index 16a41d9adb..136733cbff 100644 --- a/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/Util.java +++ b/opendaylight/config/yang-test-plugin/src/main/java/org/opendaylight/controller/config/yang/test/plugin/Util.java @@ -8,12 +8,7 @@ package org.opendaylight.controller.config.yang.test.plugin; -import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.util.regex.Matcher; public class Util { @@ -22,29 +17,4 @@ public class Util { path = path.replace(".", Matcher.quoteReplacement(File.separator)); return path; } - - public static String loadHeader() throws IOException { - StringBuffer header = new StringBuffer(); - InputStream headIn = Util.class.getClassLoader().getResourceAsStream("Header.txt"); - BufferedReader headBuf = new BufferedReader(new InputStreamReader(headIn)); - String line = null; - while ((line = headBuf.readLine()) != null) { - header.append(line).append(System.lineSeparator()); - } - headBuf.close(); - return header.toString(); - } - - public static String loadStubFile(String fileName) throws IOException { - InputStream stubIn = new FileInputStream(fileName); - BufferedReader stubBuf = new BufferedReader(new InputStreamReader(stubIn)); - - StringBuffer stubLines = new StringBuffer(); - String stubLine = null; - while ((stubLine = stubBuf.readLine()) != null) { - stubLines.append(stubLine).append(System.lineSeparator()); - } - stubBuf.close(); - return stubLines.toString(); - } } diff --git a/opendaylight/config/yang-test/pom.xml b/opendaylight/config/yang-test/pom.xml index 3e75d00943..ecce3e33fc 100644 --- a/opendaylight/config/yang-test/pom.xml +++ b/opendaylight/config/yang-test/pom.xml @@ -107,6 +107,7 @@ org.opendaylight.yangtools yang-maven-plugin + org.opendaylight.controller yang-test-plugin @@ -115,6 +116,7 @@ delete-sources + process-sources diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java index c64f824b15..07d7438a00 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModule.java @@ -1,32 +1,23 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.config.yang.test.impl; - -/** +* 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 */ -public final class DepTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModule - { - +package org.opendaylight.controller.config.yang.test.impl; +public class DepTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModule { public DepTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); } - public DepTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, - DepTestImplModule oldModule, java.lang.AutoCloseable oldInstance) { - + public DepTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.test.impl.DepTestImplModule oldModule, java.lang.AutoCloseable oldInstance) { super(identifier, dependencyResolver, oldModule, oldInstance); } @Override - protected void customValidation(){ - // Add custom validation for module attributes here. + public void customValidation() { + // add custom validation form module attributes here. } @Override @@ -38,4 +29,5 @@ public final class DepTestImplModule extends org.opendaylight.controller.config. }; } + } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java index c26c29ed60..849dd1464d 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/DepTestImplModuleFactory.java @@ -1,18 +1,20 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.config.yang.test.impl; - -/** +* 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 */ -public class DepTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModuleFactory -{ - +/* +* Generated file +* +* Generated from: yang module name: config-test-impl yang module local name: impl-dep +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Mon Mar 17 14:04:38 CET 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.test.impl; +public class DepTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractDepTestImplModuleFactory { } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java index 398bba99bd..a5b7f55df3 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModule.java @@ -1,32 +1,23 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.config.yang.test.impl; - -/** +* 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 */ -public final class IdentityTestModule extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModule - { - +package org.opendaylight.controller.config.yang.test.impl; +public class IdentityTestModule extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModule { public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); } - public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, - IdentityTestModule oldModule, java.lang.AutoCloseable oldInstance) { - + public IdentityTestModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.test.impl.IdentityTestModule oldModule, java.lang.AutoCloseable oldInstance) { super(identifier, dependencyResolver, oldModule, oldInstance); } @Override - protected void customValidation(){ - // Add custom validation for module attributes here. + public void customValidation() { + // add custom validation form module attributes here. } @Override @@ -49,4 +40,5 @@ public final class IdentityTestModule extends org.opendaylight.controller.config }; } + } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java index 9de3e0bb74..5560b6ec3f 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/IdentityTestModuleFactory.java @@ -1,18 +1,20 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.config.yang.test.impl; - -/** +* 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 */ -public class IdentityTestModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModuleFactory -{ - +/* +* Generated file +* +* Generated from: yang module name: config-test-impl yang module local name: impl-identity-test +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Mon Mar 17 14:04:38 CET 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.test.impl; +public class IdentityTestModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractIdentityTestModuleFactory { } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java index 3594ee0353..ecbf4aba33 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModule.java @@ -1,32 +1,23 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.config.yang.test.impl; - -/** +* 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 */ -public final class NetconfTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModule - { - +package org.opendaylight.controller.config.yang.test.impl; +public class NetconfTestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModule { public NetconfTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); } - public NetconfTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, - NetconfTestImplModule oldModule, java.lang.AutoCloseable oldInstance) { - + public NetconfTestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModule oldModule, java.lang.AutoCloseable oldInstance) { super(identifier, dependencyResolver, oldModule, oldInstance); } @Override - protected void customValidation(){ - // Add custom validation for module attributes here. + public void customValidation() { + // add custom validation form module attributes here. } @Override @@ -34,4 +25,5 @@ public final class NetconfTestImplModule extends org.opendaylight.controller.con return NetconfTestImplModuleUtil.registerRuntimeBeans(this); } + } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java index accc1db76e..b857c6211d 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/NetconfTestImplModuleFactory.java @@ -1,18 +1,20 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.config.yang.test.impl; - -/** +* 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 */ -public class NetconfTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModuleFactory -{ - +/* +* Generated file +* +* Generated from: yang module name: config-test-impl yang module local name: impl-netconf +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Mon Mar 17 14:04:38 CET 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.test.impl; +public class NetconfTestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractNetconfTestImplModuleFactory { } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java index 9ba1db4eed..9132407356 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModule.java @@ -1,32 +1,23 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.config.yang.test.impl; - -/** +* 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 */ -public final class TestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModule - { - +package org.opendaylight.controller.config.yang.test.impl; +public class TestImplModule extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModule { public TestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); } - public TestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, - TestImplModule oldModule, java.lang.AutoCloseable oldInstance) { - + public TestImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.test.impl.TestImplModule oldModule, java.lang.AutoCloseable oldInstance) { super(identifier, dependencyResolver, oldModule, oldInstance); } @Override - protected void customValidation(){ - // Add custom validation for module attributes here. + public void customValidation() { + // add custom validation form module attributes here. } @Override @@ -38,4 +29,5 @@ public final class TestImplModule extends org.opendaylight.controller.config.yan }; } + } diff --git a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java index a6ce734f96..ae0ef6acf4 100644 --- a/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java +++ b/opendaylight/config/yang-test/src/main/java/org/opendaylight/controller/config/yang/test/impl/TestImplModuleFactory.java @@ -1,18 +1,20 @@ /* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.config.yang.test.impl; - -/** +* 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 */ -public class TestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModuleFactory -{ - +/* +* Generated file +* +* Generated from: yang module name: config-test-impl yang module local name: impl +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Mon Mar 17 14:04:38 CET 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.controller.config.yang.test.impl; +public class TestImplModuleFactory extends org.opendaylight.controller.config.yang.test.impl.AbstractTestImplModuleFactory { } diff --git a/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml b/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml index fc0ef32954..f3fd230d5b 100644 --- a/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml +++ b/opendaylight/md-sal/compatibility/flow-management-compatibility/pom.xml @@ -30,9 +30,6 @@ org.eclipse.xtend xtend-maven-plugin - - maven-clean-plugin - diff --git a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/pom.xml b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/pom.xml index b7e193b59d..aef489ec83 100644 --- a/opendaylight/md-sal/compatibility/inventory-topology-compatibility/pom.xml +++ b/opendaylight/md-sal/compatibility/inventory-topology-compatibility/pom.xml @@ -31,9 +31,6 @@ org.eclipse.xtend xtend-maven-plugin - - maven-clean-plugin - diff --git a/opendaylight/md-sal/forwardingrules-manager/pom.xml b/opendaylight/md-sal/forwardingrules-manager/pom.xml index 00cbc18e7e..68eaa96871 100644 --- a/opendaylight/md-sal/forwardingrules-manager/pom.xml +++ b/opendaylight/md-sal/forwardingrules-manager/pom.xml @@ -31,9 +31,6 @@ org.eclipse.xtend xtend-maven-plugin - - maven-clean-plugin - diff --git a/opendaylight/md-sal/inventory-manager/pom.xml b/opendaylight/md-sal/inventory-manager/pom.xml index 362a349657..31621deeea 100644 --- a/opendaylight/md-sal/inventory-manager/pom.xml +++ b/opendaylight/md-sal/inventory-manager/pom.xml @@ -59,9 +59,6 @@ org.eclipse.xtend xtend-maven-plugin - - maven-clean-plugin - diff --git a/opendaylight/md-sal/model/pom.xml b/opendaylight/md-sal/model/pom.xml index 4c8a74c62b..a2a526426e 100644 --- a/opendaylight/md-sal/model/pom.xml +++ b/opendaylight/md-sal/model/pom.xml @@ -91,24 +91,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.7 - - - generate-sources - - add-source - - - - target/generated-sources/sal - - - - - diff --git a/opendaylight/md-sal/pom.xml b/opendaylight/md-sal/pom.xml index a45cadab7c..631f1118c5 100644 --- a/opendaylight/md-sal/pom.xml +++ b/opendaylight/md-sal/pom.xml @@ -86,23 +86,9 @@ - - IDE - - - m2e.version - - - - - target-ide - - - ${project.build.directory}/generated-sources/sal UTF-8 @@ -220,30 +206,6 @@ org.eclipse.xtend xtend-maven-plugin ${xtend.version} - - - - compile - - - ${basedir}/src/main/xtend-gen - - - - - - maven-clean-plugin - ${maven.clean.plugin.version} - - - - ${basedir}/src/main/xtend-gen - - ** - - - - org.jacoco @@ -311,27 +273,6 @@ org.apache.felix maven-bundle-plugin - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/config - ${project.build.directory}/generated-sources/sal - src/main/xtend-gen - - - - - org.apache.maven.plugins maven-jar-plugin diff --git a/opendaylight/md-sal/sal-binding-broker/pom.xml b/opendaylight/md-sal/sal-binding-broker/pom.xml index dafb3ef634..9976f48114 100644 --- a/opendaylight/md-sal/sal-binding-broker/pom.xml +++ b/opendaylight/md-sal/sal-binding-broker/pom.xml @@ -30,7 +30,7 @@ org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${project.build.directory}/generated-sources/config + ${jmxGeneratorPath} urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang @@ -72,28 +72,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - - - ${project.build.directory}/generated-sources/config - src/main/xtend-gen - - - - - org.apache.felix maven-bundle-plugin @@ -122,9 +100,6 @@ org.eclipse.xtend xtend-maven-plugin - - maven-clean-plugin - org.jacoco jacoco-maven-plugin diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java index 4f9c429e50..6334457fd4 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java @@ -21,6 +21,7 @@ import org.eclipse.xtext.xbase.lib.Exceptions; import org.opendaylight.controller.md.sal.common.api.TransactionStatus; import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException; import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation; import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction; import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction; @@ -108,27 +109,34 @@ public class AbstractForwardedTransaction currentArguments = new ArrayList<>(); - DataNormalizationOperation currentOp = codec.getDataNormalizer().getRootOperation(); - Iterator iterator = normalizedPath.getPath().iterator(); - while (iterator.hasNext()) { - PathArgument currentArg = iterator.next(); + List currentArguments = new ArrayList<>(); + DataNormalizationOperation currentOp = codec.getDataNormalizer().getRootOperation(); + Iterator iterator = normalizedPath.getPath().iterator(); + while (iterator.hasNext()) { + PathArgument currentArg = iterator.next(); + try { currentOp = currentOp.getChild(currentArg); - currentArguments.add(currentArg); - org.opendaylight.yangtools.yang.data.api.InstanceIdentifier currentPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier( - currentArguments); - boolean isPresent = writeTransaction.read(store, currentPath).get().isPresent(); - if (isPresent == false && iterator.hasNext()) { - writeTransaction.put(store, currentPath, currentOp.createDefault(currentArg)); - } + } catch (DataNormalizationException e) { + throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", path), e); + } + currentArguments.add(currentArg); + org.opendaylight.yangtools.yang.data.api.InstanceIdentifier currentPath = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier( + currentArguments); + + final Optional> d; + try { + d = writeTransaction.read(store, currentPath).get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Failed to read pre-existing data from store {} path {}", store, currentPath, e); + throw new IllegalStateException("Failed to read pre-existing data", e); + } + + if (!d.isPresent() && iterator.hasNext()) { + writeTransaction.put(store, currentPath, currentOp.createDefault(currentArg)); } - } catch (InterruptedException | ExecutionException e) { - e.printStackTrace(); } //LOG .info("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey()); writeTransaction.put(store, normalized.getKey(), normalized.getValue()); - } protected void doMerge(final DOMDataWriteTransaction writeTransaction, final LogicalDatastoreType store, diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeHelper.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeHelper.java new file mode 100644 index 0000000000..ea8b6c0972 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeHelper.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.codegen; + +import com.google.common.base.Objects; +import java.lang.reflect.Field; +import java.util.Map; +import org.eclipse.xtext.xbase.lib.Exceptions; +import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification; +import org.opendaylight.yangtools.yang.binding.BaseIdentity; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.RpcService; + +@SuppressWarnings("all") +public class RuntimeCodeHelper { + /** + * Helper method to return delegate from ManagedDirectedProxy with use of reflection. + * + * Note: This method uses reflection, but access to delegate field should be + * avoided and called only if neccessary. + */ + public static T getDelegate(final RpcService proxy) { + try { + Class _class = proxy.getClass(); + final Field field = _class.getField(RuntimeCodeSpecification.DELEGATE_FIELD); + boolean _equals = Objects.equal(field, null); + if (_equals) { + UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException("Unable to get delegate from proxy"); + throw _unsupportedOperationException; + } + try { + Object _get = field.get(proxy); + return ((T) _get); + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } catch (Throwable _e_1) { + throw Exceptions.sneakyThrow(_e_1); + } + } + + /** + * Helper method to set delegate to ManagedDirectedProxy with use of reflection. + * + * Note: This method uses reflection, but setting delegate field should not occur too much + * to introduce any significant performance hits. + */ + public static void setDelegate(final RpcService proxy, final RpcService delegate) { + try { + Class _class = proxy.getClass(); + final Field field = _class.getField(RuntimeCodeSpecification.DELEGATE_FIELD); + boolean _equals = Objects.equal(field, null); + if (_equals) { + UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException("Unable to set delegate to proxy"); + throw _unsupportedOperationException; + } + boolean _or = false; + boolean _equals_1 = Objects.equal(delegate, null); + if (_equals_1) { + _or = true; + } else { + Class _type = field.getType(); + Class _class_1 = delegate.getClass(); + boolean _isAssignableFrom = _type.isAssignableFrom(_class_1); + _or = (_equals_1 || _isAssignableFrom); + } + if (_or) { + field.set(proxy, delegate); + } else { + IllegalArgumentException _illegalArgumentException = new IllegalArgumentException("delegate class is not assignable to proxy"); + throw _illegalArgumentException; + } + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } + + /** + * Helper method to set delegate to ManagedDirectedProxy with use of reflection. + * + * Note: This method uses reflection, but setting delegate field should not occur too much + * to introduce any significant performance hits. + */ + public static void setDelegate(final Object proxy, final Object delegate) { + try { + Class _class = proxy.getClass(); + final Field field = _class.getField(RuntimeCodeSpecification.DELEGATE_FIELD); + boolean _equals = Objects.equal(field, null); + if (_equals) { + UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException("Unable to set delegate to proxy"); + throw _unsupportedOperationException; + } + boolean _or = false; + boolean _equals_1 = Objects.equal(delegate, null); + if (_equals_1) { + _or = true; + } else { + Class _type = field.getType(); + Class _class_1 = delegate.getClass(); + boolean _isAssignableFrom = _type.isAssignableFrom(_class_1); + _or = (_equals_1 || _isAssignableFrom); + } + if (_or) { + field.set(proxy, delegate); + } else { + IllegalArgumentException _illegalArgumentException = new IllegalArgumentException("delegate class is not assignable to proxy"); + throw _illegalArgumentException; + } + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } + + public static Map,? extends RpcService> getRoutingTable(final RpcService target, final Class tableClass) { + try { + Class _class = target.getClass(); + String _routingTableField = RuntimeCodeSpecification.getRoutingTableField(tableClass); + final Field field = _class.getField(_routingTableField); + boolean _equals = Objects.equal(field, null); + if (_equals) { + UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException( + "Unable to get routing table. Table field does not exists"); + throw _unsupportedOperationException; + } + try { + Object _get = field.get(target); + return ((Map,? extends RpcService>) _get); + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } catch (Throwable _e_1) { + throw Exceptions.sneakyThrow(_e_1); + } + } + + public static void setRoutingTable(final RpcService target, final Class tableClass, final Map,? extends RpcService> routingTable) { + try { + Class _class = target.getClass(); + String _routingTableField = RuntimeCodeSpecification.getRoutingTableField(tableClass); + final Field field = _class.getField(_routingTableField); + boolean _equals = Objects.equal(field, null); + if (_equals) { + UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException( + "Unable to set routing table. Table field does not exists"); + throw _unsupportedOperationException; + } + field.set(target, routingTable); + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeHelper.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeHelper.xtend deleted file mode 100644 index dff0d215b2..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeHelper.xtend +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.codegen - -import java.util.Map - -import org.opendaylight.yangtools.yang.binding.BaseIdentity -import org.opendaylight.yangtools.yang.binding.RpcService -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier - -import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification.* - -class RuntimeCodeHelper { - /** - * Helper method to return delegate from ManagedDirectedProxy with use of reflection. - * - * Note: This method uses reflection, but access to delegate field should be - * avoided and called only if neccessary. - * - */ - public static def getDelegate(RpcService proxy) { - val field = proxy.class.getField(DELEGATE_FIELD) - if (field == null) throw new UnsupportedOperationException("Unable to get delegate from proxy"); - return field.get(proxy) as T - } - - /** - * Helper method to set delegate to ManagedDirectedProxy with use of reflection. - * - * Note: This method uses reflection, but setting delegate field should not occur too much - * to introduce any significant performance hits. - * - */ - public static def void setDelegate(RpcService proxy, RpcService delegate) { - val field = proxy.class.getField(DELEGATE_FIELD) - if (field == null) throw new UnsupportedOperationException("Unable to set delegate to proxy"); - if (delegate == null || field.type.isAssignableFrom(delegate.class)) { - field.set(proxy, delegate) - } else - throw new IllegalArgumentException("delegate class is not assignable to proxy"); - } - - /** - * Helper method to set delegate to ManagedDirectedProxy with use of reflection. - * - * Note: This method uses reflection, but setting delegate field should not occur too much - * to introduce any significant performance hits. - * - */ - public static def void setDelegate(Object proxy, Object delegate) { - val field = proxy.class.getField(DELEGATE_FIELD) - if (field == null) throw new UnsupportedOperationException("Unable to set delegate to proxy"); - if (delegate == null || field.type.isAssignableFrom(delegate.class)) { - field.set(proxy, delegate) - } else - throw new IllegalArgumentException("delegate class is not assignable to proxy"); - } - - - public static def Map, ? extends RpcService> getRoutingTable(RpcService target, - Class tableClass) { - val field = target.class.getField(tableClass.routingTableField) - if (field == null) throw new UnsupportedOperationException( - "Unable to get routing table. Table field does not exists"); - return field.get(target) as Map, ? extends RpcService>; - } - - public static def void setRoutingTable(RpcService target, Class tableClass, - Map, ? extends RpcService> routingTable) { - val field = target.class.getField(tableClass.routingTableField) - if (field == null) throw new UnsupportedOperationException( - "Unable to set routing table. Table field does not exists"); - field.set(target,routingTable); - } - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.java new file mode 100644 index 0000000000..0bc11d9b35 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + + +package org.opendaylight.controller.sal.binding.codegen; + +import java.lang.reflect.Method; +import org.opendaylight.yangtools.yang.binding.Notification; + +@SuppressWarnings("all") +public class YangtoolsMappingHelper { + public static boolean isNotificationCallback(final Method it) { + return it.getName().startsWith("on") && (it.getParameterTypes().length == 1) && + Notification.class.isAssignableFrom(it.getParameterTypes()[0]); + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.xtend deleted file mode 100644 index 18d3e26346..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.xtend +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.codegen - -import java.lang.reflect.Method -import org.opendaylight.yangtools.yang.binding.Notification - -public static class YangtoolsMappingHelper { - - public static def boolean isNotificationCallback(Method it) { - return name.startsWith("on") && parameterTypes.size === 1 && - Notification.isAssignableFrom(parameterTypes.get(0)) - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/BrokerImplClassLoader.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/BrokerImplClassLoader.java new file mode 100644 index 0000000000..cab4fe90e0 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/BrokerImplClassLoader.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + + +package org.opendaylight.controller.sal.binding.codegen.impl; + +import org.eclipse.xtext.xbase.lib.Exceptions; + +@SuppressWarnings("all") +public class BrokerImplClassLoader extends ClassLoader { + private final ClassLoader spiClassLoader; + + public BrokerImplClassLoader(final ClassLoader model, final ClassLoader spi) { + super(model); + this.spiClassLoader = spi; + } + + public Class loadClass(final String name) throws ClassNotFoundException { + try { + return super.loadClass(name); + } catch (ClassNotFoundException e) { + return this.spiClassLoader.loadClass(name); + } + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/BrokerImplClassLoader.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/BrokerImplClassLoader.xtend deleted file mode 100644 index 6481c9d1b4..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/BrokerImplClassLoader.xtend +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.codegen.impl - -import java.lang.ClassLoader - -class BrokerImplClassLoader extends ClassLoader { - - val ClassLoader spiClassLoader - - public new(ClassLoader model, ClassLoader spi) { - super(model) - spiClassLoader = spi; - } - - override public loadClass(String name) throws ClassNotFoundException { - try { - return super.loadClass(name); - } catch (ClassNotFoundException e) { - return spiClassLoader.loadClass(name); - } - } - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend index fe2681f1f7..6d675b4b5e 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend @@ -60,7 +60,7 @@ class NotificationBrokerImpl implements NotificationProviderService, AutoCloseab override publish(Notification notification, ExecutorService service) { val allTypes = notification.notificationTypes - var Iterable> listenerToNotify = Collections.emptySet(); + var Iterable> listenerToNotify = Collections.emptySet(); for (type : allTypes) { listenerToNotify = listenerToNotify + listeners.get(type as Class) } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProxyContext.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProxyContext.java new file mode 100644 index 0000000000..3b6a2539de --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProxyContext.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.sal.binding.impl; + +import org.opendaylight.yangtools.yang.binding.RpcService; +import org.osgi.framework.ServiceRegistration; + +@SuppressWarnings("all") +public class RpcProxyContext { + public RpcProxyContext(final Class proxyClass) { + this.proxyClass = proxyClass; + } + + protected final Class proxyClass; + + protected RpcService _proxy; + + public RpcService getProxy() { + return this._proxy; + } + + public void setProxy(final RpcService proxy) { + this._proxy = proxy; + } + + protected ServiceRegistration _registration; + + public ServiceRegistration getRegistration() { + return this._registration; + } + + public void setRegistration(final ServiceRegistration registration) { + this._registration = registration; + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProxyContext.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProxyContext.xtend deleted file mode 100644 index 07494599f8..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProxyContext.xtend +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.impl - -import org.opendaylight.yangtools.yang.binding.RpcService -import org.osgi.framework.ServiceRegistration - -class RpcProxyContext { - - new(Class proxyClass) { - this.proxyClass = proxyClass - } - - protected val Class proxyClass; - - @Property - protected var RpcService proxy; - - @Property - protected var ServiceRegistration registration; -} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java index 9edea0c2fd..93849c2e91 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java @@ -91,6 +91,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; public class BindingIndependentConnector implements // RuntimeDataProvider, // @@ -699,8 +700,9 @@ public class BindingIndependentConnector implements // } } + @Override - public RpcResult invokeRpc(final QName rpc, final CompositeNode domInput) { + public ListenableFuture> invokeRpc(final QName rpc, final CompositeNode domInput) { checkArgument(rpc != null); checkArgument(domInput != null); @@ -709,10 +711,11 @@ public class BindingIndependentConnector implements // RpcService rpcService = baRpcRegistry.getRpcService(rpcType); checkState(rpcService != null); CompositeNode domUnwrappedInput = domInput.getFirstCompositeByName(QName.create(rpc, "input")); + try { - return resolveInvocationStrategy(rpc).invokeOn(rpcService, domUnwrappedInput); + return Futures.immediateFuture(resolveInvocationStrategy(rpc).invokeOn(rpcService, domUnwrappedInput)); } catch (Exception e) { - throw new IllegalStateException(e); + return Futures.immediateFailedFuture(e); } } @@ -813,21 +816,25 @@ public class BindingIndependentConnector implements // } @Override - public Future> forwardToDomBroker(final DataObject input) { - if(biRpcRegistry != null) { - CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); - RpcResult result = biRpcRegistry.invokeRpc(rpc, wrappedXml); - Object baResultValue = null; - if (result.getResult() != null) { - baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), result.getResult()); - } - RpcResult baResult = Rpcs.getRpcResult(result.isSuccessful(), baResultValue, result.getErrors()); - return Futures.> immediateFuture(baResult); + public ListenableFuture> forwardToDomBroker(final DataObject input) { + if(biRpcRegistry == null) { + return Futures.> immediateFuture(Rpcs.getRpcResult(false)); } - return Futures.> immediateFuture(Rpcs.getRpcResult(false)); - } + CompositeNode xml = mappingService.toDataDom(input); + CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); + + return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), new Function, RpcResult>() { + @Override + public RpcResult apply(RpcResult input) { + Object baResultValue = null; + if (input.getResult() != null) { + baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), input.getResult()); + } + return Rpcs.getRpcResult(input.isSuccessful(), baResultValue, input.getErrors()); + } + }); + } } private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy { @@ -876,18 +883,21 @@ public class BindingIndependentConnector implements // } @Override - public Future> forwardToDomBroker(final DataObject input) { - if(biRpcRegistry != null) { - CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.>of(xml)); - RpcResult result = biRpcRegistry.invokeRpc(rpc, wrappedXml); - Object baResultValue = null; - RpcResult baResult = Rpcs.getRpcResult(result.isSuccessful(), null, result.getErrors()); - return Futures.>immediateFuture(baResult); + public ListenableFuture> forwardToDomBroker(final DataObject input) { + if(biRpcRegistry == null) { + return Futures.> immediateFuture(Rpcs.getRpcResult(false)); } - return Futures.>immediateFuture(Rpcs.getRpcResult(false)); - } + CompositeNode xml = mappingService.toDataDom(input); + CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.>of(xml)); + + return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), new Function, RpcResult>() { + @Override + public RpcResult apply(RpcResult input) { + return Rpcs.getRpcResult(input.isSuccessful(), null, input.getErrors()); + } + }); + } } public boolean isRpcForwarding() { diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/BindingAwareDataReaderRouter.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/BindingAwareDataReaderRouter.java new file mode 100644 index 0000000000..b0316635e2 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/BindingAwareDataReaderRouter.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.impl.util; + +import java.util.Iterator; +import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +@SuppressWarnings("all") +public class BindingAwareDataReaderRouter extends AbstractDataReadRouter,DataObject> { + protected DataObject merge(final InstanceIdentifier path, final Iterable data) { + return data.iterator().next(); + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/BindingAwareDataReaderRouter.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/BindingAwareDataReaderRouter.xtend deleted file mode 100644 index 5b775806d5..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/BindingAwareDataReaderRouter.xtend +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.impl.util - -import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yangtools.yang.binding.DataObject - -class BindingAwareDataReaderRouter extends AbstractDataReadRouter, DataObject> { - - override protected merge(InstanceIdentifier path, Iterable data) { - return data.iterator.next; - } - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/MapUtils.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/MapUtils.java new file mode 100644 index 0000000000..aa6a9a21e5 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/MapUtils.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.sal.binding.impl.util; + +import com.google.common.collect.Multimap; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map.Entry; +import org.opendaylight.yangtools.concepts.Path; + +@SuppressWarnings("all") +public class MapUtils { + public static

, V extends Object> Collection> getAllChildren(final Multimap map, final P path) { + HashSet> _hashSet = new HashSet>(); + final HashSet> ret = _hashSet; + final Collection> entries = map.entries(); + for (final Entry entry : entries) { + { + final P currentPath = entry.getKey(); + if (path.contains(currentPath)) { + ret.add(entry); + } else if (currentPath.contains(path)){ + ret.add(entry); + } + } + } + return ret; + } +} + diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/MapUtils.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/MapUtils.xtend deleted file mode 100644 index c60686d209..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/MapUtils.xtend +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.impl.util - -import com.google.common.collect.Multimap -import java.util.Collection -import java.util.HashSet -import java.util.Map.Entry -import org.opendaylight.yangtools.concepts.Path - -class MapUtils { - - public static def

, V> Collection> getAllChildren( - Multimap map, P path) { - val ret = new HashSet(); - val entries = map.entries; - - for (entry : entries) { - val currentPath = entry.key; - // If the registered reader processes nested elements - if (path.contains(currentPath)) { - ret.add(entry); - } else if(currentPath.contains(path)) { - // If the registered reader is parent of entry - ret.add(entry); - } - } - - return ret; - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java index 4bad2bbb86..d6d87bac84 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java @@ -351,7 +351,6 @@ public class BindingTestContext implements AutoCloseable, SchemaContextProvider private void startDomBroker() { checkState(executor != null); biBrokerImpl = new BrokerImpl(); - biBrokerImpl.setExecutor(executor); biBrokerImpl.setRouter(new SchemaAwareRpcBroker("/", this)); } diff --git a/opendaylight/md-sal/sal-binding-config/pom.xml b/opendaylight/md-sal/sal-binding-config/pom.xml index 145dc37552..f75995dc22 100644 --- a/opendaylight/md-sal/sal-binding-config/pom.xml +++ b/opendaylight/md-sal/sal-binding-config/pom.xml @@ -43,7 +43,7 @@ org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${project.build.directory}/generated-sources/config + ${jmxGeneratorPath} urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang @@ -73,25 +73,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/config - - - - - diff --git a/opendaylight/md-sal/sal-binding-dom-it/pom.xml b/opendaylight/md-sal/sal-binding-dom-it/pom.xml index 82e3d97572..94832c14b6 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/pom.xml +++ b/opendaylight/md-sal/sal-binding-dom-it/pom.xml @@ -19,9 +19,6 @@ org.eclipse.xtend xtend-maven-plugin - - maven-clean-plugin - org.jacoco jacoco-maven-plugin diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerRpcTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerRpcTest.java index b1547b66a7..ca38ed0797 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerRpcTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerRpcTest.java @@ -50,6 +50,7 @@ import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.MoreExecutors; public class CrossBrokerRpcTest { @@ -64,7 +65,7 @@ public class CrossBrokerRpcTest { public static final NodeId NODE_B = new NodeId("b"); public static final NodeId NODE_C = new NodeId("c"); public static final NodeId NODE_D = new NodeId("d"); - + private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id"); private static final QName ADD_FLOW_QNAME = QName.create(NodeFlowRemoved.QNAME, "add-flow"); @@ -78,7 +79,7 @@ public class CrossBrokerRpcTest { public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier BI_NODE_C_ID = createBINodeIdentifier(NODE_C); public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier BI_NODE_D_ID = createBINodeIdentifier(NODE_D); - + @Before public void setup() { @@ -99,7 +100,7 @@ public class CrossBrokerRpcTest { } @Test - public void bindingRoutedRpcProvider_DomInvokerTest() { + public void bindingRoutedRpcProvider_DomInvokerTest() throws Exception { flowService// .registerPath(NodeContext.class, BA_NODE_A_ID) // @@ -114,7 +115,7 @@ public class CrossBrokerRpcTest { CompositeNode addFlowDom = toDomRpc(ADD_FLOW_QNAME, addFlowA); assertNotNull(addFlowDom); - RpcResult domResult = biRpcInvoker.invokeRpc(ADD_FLOW_QNAME, addFlowDom); + RpcResult domResult = biRpcInvoker.invokeRpc(ADD_FLOW_QNAME, addFlowDom).get(); assertNotNull(domResult); assertTrue("DOM result is successful.", domResult.isSuccessful()); assertTrue("Bidning Add Flow RPC was captured.", flowService.getReceivedAddFlows().containsKey(BA_NODE_A_ID)); @@ -128,18 +129,18 @@ public class CrossBrokerRpcTest { final AddFlowOutput output = builder.build(); org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration registration = biRpcRegistry.addRoutedRpcImplementation(ADD_FLOW_QNAME, new RpcImplementation() { @Override - public RpcResult invokeRpc(QName rpc, CompositeNode input) { - CompositeNode result = testContext.getBindingToDomMappingService().toDataDom(output); - return Rpcs.getRpcResult(true, result, ImmutableList.of()); + public Set getSupportedRpcs() { + return ImmutableSet.of(ADD_FLOW_QNAME); } @Override - public Set getSupportedRpcs() { - return ImmutableSet.of(ADD_FLOW_QNAME); + public ListenableFuture> invokeRpc(QName rpc, CompositeNode input) { + CompositeNode result = testContext.getBindingToDomMappingService().toDataDom(output); + return Futures.immediateFuture(Rpcs.getRpcResult(true, result, ImmutableList.of())); } }); registration.registerPath(NodeContext.QNAME, BI_NODE_C_ID); - + SalFlowService baFlowInvoker = baRpcRegistry.getRpcService(SalFlowService.class); Future> baResult = baFlowInvoker.addFlow(addFlow(BA_NODE_C_ID).setPriority(500).build()); assertNotNull(baResult); diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationException.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationException.java new file mode 100644 index 0000000000..f7a15b614e --- /dev/null +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationException.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.common.impl.util.compat; + +public class DataNormalizationException extends Exception { + private static final long serialVersionUID = 1L; + + public DataNormalizationException(String message) { + super(message); + } + + public DataNormalizationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java index 941f2fdb39..1055fa81fd 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ package org.opendaylight.controller.md.sal.common.impl.util.compat; import static com.google.common.base.Preconditions.checkArgument; @@ -70,9 +77,9 @@ public abstract class DataNormalizationOperation impleme return Collections.singleton(identifier.getNodeType()); } - public abstract DataNormalizationOperation getChild(final PathArgument child); + public abstract DataNormalizationOperation getChild(final PathArgument child) throws DataNormalizationException; - public abstract DataNormalizationOperation getChild(QName child); + public abstract DataNormalizationOperation getChild(QName child) throws DataNormalizationException; public abstract NormalizedNode normalize(Node legacyData); @@ -162,7 +169,13 @@ public abstract class DataNormalizationOperation impleme Set> usedMixins = new HashSet<>(); for (Node childLegacy : compositeNode.getValue()) { - DataNormalizationOperation childOp = getChild(childLegacy.getNodeType()); + final DataNormalizationOperation childOp; + + try { + childOp = getChild(childLegacy.getNodeType()); + } catch (DataNormalizationException e) { + throw new IllegalArgumentException(String.format("Failed to normalize data %s", compositeNode.getValue()), e); + } // We skip unknown nodes if this node is mixin since // it's nodes and parent nodes are interleaved @@ -175,8 +188,7 @@ public abstract class DataNormalizationOperation impleme if (childOp.isMixin()) { if (usedMixins.contains(childOp)) { // We already run / processed that mixin, so to avoid - // dupliciry we are - // skiping next nodes. + // duplicity we are skipping next nodes. continue; } builder.addChild(childOp.normalize(compositeNode)); @@ -208,7 +220,7 @@ public abstract class DataNormalizationOperation impleme } @Override - public DataNormalizationOperation getChild(final PathArgument child) { + public DataNormalizationOperation getChild(final PathArgument child) throws DataNormalizationException { DataNormalizationOperation potential = byArg.get(child); if (potential != null) { return potential; @@ -218,7 +230,7 @@ public abstract class DataNormalizationOperation impleme } @Override - public DataNormalizationOperation getChild(final QName child) { + public DataNormalizationOperation getChild(final QName child) throws DataNormalizationException { DataNormalizationOperation potential = byQName.get(child); if (potential != null) { return potential; @@ -486,15 +498,19 @@ public abstract class DataNormalizationOperation impleme } } - public static DataNormalizationOperation fromSchemaAndPathArgument(final DataNodeContainer schema, - final QName child) { + private static DataNormalizationOperation fromSchemaAndPathArgument(final DataNodeContainer schema, + final QName child) throws DataNormalizationException { DataSchemaNode potential = schema.getDataChildByName(child); if (potential == null) { Iterable choices = FluentIterable.from( schema.getChildNodes()).filter(org.opendaylight.yangtools.yang.model.api.ChoiceNode.class); potential = findChoice(choices, child); } - checkArgument(potential != null, "Supplied QName %s is not valid according to schema %s", child, schema); + + if (potential == null) { + throw new DataNormalizationException(String.format("Supplied QName %s is not valid according to schema %s", child, schema)); + } + if ((schema instanceof DataSchemaNode) && !((DataSchemaNode) schema).isAugmenting() && potential.isAugmenting()) { return fromAugmentation(schema, (AugmentationTarget) schema, potential); } @@ -541,7 +557,7 @@ public abstract class DataNormalizationOperation impleme } } - private static DataNormalizationOperation fromSchema(final DataNodeContainer schema, final PathArgument child) { + private static DataNormalizationOperation fromSchema(final DataNodeContainer schema, final PathArgument child) throws DataNormalizationException { if (child instanceof AugmentationIdentifier) { return fromSchemaAndPathArgument(schema, ((AugmentationIdentifier) child).getPossibleChildNames() .iterator().next()); diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java index 28b2bde26d..e1fc3c3cdb 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ package org.opendaylight.controller.md.sal.common.impl.util.compat; import static com.google.common.base.Preconditions.checkArgument; @@ -7,6 +14,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.Map; +import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; @@ -44,18 +52,24 @@ public class DataNormalizer { DataNormalizationOperation currentOp = operation; Iterator arguments = legacy.getPath().iterator(); - while ( arguments.hasNext() ) { - PathArgument legacyArg = arguments.next(); - currentOp = currentOp.getChild(legacyArg); - checkArgument(currentOp != null, "Legacy Instance Identifier %s is not correct. Normalized Instance Identifier so far %s",legacy,normalizedArgs.build()); - while (currentOp.isMixin()) { - normalizedArgs.add(currentOp.getIdentifier()); - currentOp = currentOp.getChild(legacyArg.getNodeType()); - } - if(arguments.hasNext() || (!currentOp.isKeyedEntry() || legacyArg instanceof NodeIdentifierWithPredicates || legacyArg instanceof NodeWithValue)) { - normalizedArgs.add(legacyArg); + + try { + while ( arguments.hasNext() ) { + PathArgument legacyArg = arguments.next(); + currentOp = currentOp.getChild(legacyArg); + checkArgument(currentOp != null, "Legacy Instance Identifier %s is not correct. Normalized Instance Identifier so far %s",legacy,normalizedArgs.build()); + while (currentOp.isMixin()) { + normalizedArgs.add(currentOp.getIdentifier()); + currentOp = currentOp.getChild(legacyArg.getNodeType()); + } + if(arguments.hasNext() || (!currentOp.isKeyedEntry() || legacyArg instanceof NodeIdentifierWithPredicates || legacyArg instanceof NodeWithValue)) { + normalizedArgs.add(legacyArg); + } } + } catch (DataNormalizationException e) { + throw new IllegalArgumentException(String.format("Failed to normalize path %s", legacy), e); } + return new InstanceIdentifier(normalizedArgs.build()); } @@ -69,12 +83,24 @@ public class DataNormalizer { DataNormalizationOperation currentOp = operation; for (PathArgument arg : normalizedPath.getPath()) { - currentOp = currentOp.getChild(arg); + try { + currentOp = currentOp.getChild(arg); + } catch (DataNormalizationException e) { + throw new IllegalArgumentException(String.format("Failed to validate normalized path %s", normalizedPath), e); + } } - // Write Augmentaiton data resolution + + // Write Augmentation data resolution if (legacyData.getChildren().size() == 1) { - DataNormalizationOperation potentialOp = currentOp.getChild(legacyData.getChildren().get(0) - .getNodeType()); + final DataNormalizationOperation potentialOp; + + try { + final QName childType = legacyData.getChildren().get(0).getNodeType(); + potentialOp = currentOp.getChild(childType); + } catch (DataNormalizationException e) { + throw new IllegalArgumentException(String.format("Failed to get child operation for %s", legacyData), e); + } + if(potentialOp.getIdentifier() instanceof AugmentationIdentifier) { currentOp = potentialOp; ArrayList reworkedArgs = new ArrayList<>(normalizedPath.getPath()); diff --git a/opendaylight/md-sal/sal-dom-api/pom.xml b/opendaylight/md-sal/sal-dom-api/pom.xml index 15932d56ce..181fc5c0c5 100644 --- a/opendaylight/md-sal/sal-dom-api/pom.xml +++ b/opendaylight/md-sal/sal-dom-api/pom.xml @@ -33,7 +33,7 @@ org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${project.build.directory}/generated-sources/config + ${jmxGeneratorPath} urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang @@ -79,25 +79,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/config - - - - - diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RoutedRpcDefaultImplementation.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RoutedRpcDefaultImplementation.java index c8eb7fd56f..4f11ba0661 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RoutedRpcDefaultImplementation.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RoutedRpcDefaultImplementation.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ package org.opendaylight.controller.sal.core.api; import org.opendaylight.yangtools.yang.common.QName; @@ -5,8 +12,10 @@ import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import com.google.common.util.concurrent.ListenableFuture; + public interface RoutedRpcDefaultImplementation { - public RpcResult invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input); + ListenableFuture> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input); } diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcImplementation.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcImplementation.java index 6b1030a815..38b33d5d2a 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcImplementation.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/RpcImplementation.java @@ -15,6 +15,8 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import com.google.common.util.concurrent.ListenableFuture; + /** * {@link Provider}'s implementation of an RPC. * @@ -42,8 +44,6 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode; * {@link RpcResult} *

  • {@link Broker} returns the {@link RpcResult} to {@link Consumer} * - * - * */ public interface RpcImplementation extends Provider.ProviderFunctionality { @@ -59,13 +59,12 @@ public interface RpcImplementation extends Provider.ProviderFunctionality { Set getSupportedRpcs(); /** - * Invokes a implementation of specified rpc. - * + * Invokes a implementation of specified RPC asynchronously. * * @param rpc - * Rpc to be invoked + * RPC to be invoked * @param input - * Input data for rpc. + * Input data for the RPC. * * @throws IllegalArgumentException *
      @@ -73,9 +72,9 @@ public interface RpcImplementation extends Provider.ProviderFunctionality { *
    • If input is not null and * false == rpc.equals(input.getNodeType) *
    - * @return RpcResult containing the output of rpc if was executed - * successfully, the list of errors otherwise. + * @return Future promising an RpcResult containing the output of + * the RPC if was executed successfully, the list of errors + * otherwise. */ - RpcResult invokeRpc(QName rpc, CompositeNode input); - + ListenableFuture> invokeRpc(QName rpc, CompositeNode input); } diff --git a/opendaylight/md-sal/sal-dom-broker/pom.xml b/opendaylight/md-sal/sal-dom-broker/pom.xml index 5063e4339b..360988fbb2 100644 --- a/opendaylight/md-sal/sal-dom-broker/pom.xml +++ b/opendaylight/md-sal/sal-dom-broker/pom.xml @@ -84,7 +84,7 @@ org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${project.build.directory}/generated-sources/config + ${jmxGeneratorPath} urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang @@ -156,26 +156,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/config - src/main/xtend-gen - - - - - org.eclipse.xtend xtend-maven-plugin diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleTransaction.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleTransaction.java index fce2494554..b905d2f673 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleTransaction.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleTransaction.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ package org.opendaylight.controller.md.sal.dom.broker.impl.compat; import static com.google.common.base.Preconditions.checkNotNull; @@ -14,6 +21,7 @@ import java.util.concurrent.Future; import org.opendaylight.controller.md.sal.common.api.TransactionStatus; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException; import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation; import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer; import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction; @@ -232,7 +240,11 @@ public abstract class BackwardsCompatibleTransaction iterator = normalizedPath.getPath().iterator(); while(iterator.hasNext()) { PathArgument currentArg = iterator.next(); - currentOp = currentOp.getChild(currentArg); + try { + currentOp = currentOp.getChild(currentArg); + } catch (DataNormalizationException e) { + throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", normalizedPath), e); + } currentArguments.add(currentArg); InstanceIdentifier currentPath = new InstanceIdentifier(currentArguments); boolean isPresent = getDelegate().read(store, currentPath).get().isPresent(); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.xtend index 64de8683d1..0ed14c1027 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.xtend +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.xtend @@ -7,13 +7,11 @@ */ package org.opendaylight.controller.sal.dom.broker; +import com.google.common.util.concurrent.ListenableFuture import java.util.Collections import java.util.HashSet import java.util.Set -import java.util.concurrent.Callable -import java.util.concurrent.ExecutorService -import java.util.concurrent.Executors -import java.util.concurrent.Future +import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener import org.opendaylight.controller.sal.core.api.Broker import org.opendaylight.controller.sal.core.api.Consumer import org.opendaylight.controller.sal.core.api.Provider @@ -26,7 +24,6 @@ import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter import org.opendaylight.controller.sal.core.api.RpcRegistrationListener import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry import org.opendaylight.controller.sal.core.api.RpcImplementation -import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener import org.opendaylight.controller.sal.core.api.RpcRoutingContext import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation @@ -39,12 +36,9 @@ public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable { private val Set providerSessions = Collections.synchronizedSet( new HashSet()); - // Implementation specific - @Property - private var ExecutorService executor = Executors.newFixedThreadPool(5); @Property private var BundleContext bundleContext; - + @Property private var AutoCloseable deactivator; @@ -69,9 +63,8 @@ public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable { return session; } - protected def Future> invokeRpcAsync(QName rpc, CompositeNode input) { - val result = executor.submit([|router.invokeRpc(rpc, input)] as Callable>); - return result; + protected def ListenableFuture> invokeRpcAsync(QName rpc, CompositeNode input) { + return router.invokeRpc(rpc, input); } // Validation @@ -111,15 +104,15 @@ public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable { sessions.remove(consumerContextImpl); providerSessions.remove(consumerContextImpl); } - + override close() throws Exception { deactivator?.close(); } - + override addRpcImplementation(QName rpcType, RpcImplementation implementation) throws IllegalArgumentException { router.addRpcImplementation(rpcType,implementation); } - + override addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) { router.addRoutedRpcImplementation(rpcType,implementation); } @@ -131,17 +124,17 @@ public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable { override addRpcRegistrationListener(RpcRegistrationListener listener) { return router.addRpcRegistrationListener(listener); } - + override > registerRouteChangeListener(L listener) { return router.registerRouteChangeListener(listener); } - override invokeRpc(QName rpc,CompositeNode input){ - return router.invokeRpc(rpc,input) - } - override getSupportedRpcs() { return router.getSupportedRpcs(); } - + + override invokeRpc(QName rpc, CompositeNode input) { + return router.invokeRpc(rpc,input) + } + } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java index f9f977e3c2..263f0500fd 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java @@ -123,9 +123,8 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv return rpcs.getSupportedRpcs(); } - @Override - public RpcResult invokeRpc(QName rpc, CompositeNode input) { + public ListenableFuture> invokeRpc(QName rpc, CompositeNode input) { return rpcs.invokeRpc(rpc, input); } @@ -134,7 +133,6 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv return rpcs.addRpcRegistrationListener(listener); } - @Override public ListenableFuture> rpc(QName type, CompositeNode input) { return null; @@ -228,6 +226,4 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv L listener) { return rpcs.registerRouteChangeListener(listener); } - - } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareRpcBroker.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareRpcBroker.java index 598361c3ae..3e7b115f11 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareRpcBroker.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareRpcBroker.java @@ -46,6 +46,7 @@ import com.google.common.base.Optional; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.util.concurrent.ListenableFuture; public class SchemaAwareRpcBroker implements RpcRouter, Identifiable, RoutedRpcDefaultImplementation { @@ -85,16 +86,16 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable, Ro this.schemaProvider = schemaProvider; } - public RoutedRpcDefaultImplementation getRoutedRpcDefaultDelegate() { - return defaultDelegate; - } + public RoutedRpcDefaultImplementation getRoutedRpcDefaultDelegate() { + return defaultDelegate; + } @Override - public void setRoutedRpcDefaultDelegate(RoutedRpcDefaultImplementation defaultDelegate) { - this.defaultDelegate = defaultDelegate; - } + public void setRoutedRpcDefaultDelegate(RoutedRpcDefaultImplementation defaultDelegate) { + this.defaultDelegate = defaultDelegate; + } - @Override + @Override public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) { checkArgument(rpcType != null, "RPC Type should not be null"); checkArgument(implementation != null, "RPC Implementatoin should not be null"); @@ -163,7 +164,7 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable, Ro } @Override - public RpcResult invokeRpc(QName rpc, CompositeNode input) { + public ListenableFuture> invokeRpc(QName rpc, CompositeNode input) { return findRpcImplemention(rpc).invokeRpc(rpc, input); } @@ -235,7 +236,7 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable, Ro } @Override - public RpcResult invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) { + public ListenableFuture> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) { checkState(defaultDelegate != null); return defaultDelegate.invokeRpc(rpc, identifier, input); } @@ -319,7 +320,7 @@ public class SchemaAwareRpcBroker implements RpcRouter, Identifiable, Ro } @Override - public RpcResult invokeRpc(QName rpc, CompositeNode input) { + public ListenableFuture> invokeRpc(QName rpc, CompositeNode input) { CompositeNode inputContainer = input.getFirstCompositeByName(QName.create(rpc,"input")); checkArgument(inputContainer != null, "Rpc payload must contain input element"); SimpleNode routeContainer = inputContainer.getFirstSimpleByName(strategy.getLeaf()); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/RpcProvisionRegistryProxy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/RpcProvisionRegistryProxy.java index 40842c004a..6e44cba494 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/RpcProvisionRegistryProxy.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/RpcProvisionRegistryProxy.java @@ -8,6 +8,8 @@ package org.opendaylight.controller.sal.dom.broker.osgi; +import java.util.Set; + import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; import org.opendaylight.controller.sal.core.api.*; import org.opendaylight.yangtools.concepts.ListenerRegistration; @@ -17,7 +19,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.osgi.framework.ServiceReference; -import java.util.Set; +import com.google.common.util.concurrent.ListenableFuture; public class RpcProvisionRegistryProxy extends AbstractBrokerServiceProxy implements RpcProvisionRegistry { @@ -41,24 +43,23 @@ public class RpcProvisionRegistryProxy extends AbstractBrokerServiceProxy> ListenerRegistration registerRouteChangeListener(L listener) { return getDelegate().registerRouteChangeListener(listener); } + @Override + public Set getSupportedRpcs() { + return getDelegate().getSupportedRpcs(); + } - @Override - public Set getSupportedRpcs() { - return getDelegate().getSupportedRpcs(); - } - - @Override - public RpcResult invokeRpc(QName rpc, CompositeNode input) { - return getDelegate().invokeRpc(rpc,input); - } + @Override + public ListenableFuture> invokeRpc(QName rpc, CompositeNode input) { + return getDelegate().invokeRpc(rpc, input); + } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/spi/RoutedRpcProcessor.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/spi/RoutedRpcProcessor.java index 02419ff529..2976c76ffa 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/spi/RoutedRpcProcessor.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/spi/RoutedRpcProcessor.java @@ -8,27 +8,20 @@ package org.opendaylight.controller.sal.dom.broker.spi; import java.util.Map; -import java.util.Set; import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration; import org.opendaylight.controller.sal.core.api.RpcImplementation; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; public interface RoutedRpcProcessor extends RpcImplementation { - public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation); + RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation); - public Set getSupportedRpcs(); - - public QName getRpcType(); - - public RpcResult invokeRpc(QName rpc, CompositeNode input); + QName getRpcType(); Map getRoutes(); - + RpcImplementation getDefaultRoute(); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/spi/RpcRouter.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/spi/RpcRouter.java index d1523a01d6..b19dac5535 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/spi/RpcRouter.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/spi/RpcRouter.java @@ -14,8 +14,6 @@ import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration; import org.opendaylight.controller.sal.core.api.RpcImplementation; import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.RpcResult; -import org.opendaylight.yangtools.yang.data.api.CompositeNode; public interface RpcRouter extends RpcProvisionRegistry, RpcImplementation { @@ -28,7 +26,4 @@ public interface RpcRouter extends RpcProvisionRegistry, RpcImplementation { @Override public Set getSupportedRpcs(); - - @Override - public RpcResult invokeRpc(QName rpc, CompositeNode input); } diff --git a/opendaylight/md-sal/sal-netconf-connector/pom.xml b/opendaylight/md-sal/sal-netconf-connector/pom.xml index 182441d3f5..ae819b0f78 100644 --- a/opendaylight/md-sal/sal-netconf-connector/pom.xml +++ b/opendaylight/md-sal/sal-netconf-connector/pom.xml @@ -204,7 +204,7 @@ org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${project.build.directory}/generated-sources/config + ${jmxGeneratorPath} urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang @@ -235,27 +235,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/config - src/main/xtend-gen - - - - - - org.eclipse.xtend xtend-maven-plugin diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java index 5c6702ae64..e6dc59cc10 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java @@ -14,9 +14,11 @@ import java.util.Date; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class InventoryUtils { - + private static final Logger LOG = LoggerFactory.getLogger(InventoryUtils.class); private static final URI INVENTORY_NAMESPACE = URI.create("urn:opendaylight:inventory"); private static final URI NETCONF_INVENTORY_NAMESPACE = URI.create("urn:opendaylight:netconf-node-inventory"); private static final Date INVENTORY_REVISION = dateFromString("2013-08-19"); @@ -33,18 +35,23 @@ public class InventoryUtils { .toInstance(); public static final QName NETCONF_INVENTORY_MOUNT = null; + private InventoryUtils() { + throw new UnsupportedOperationException("Utility class cannot be instantiated"); + } + /** * Converts date in string format yyyy-MM-dd to java.util.Date. - * + * * @return java.util.Date conformant to string formatted date yyyy-MM-dd. */ private static Date dateFromString(final String date) { + // We do not reuse the formatter because it's not thread-safe SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); try { return formatter.parse(date); } catch (ParseException e) { - e.printStackTrace(); + LOG.error("Failed to parse date {}", date, e); + return null; } - return null; } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend index 4ae84c7d31..12e8b5587c 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend @@ -13,19 +13,18 @@ import io.netty.util.concurrent.EventExecutor import java.io.InputStream import java.net.InetSocketAddress import java.net.URI +import java.util.ArrayList +import java.util.Collection import java.util.Collections import java.util.List import java.util.Set import java.util.concurrent.ExecutorService -import java.util.concurrent.Future import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler import org.opendaylight.controller.md.sal.common.api.data.DataModification import org.opendaylight.controller.md.sal.common.api.data.DataReader -import org.opendaylight.controller.netconf.api.NetconfMessage -import org.opendaylight.controller.netconf.client.NetconfClient import org.opendaylight.controller.netconf.client.NetconfClientDispatcher -import org.opendaylight.controller.netconf.util.xml.XmlUtil import org.opendaylight.controller.sal.core.api.Broker.ProviderSession +import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration import org.opendaylight.controller.sal.core.api.Provider import org.opendaylight.controller.sal.core.api.RpcImplementation import org.opendaylight.controller.sal.core.api.data.DataBrokerService @@ -45,7 +44,6 @@ import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl import org.opendaylight.yangtools.yang.model.api.SchemaContext import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider -import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl import org.opendaylight.yangtools.yang.parser.impl.util.YangSourceContext import org.slf4j.Logger @@ -56,14 +54,12 @@ import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.* import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.* -class NetconfDevice implements Provider, // +class NetconfDevice implements Provider, // DataReader, // DataCommitHandler, // RpcImplementation, // AutoCloseable { - var NetconfClient client; - @Property var InetSocketAddress socketAddress; @@ -93,15 +89,12 @@ AutoCloseable { Registration> operReaderReg Registration> confReaderReg Registration> commitHandlerReg + List rpcReg + @Property val String name - MountProvisionService mountService - int messegeRetryCount = 5; - - int messageTimeoutCount = 5 * 1000; - - Set cachedCapabilities + MountProvisionService mountService @Property var NetconfClientDispatcher dispatcher @@ -110,11 +103,13 @@ AutoCloseable { @Property var SchemaSourceProvider remoteSourceProvider - + DataBrokerService dataBroker + var NetconfDeviceListener listener; + public new(String name) { - this.name = name; + this._name = name; this.logger = LoggerFactory.getLogger(NetconfDevice.name + "#" + name); this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE, Collections.singletonMap(INVENTORY_ID, name)).toInstance; @@ -125,10 +120,11 @@ AutoCloseable { checkState(schemaSourceProvider != null, "Schema Source Provider must be set.") checkState(eventExecutor != null, "Event executor must be set."); - val listener = new NetconfDeviceListener(this); - val task = startClientTask(dispatcher, listener) - return processingExecutor.submit(task) as Future; + listener = new NetconfDeviceListener(this); + + logger.info("Starting NETCONF Client {} for address {}", name, socketAddress); + dispatcher.createClient(socketAddress, listener, reconnectStrategy); } def Optional getSchemaContext() { @@ -138,59 +134,65 @@ AutoCloseable { return deviceContextProvider.currentContext; } - private def Runnable startClientTask(NetconfClientDispatcher dispatcher, NetconfDeviceListener listener) { - return [ | - try { - logger.info("Starting Netconf Client on: {}", socketAddress); - client = NetconfClient.clientFor(name, socketAddress, reconnectStrategy, dispatcher, listener); - logger.debug("Initial capabilities {}", initialCapabilities); - var SchemaSourceProvider delegate; - if (NetconfRemoteSchemaSourceProvider.isSupportedFor(initialCapabilities)) { - delegate = new NetconfRemoteSchemaSourceProvider(this); - } else if(client.capabilities.contains(NetconfRemoteSchemaSourceProvider.IETF_NETCONF_MONITORING.namespace.toString)) { - delegate = new NetconfRemoteSchemaSourceProvider(this); - } else { - logger.info("Netconf server {} does not support IETF Netconf Monitoring", socketAddress); - delegate = SchemaSourceProviders.noopProvider(); - } - remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate); - deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider); - deviceContextProvider.createContextFromCapabilities(initialCapabilities); - if (mountInstance != null && schemaContext.isPresent) { - mountInstance.schemaContext = schemaContext.get(); - val operations = schemaContext.get().operations; - for (rpc : operations) { - mountInstance.addRpcImplementation(rpc.QName, this); - } - } - updateDeviceState() - if (mountInstance != null && confReaderReg == null && operReaderReg == null) { - confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this); - operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this); - commitHandlerReg = mountInstance.registerCommitHandler(ROOT_PATH, this); - } - } catch (Exception e) { - logger.error("Netconf client NOT started. ", e) + def bringDown() { + if (rpcReg != null) { + for (reg : rpcReg) { + reg.close() } - ] + rpcReg = null + } + confReaderReg?.close() + confReaderReg = null + operReaderReg?.close() + operReaderReg = null + commitHandlerReg?.close() + commitHandlerReg = null + + updateDeviceState(false, Collections.emptySet()) } - private def updateDeviceState() { + def bringUp(SchemaSourceProvider delegate, Set capabilities) { + remoteSourceProvider = schemaSourceProvider.createInstanceFor(delegate); + deviceContextProvider = new NetconfDeviceSchemaContextProvider(this, remoteSourceProvider); + deviceContextProvider.createContextFromCapabilities(capabilities); + if (mountInstance != null && schemaContext.isPresent) { + mountInstance.schemaContext = schemaContext.get(); + } + + updateDeviceState(true, capabilities) + + if (mountInstance != null) { + confReaderReg = mountInstance.registerConfigurationReader(ROOT_PATH, this); + operReaderReg = mountInstance.registerOperationalReader(ROOT_PATH, this); + commitHandlerReg = mountInstance.registerCommitHandler(ROOT_PATH, this); + + val rpcs = new ArrayList(); + for (rpc : mountInstance.schemaContext.operations) { + rpcs.add(mountInstance.addRpcImplementation(rpc.QName, this)); + } + rpcReg = rpcs + } + } + + private def updateDeviceState(boolean up, Set capabilities) { val transaction = dataBroker.beginTransaction val it = ImmutableCompositeNode.builder setQName(INVENTORY_NODE) addLeaf(INVENTORY_ID, name) - addLeaf(INVENTORY_CONNECTED, client.clientSession.up) + addLeaf(INVENTORY_CONNECTED, up) - logger.debug("Client capabilities {}", client.capabilities) - for (capability : client.capabilities) { + logger.debug("Client capabilities {}", capabilities) + for (capability : capabilities) { addLeaf(NETCONF_INVENTORY_INITIAL_CAPABILITY, capability) } logger.debug("Update device state transaction " + transaction.identifier + " putting operational data started.") + transaction.removeOperationalData(path) transaction.putOperationalData(path, it.toInstance) logger.debug("Update device state transaction " + transaction.identifier + " putting operational data ended.") + + // FIXME: this has to be asynchronous val transactionStatus = transaction.commit.get; if (transactionStatus.successful) { @@ -203,13 +205,13 @@ AutoCloseable { override readConfigurationData(InstanceIdentifier path) { val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, - wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure())); + wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure())).get(); val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME); return data?.findNode(path) as CompositeNode; } override readOperationalData(InstanceIdentifier path) { - val result = invokeRpc(NETCONF_GET_QNAME, wrap(NETCONF_GET_QNAME, path.toFilterStructure())); + val result = invokeRpc(NETCONF_GET_QNAME, wrap(NETCONF_GET_QNAME, path.toFilterStructure())).get(); val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME); return data?.findNode(path) as CompositeNode; } @@ -218,30 +220,8 @@ AutoCloseable { Collections.emptySet; } - def createSubscription(String streamName) { - val it = ImmutableCompositeNode.builder() - QName = NETCONF_CREATE_SUBSCRIPTION_QNAME - addLeaf("stream", streamName); - invokeRpc(QName, toInstance()) - } - override invokeRpc(QName rpc, CompositeNode input) { - try { - val message = rpc.toRpcMessage(input,schemaContext); - val result = sendMessageImpl(message, messegeRetryCount, messageTimeoutCount); - return result.toRpcResult(rpc, schemaContext); - - } catch (Exception e) { - logger.error("Rpc was not processed correctly.", e) - throw e; - } - } - - def NetconfMessage sendMessageImpl(NetconfMessage message, int retryCount, int timeout) { - logger.debug("Send message {}",XmlUtil.toString(message.document)) - val result = client.sendMessage(message, retryCount, timeout); - NetconfMapping.checkValidReply(message, result) - return result; + return listener.sendRequest(rpc.toRpcMessage(input,schemaContext)); } override getProviderFunctionality() { @@ -284,7 +264,7 @@ AutoCloseable { return null; } else if (current instanceof CompositeNode) { val currentComposite = (current as CompositeNode); - + current = currentComposite.getFirstCompositeByName(arg.nodeType); if(current == null) { current = currentComposite.getFirstCompositeByName(arg.nodeType.withoutRevision()); @@ -303,18 +283,13 @@ AutoCloseable { } override requestCommit(DataModification modification) { - val twoPhaseCommit = new NetconfDeviceTwoPhaseCommitTransaction(this, modification); + val twoPhaseCommit = new NetconfDeviceTwoPhaseCommitTransaction(this, modification, true); twoPhaseCommit.prepare() return twoPhaseCommit; } - def getInitialCapabilities() { - val capabilities = client?.capabilities; - if (capabilities == null) { - return null; - } - if (cachedCapabilities == null) { - cachedCapabilities = FluentIterable.from(capabilities).filter[ + def getCapabilities(Collection capabilities) { + return FluentIterable.from(capabilities).filter[ contains("?") && contains("module=") && contains("revision=")].transform [ val parts = split("\\?"); val namespace = parts.get(0); @@ -333,16 +308,11 @@ AutoCloseable { } return QName.create(namespace, revision, moduleName); ].toSet(); - } - return cachedCapabilities; } override close() { - confReaderReg?.close() - operReaderReg?.close() - client?.close() + bringDown() } - } package class NetconfDeviceSchemaContextProvider { diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java index 13cd5dbcf0..d5e1d35d7d 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceListener.java @@ -7,48 +7,206 @@ */ package org.opendaylight.controller.sal.connect.netconf; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.FutureListener; + +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Queue; +import java.util.Set; + import org.opendaylight.controller.netconf.api.NetconfMessage; -import org.opendaylight.controller.netconf.client.AbstractNetconfClientNotifySessionListener; +import org.opendaylight.controller.netconf.api.NetconfTerminationReason; import org.opendaylight.controller.netconf.client.NetconfClientSession; +import org.opendaylight.controller.netconf.client.NetconfClientSessionListener; +import org.opendaylight.controller.netconf.util.xml.XmlElement; +import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; +import org.opendaylight.controller.sal.common.util.Rpcs; import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider; +import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +class NetconfDeviceListener implements NetconfClientSessionListener { + private static final class Request { + final UncancellableFuture> future; + final NetconfMessage request; + + private Request(UncancellableFuture> future, NetconfMessage request) { + this.future = future; + this.request = request; + } + } -class NetconfDeviceListener extends AbstractNetconfClientNotifySessionListener { + private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceListener.class); + private final Queue requests = new ArrayDeque<>(); private final NetconfDevice device; + private NetconfClientSession session; public NetconfDeviceListener(final NetconfDevice device) { this.device = Preconditions.checkNotNull(device); } - /** - * Method intended to customize notification processing. - * - * @param session - * {@see - * NetconfClientSessionListener#onMessage(NetconfClientSession, - * NetconfMessage)} - * @param message - * {@see - * NetconfClientSessionListener#onMessage(NetconfClientSession, - * NetconfMessage)} - */ @Override - public void onNotification(final NetconfClientSession session, final NetconfMessage message) { - this.device.logger.debug("Received NETCONF notification.", message); - CompositeNode domNotification = null; - if (message != null) { - domNotification = NetconfMapping.toNotificationNode(message, device.getSchemaContext()); - } - if (domNotification != null) { - MountProvisionInstance _mountInstance = null; - if (this.device != null) { - _mountInstance = this.device.getMountInstance(); + public synchronized void onSessionUp(final NetconfClientSession session) { + LOG.debug("Session with {} established as address {} session-id {}", + device.getName(), device.getSocketAddress(), session.getSessionId()); + + final Set caps = device.getCapabilities(session.getServerCapabilities()); + LOG.trace("Server {} advertized capabilities {}", device.getName(), caps); + + // Select the appropriate provider + final SchemaSourceProvider delegate; + if (NetconfRemoteSchemaSourceProvider.isSupportedFor(caps)) { + delegate = new NetconfRemoteSchemaSourceProvider(device); + } else if(caps.contains(NetconfRemoteSchemaSourceProvider.IETF_NETCONF_MONITORING.getNamespace().toString())) { + delegate = new NetconfRemoteSchemaSourceProvider(device); + } else { + LOG.info("Netconf server {} does not support IETF Netconf Monitoring", device.getName()); + delegate = SchemaSourceProviders.noopProvider(); + } + + device.bringUp(delegate, caps); + + this.session = session; + } + + private synchronized void tearDown(final Exception e) { + session = null; + + /* + * Walk all requests, check if they have been executing + * or cancelled and remove them from the queue. + */ + final Iterator it = requests.iterator(); + while (it.hasNext()) { + final Request r = it.next(); + if (r.future.isUncancellable()) { + // FIXME: add a RpcResult instead? + r.future.setException(e); + it.remove(); + } else if (r.future.isCancelled()) { + // This just does some house-cleaning + it.remove(); } - if (_mountInstance != null) { - _mountInstance.publish(domNotification); + } + + device.bringDown(); + } + + @Override + public void onSessionDown(final NetconfClientSession session, final Exception e) { + LOG.debug("Session with {} went down", device.getName(), e); + tearDown(e); + } + + @Override + public void onSessionTerminated(final NetconfClientSession session, final NetconfTerminationReason reason) { + LOG.debug("Session with {} terminated {}", session, reason); + tearDown(new RuntimeException(reason.getErrorMessage())); + } + + @Override + public void onMessage(final NetconfClientSession session, final NetconfMessage message) { + /* + * Dispatch between notifications and messages. Messages need to be processed + * with lock held, notifications do not. + */ + if (isNotification(message)) { + processNotification(message); + } else { + processMessage(message); + } + } + + private synchronized void processMessage(final NetconfMessage message) { + final Request r = requests.peek(); + if (r.future.isUncancellable()) { + requests.poll(); + LOG.debug("Matched {} to {}", r.request, message); + + // FIXME: this can throw exceptions, which should result + // in the future failing + NetconfMapping.checkValidReply(r.request, message); + r.future.set(Rpcs.getRpcResult(true, NetconfMapping.toNotificationNode(message, device.getSchemaContext()), + Collections.emptyList())); + } else { + LOG.warn("Ignoring unsolicited message", message); + } + } + + synchronized ListenableFuture> sendRequest(final NetconfMessage message) { + if (session == null) { + LOG.debug("Session to {} is disconnected, failing RPC request {}", device.getName(), message); + return Futures.>immediateFuture(new RpcResult() { + @Override + public boolean isSuccessful() { + return false; + } + + @Override + public CompositeNode getResult() { + return null; + } + + @Override + public Collection getErrors() { + // FIXME: indicate that the session is down + return Collections.emptySet(); + } + }); + } + + final Request req = new Request(new UncancellableFuture>(true), message); + requests.add(req); + + session.sendMessage(req.request).addListener(new FutureListener() { + @Override + public void operationComplete(final Future future) throws Exception { + if (!future.isSuccess()) { + // We expect that a session down will occur at this point + LOG.debug("Failed to send request {}", req.request, future.cause()); + req.future.setException(future.cause()); + } else { + LOG.trace("Finished sending request {}", req.request); + } } + }); + + return req.future; + } + + /** + * Process an incoming notification. + * + * @param notification Notification message + */ + private void processNotification(final NetconfMessage notification) { + this.device.logger.debug("Received NETCONF notification.", notification); + CompositeNode domNotification = NetconfMapping.toNotificationNode(notification, device.getSchemaContext()); + if (domNotification == null) { + return; + } + + MountProvisionInstance mountInstance = this.device.getMountInstance(); + if (mountInstance != null) { + mountInstance.publish(domNotification); } } + + private static boolean isNotification(final NetconfMessage message) { + final XmlElement xmle = XmlElement.fromDomDocument(message.getDocument()); + return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(xmle.getName()) ; + } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java index c5390e5409..5f14c264ed 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java @@ -15,14 +15,17 @@ import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NET import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_RUNNING_QNAME; import static org.opendaylight.controller.sal.connect.netconf.NetconfMapping.NETCONF_TARGET_QNAME; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.ExecutionException; import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction; import org.opendaylight.controller.md.sal.common.api.data.DataModification; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; @@ -31,51 +34,52 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -public class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction { - - private final NetconfDevice device; +class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction { + private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceTwoPhaseCommitTransaction.class); private final DataModification modification; - private final boolean candidateSupported = true; + private final NetconfDevice device; + private final boolean candidateSupported; public NetconfDeviceTwoPhaseCommitTransaction(NetconfDevice device, - DataModification modification) { - super(); - this.device = device; - this.modification = modification; + DataModification modification, + boolean candidateSupported) { + this.device = Preconditions.checkNotNull(device); + this.modification = Preconditions.checkNotNull(modification); + this.candidateSupported = candidateSupported; } - public void prepare() { + void prepare() throws InterruptedException, ExecutionException { for (InstanceIdentifier toRemove : modification.getRemovedConfigurationData()) { sendDelete(toRemove); } for(Entry toUpdate : modification.getUpdatedConfigurationData().entrySet()) { sendMerge(toUpdate.getKey(),toUpdate.getValue()); } - } - private void sendMerge(InstanceIdentifier key, CompositeNode value) { + private void sendMerge(InstanceIdentifier key, CompositeNode value) throws InterruptedException, ExecutionException { sendEditRpc(createEditStructure(key, Optional.absent(), Optional.of(value))); } - private void sendDelete(InstanceIdentifier toDelete) { + private void sendDelete(InstanceIdentifier toDelete) throws InterruptedException, ExecutionException { sendEditRpc(createEditStructure(toDelete, Optional.of("delete"), Optional. absent())); } - private void sendEditRpc(CompositeNode editStructure) { + private void sendEditRpc(CompositeNode editStructure) throws InterruptedException, ExecutionException { CompositeNodeBuilder builder = configurationRpcBuilder(); builder.setQName(NETCONF_EDIT_CONFIG_QNAME); builder.add(editStructure); - RpcResult rpcResult = device.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, builder.toInstance()); + RpcResult rpcResult = device.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, builder.toInstance()).get(); Preconditions.checkState(rpcResult.isSuccessful(),"Rpc Result was unsuccessful"); - } private CompositeNodeBuilder configurationRpcBuilder() { @@ -135,8 +139,45 @@ public class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransac public RpcResult finish() { CompositeNodeBuilder commitInput = ImmutableCompositeNode.builder(); commitInput.setQName(NETCONF_COMMIT_QNAME); - RpcResult rpcResult = device.invokeRpc(NetconfMapping.NETCONF_COMMIT_QNAME, commitInput.toInstance()); - return (RpcResult) rpcResult; + try { + final RpcResult rpcResult = device.invokeRpc(NetconfMapping.NETCONF_COMMIT_QNAME, commitInput.toInstance()).get(); + return new RpcResult() { + + @Override + public boolean isSuccessful() { + return rpcResult.isSuccessful(); + } + + @Override + public Void getResult() { + return null; + } + + @Override + public Collection getErrors() { + return rpcResult.getErrors(); + } + }; + } catch (final InterruptedException | ExecutionException e) { + LOG.warn("Failed to finish operation", e); + return new RpcResult() { + @Override + public boolean isSuccessful() { + return false; + } + + @Override + public Void getResult() { + return null; + } + + @Override + public Collection getErrors() { + // FIXME: wrap the exception + return Collections.emptySet(); + } + }; + } } @Override diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfInventoryUtils.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfInventoryUtils.java index bae0f08947..b68f18f52e 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfInventoryUtils.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfInventoryUtils.java @@ -11,18 +11,19 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.CompositeNode; public class NetconfInventoryUtils { - - public static final QName NETCONF_MOUNT = null; public static final QName NETCONF_ENDPOINT = null; public static final QName NETCONF_ENDPOINT_ADDRESS = null; public static final QName NETCONF_ENDPOINT_PORT = null; + private NetconfInventoryUtils() { + throw new UnsupportedOperationException("Utility class cannot be instantiated"); + } public static String getEndpointAddress(CompositeNode node) { return node.getCompositesByName(NETCONF_ENDPOINT).get(0).getFirstSimpleByName(NETCONF_ENDPOINT_ADDRESS).getValue().toString(); } - + public static String getEndpointPort(CompositeNode node) { return node.getCompositesByName(NETCONF_ENDPOINT).get(0).getFirstSimpleByName(NETCONF_ENDPOINT_PORT).getValue().toString(); } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend index e5a24fcf63..228a01eb4c 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend @@ -39,8 +39,8 @@ class NetconfMapping { public static val NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0") public static val NETCONF_MONITORING_URI = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring" public static val NETCONF_NOTIFICATION_URI = URI.create("urn:ietf:params:xml:ns:netconf:notification:1.0") - - + + public static val NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf"); public static val NETCONF_RPC_QNAME = QName.create(NETCONF_QNAME, "rpc"); public static val NETCONF_GET_QNAME = QName.create(NETCONF_QNAME, "get"); @@ -51,15 +51,15 @@ class NetconfMapping { public static val NETCONF_DELETE_CONFIG_QNAME = QName.create(NETCONF_QNAME, "delete-config"); public static val NETCONF_OPERATION_QNAME = QName.create(NETCONF_QNAME, "operation"); public static val NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit"); - + public static val NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config"); public static val NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source"); public static val NETCONF_TARGET_QNAME = QName.create(NETCONF_QNAME, "target"); - + public static val NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate"); public static val NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running"); - - + + public static val NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply"); public static val NETCONF_OK_QNAME = QName.create(NETCONF_QNAME, "ok"); public static val NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data"); @@ -78,7 +78,7 @@ class NetconfMapping { if(identifier.path.empty) { return null; } - + for (component : identifier.path.reverseView) { val Node current = component.toNode(previous); previous = current; @@ -106,11 +106,11 @@ class NetconfMapping { } static def CompositeNode toCompositeNode(NetconfMessage message,Optional ctx) { - //TODO: implement general normalization to normalize incoming Netconf Message + //TODO: implement general normalization to normalize incoming Netconf Message // for Schema Context counterpart return null } - + static def CompositeNode toNotificationNode(NetconfMessage message,Optional ctx) { if (ctx.present) { val schemaContext = ctx.get @@ -127,56 +127,53 @@ class NetconfMapping { w3cPayload.documentElement.setAttribute("message-id", "m-" + messageId.andIncrement) return new NetconfMessage(w3cPayload); } - + def static flattenInput(CompositeNode node) { val inputQName = QName.create(node.nodeType,"input"); val input = node.getFirstCompositeByName(inputQName); if(input == null) return node; if(input instanceof CompositeNode) { - + val nodes = ImmutableList.builder() // .addAll(input.children) // .addAll(node.children.filter[nodeType != inputQName]) // .build() return ImmutableCompositeNode.create(node.nodeType,nodes); - } - + } + } static def RpcResult toRpcResult(NetconfMessage message,QName rpc,Optional context) { var CompositeNode rawRpc; if(context.present) { if(isDataRetrievalReply(rpc)) { - + val xmlData = message.document.dataSubtree val dataNodes = XmlDocumentUtils.toDomNodes(xmlData, Optional.of(context.get.dataDefinitions)) - + val it = ImmutableCompositeNode.builder() setQName(NETCONF_RPC_REPLY_QNAME) add(ImmutableCompositeNode.create(NETCONF_DATA_QNAME, dataNodes)); - + rawRpc = it.toInstance; //sys(xmlData) } else { val rpcSchema = context.get.operations.findFirst[QName == rpc] rawRpc = message.document.toCompositeNode() as CompositeNode; } - - - } else { rawRpc = message.document.toCompositeNode() as CompositeNode; } //rawRpc. return Rpcs.getRpcResult(true, rawRpc, Collections.emptySet()); } - + def static Element getDataSubtree(Document doc) { doc.getElementsByTagNameNS(NETCONF_URI.toString,"data").item(0) as Element } - + def static boolean isDataRetrievalReply(QName it) { - return NETCONF_URI == namespace && ( localName == NETCONF_GET_CONFIG_QNAME.localName || localName == NETCONF_GET_QNAME.localName) + return NETCONF_URI == namespace && ( localName == NETCONF_GET_CONFIG_QNAME.localName || localName == NETCONF_GET_QNAME.localName) } static def wrap(QName name, Node node) { @@ -209,12 +206,12 @@ class NetconfMapping { public static def Node toCompositeNode(Document document) { return XmlDocumentUtils.toDomNode(document) as Node } - + public static def checkValidReply(NetconfMessage input, NetconfMessage output) { val inputMsgId = input.document.documentElement.getAttribute("message-id") val outputMsgId = output.document.documentElement.getAttribute("message-id") Preconditions.checkState(inputMsgId == outputMsgId,"Rpc request and reply message IDs must be same."); - + } - + } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java index fa6b6f7ca5..c734e80d9a 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfRemoteSchemaSourceProvider.java @@ -7,7 +7,8 @@ */ package org.opendaylight.controller.sal.connect.netconf; -import java.util.Set; +import java.util.Collection; +import java.util.concurrent.ExecutionException; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcResult; @@ -18,6 +19,7 @@ import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider; import com.google.common.base.Optional; +import com.google.common.base.Preconditions; class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider { @@ -26,11 +28,10 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider public static final QName GET_SCHEMA_QNAME = QName.create(IETF_NETCONF_MONITORING, "get-schema"); public static final QName GET_DATA_QNAME = QName.create(IETF_NETCONF_MONITORING, "data"); - NetconfDevice device; + private final NetconfDevice device; public NetconfRemoteSchemaSourceProvider(NetconfDevice device) { - super(); - this.device = device; + this.device = Preconditions.checkNotNull(device); } @Override @@ -44,15 +45,19 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider } device.logger.trace("Loading YANG schema source for {}:{}", moduleName, revision); - RpcResult schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance()); - if (schemaReply.isSuccessful()) { - String schemaBody = getSchemaFromRpc(schemaReply.getResult()); - if (schemaBody != null) { - device.logger.trace("YANG Schema successfully retrieved from remote for {}:{}", moduleName, revision); - return Optional.of(schemaBody); + try { + RpcResult schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance()).get(); + if (schemaReply.isSuccessful()) { + String schemaBody = getSchemaFromRpc(schemaReply.getResult()); + if (schemaBody != null) { + device.logger.trace("YANG Schema successfully retrieved from remote for {}:{}", moduleName, revision); + return Optional.of(schemaBody); + } } + device.logger.warn("YANG shcema was not successfully retrieved."); + } catch (InterruptedException | ExecutionException e) { + device.logger.warn("YANG shcema was not successfully retrieved.", e); } - device.logger.warn("YANG shcema was not successfully retrieved."); return Optional.absent(); } @@ -68,7 +73,7 @@ class NetconfRemoteSchemaSourceProvider implements SchemaSourceProvider return null; } - public static final boolean isSupportedFor(Set capabilities) { + public static final boolean isSupportedFor(Collection capabilities) { return capabilities.contains(IETF_NETCONF_MONITORING); } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/UncancellableFuture.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/UncancellableFuture.java new file mode 100644 index 0000000000..c353f86eb6 --- /dev/null +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/UncancellableFuture.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.connect.netconf; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.GuardedBy; + +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.AbstractFuture; + +final class UncancellableFuture extends AbstractFuture { + @GuardedBy("this") + private boolean uncancellable = false; + + public UncancellableFuture(boolean uncancellable) { + this.uncancellable = uncancellable; + } + + public synchronized boolean setUncancellable() { + if (isCancelled()) { + return false; + } + + uncancellable = true; + return true; + } + + public synchronized boolean isUncancellable() { + return uncancellable; + } + + @Override + public synchronized boolean cancel(boolean mayInterruptIfRunning) { + if (uncancellable) { + return false; + } + + return super.cancel(mayInterruptIfRunning); + } + + @Override + public synchronized boolean set(@Nullable V value) { + Preconditions.checkState(uncancellable == true); + return super.set(value); + } + + @Override + protected boolean setException(Throwable throwable) { + Preconditions.checkState(uncancellable == true); + return super.setException(throwable); + } +} diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java deleted file mode 100644 index 23892e18bd..0000000000 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/YangModelInputStreamAdapter.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.connect.netconf; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.opendaylight.yangtools.concepts.Delegator; -import org.opendaylight.yangtools.yang.common.QName; - -import com.google.common.base.Charsets; - -/** - * - * - */ -public class YangModelInputStreamAdapter extends InputStream implements Delegator { - - final String source; - final QName moduleIdentifier; - final InputStream delegate; - - private YangModelInputStreamAdapter(String source, QName moduleIdentifier, InputStream delegate) { - super(); - this.source = source; - this.moduleIdentifier = moduleIdentifier; - this.delegate = delegate; - } - - @Override - public int read() throws IOException { - return delegate.read(); - } - - @Override - public int hashCode() { - return delegate.hashCode(); - } - - @Override - public int read(byte[] b) throws IOException { - return delegate.read(b); - } - - @Override - public boolean equals(Object obj) { - return delegate.equals(obj); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - return delegate.read(b, off, len); - } - - @Override - public long skip(long n) throws IOException { - return delegate.skip(n); - } - - @Override - public int available() throws IOException { - return delegate.available(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public void mark(int readlimit) { - delegate.mark(readlimit); - } - - @Override - public void reset() throws IOException { - delegate.reset(); - } - - @Override - public boolean markSupported() { - return delegate.markSupported(); - } - - @Override - public InputStream getDelegate() { - return delegate; - } - - @Override - public String toString() { - return "YangModelInputStreamAdapter [moduleIdentifier=" + moduleIdentifier + ", delegate=" + delegate + "]"; - } - - public static YangModelInputStreamAdapter create(QName name, String module) { - return new YangModelInputStreamAdapter(null, name, new ByteArrayInputStream(module.getBytes(Charsets.UTF_8))); - } -} diff --git a/opendaylight/md-sal/sal-remote/pom.xml b/opendaylight/md-sal/sal-remote/pom.xml index 15bd2e7a30..0c06b4490d 100644 --- a/opendaylight/md-sal/sal-remote/pom.xml +++ b/opendaylight/md-sal/sal-remote/pom.xml @@ -64,25 +64,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/ - - - - - diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml b/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml index 415ae5aa05..0c817d26f6 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml @@ -157,7 +157,7 @@ org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator - ${project.build.directory}/generated-sources/config + ${jmxGeneratorPath} urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImpl.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImpl.java index 84df2e43f0..8f95e73b15 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImpl.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImpl.java @@ -7,7 +7,16 @@ package org.opendaylight.controller.sal.connector.remoterpc; -import com.google.common.base.Optional; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.concurrent.TimeUnit; + import org.opendaylight.controller.sal.common.util.RpcErrors; import org.opendaylight.controller.sal.common.util.Rpcs; import org.opendaylight.controller.sal.connector.api.RpcRouter; @@ -27,16 +36,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.zeromq.ZMQ; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; -import java.util.concurrent.TimeUnit; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; +import com.google.common.base.Optional; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; /** * An implementation of {@link RpcImplementation} that makes @@ -46,8 +48,8 @@ public class ClientImpl implements RemoteRpcClient { private final Logger _logger = LoggerFactory.getLogger(ClientImpl.class); - private ZMQ.Context context = ZMQ.context(1); - private ClientRequestHandler handler; + private final ZMQ.Context context = ZMQ.context(1); + private final ClientRequestHandler handler; private RoutingTableProvider routingTableProvider; public ClientImpl(){ @@ -64,6 +66,7 @@ public class ClientImpl implements RemoteRpcClient { return routingTableProvider; } + @Override public void setRoutingTableProvider(RoutingTableProvider routingTableProvider) { this.routingTableProvider = routingTableProvider; } @@ -93,7 +96,7 @@ public class ClientImpl implements RemoteRpcClient { * @param input payload for the remote service * @return */ - public RpcResult invokeRpc(QName rpc, CompositeNode input) { + public ListenableFuture> invokeRpc(QName rpc, CompositeNode input) { RouteIdentifierImpl routeId = new RouteIdentifierImpl(); routeId.setType(rpc); @@ -115,7 +118,7 @@ public class ClientImpl implements RemoteRpcClient { * payload * @return */ - public RpcResult invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) { + public ListenableFuture> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) { RouteIdentifierImpl routeId = new RouteIdentifierImpl(); routeId.setType(rpc); @@ -126,7 +129,7 @@ public class ClientImpl implements RemoteRpcClient { return sendMessage(input, routeId, address); } - private RpcResult sendMessage(CompositeNode input, RouteIdentifierImpl routeId, String address) { + private ListenableFuture> sendMessage(CompositeNode input, RouteIdentifierImpl routeId, String address) { Message request = new Message.MessageBuilder() .type(Message.MessageType.REQUEST) .sender(Context.getInstance().getLocalUri()) @@ -164,11 +167,11 @@ public class ClientImpl implements RemoteRpcClient { } } - return Rpcs.getRpcResult(true, payload, errors); + return Futures.immediateFuture(Rpcs.getRpcResult(true, payload, errors)); } catch (Exception e){ collectErrors(e, errors); - return Rpcs.getRpcResult(false, null, errors); + return Futures.immediateFuture(Rpcs.getRpcResult(false, null, errors)); } } diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProvider.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProvider.java index 16e7200247..edcef83574 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProvider.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProvider.java @@ -8,7 +8,14 @@ package org.opendaylight.controller.sal.connector.remoterpc; -import com.google.common.base.Optional; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + import org.opendaylight.controller.md.sal.common.api.routing.RouteChange; import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; import org.opendaylight.controller.sal.connector.api.RpcRouter; @@ -32,13 +39,8 @@ import org.osgi.util.tracker.ServiceTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Optional; +import com.google.common.util.concurrent.ListenableFuture; public class RemoteRpcProvider implements RpcImplementation, @@ -46,7 +48,7 @@ public class RemoteRpcProvider implements AutoCloseable, Provider { - private Logger _logger = LoggerFactory.getLogger(RemoteRpcProvider.class); + private final Logger _logger = LoggerFactory.getLogger(RemoteRpcProvider.class); private final ServerImpl server; private final ClientImpl client; @@ -96,12 +98,12 @@ public class RemoteRpcProvider implements } @Override - public RpcResult invokeRpc(QName rpc, CompositeNode input) { + public ListenableFuture> invokeRpc(QName rpc, CompositeNode input) { return client.invokeRpc(rpc, input); } @Override - public RpcResult invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) { + public ListenableFuture> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) { return client.invokeRpc(rpc, identifier, input); } @@ -289,8 +291,5 @@ public class RemoteRpcProvider implements return routeIdSet; } - - } - } diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImpl.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImpl.java index 722ca06879..d256b998d4 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImpl.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImpl.java @@ -254,7 +254,6 @@ public class ServerImpl implements RemoteRpcServer { e = NetworkInterface.getNetworkInterfaces(); } catch (SocketException e1) { _logger.error("Failed to get list of interfaces", e1); - //throw new RuntimeException("Failed to acquire list of interfaces", e1); return null; } while (e.hasMoreElements()) { @@ -265,7 +264,7 @@ public class ServerImpl implements RemoteRpcServer { while (ee.hasMoreElements()) { InetAddress i = (InetAddress) ee.nextElement(); _logger.debug("Trying address {}", i); - if ((i instanceof Inet4Address) && (i.isSiteLocalAddress())) { + if ((i instanceof Inet4Address) && (!i.isLoopbackAddress())) { String hostAddress = i.getHostAddress(); _logger.debug("Settled on host address {}", hostAddress); return hostAddress; diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImplTest.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImplTest.java index c0aae2dfb5..0fa12e351c 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImplTest.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImplTest.java @@ -7,29 +7,25 @@ */ package org.opendaylight.controller.sal.connector.remoterpc; -import com.google.common.base.Optional; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; + import junit.framework.Assert; + import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.opendaylight.controller.sal.common.util.Rpcs; import org.opendaylight.controller.sal.connector.api.RpcRouter; -import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener; import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable; -import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException; -import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException; import org.opendaylight.controller.sal.connector.remoterpc.dto.Message; import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil; -import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import java.io.IOException; -import java.util.*; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import com.google.common.base.Optional; /** * @@ -88,7 +84,7 @@ public class ClientImplTest { when(mockHandler.handle(any(Message.class))). thenReturn(MessagingUtil.createEmptyMessage()); - RpcResult result = client.invokeRpc(null, null); + RpcResult result = client.invokeRpc(null, null).get(); Assert.assertTrue(result.isSuccessful()); Assert.assertTrue(result.getErrors().isEmpty()); @@ -101,7 +97,7 @@ public class ClientImplTest { when(mockHandler.handle(any(Message.class))). thenThrow(new IOException()); - RpcResult result = client.invokeRpc(null, null); + RpcResult result = client.invokeRpc(null, null).get(); Assert.assertFalse(result.isSuccessful()); Assert.assertFalse(result.getErrors().isEmpty()); diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend index 837d7ae5b7..cb02fc89bf 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend @@ -483,7 +483,7 @@ class ControllerContext implements SchemaContextListener { + "\" cannot contain \"null\" value as a key." ) } - keyValues.addKeyValue(listNode.getDataChildByName(key), uriKeyValue); + keyValues.addKeyValue(listNode.getDataChildByName(key), uriKeyValue, mountPoint); i = i + 1; } consumed = consumed + i; @@ -541,13 +541,13 @@ class ControllerContext implements SchemaContextListener { } } - private def void addKeyValue(HashMap map, DataSchemaNode node, String uriValue) { + private def void addKeyValue(HashMap map, DataSchemaNode node, String uriValue, MountInstance mountPoint) { checkNotNull(uriValue); checkArgument(node instanceof LeafSchemaNode); val urlDecoded = URLDecoder.decode(uriValue); val typedef = (node as LeafSchemaNode).type; - var decoded = TypeDefinitionAwareCodec.from(typedef)?.deserialize(urlDecoded) + var decoded = RestCodec.from(typedef, mountPoint)?.deserialize(urlDecoded) var additionalInfo = "" if(decoded === null) { var baseType = RestUtil.resolveBaseTypeFrom(typedef) diff --git a/opendaylight/md-sal/sal-restconf-broker/pom.xml b/opendaylight/md-sal/sal-restconf-broker/pom.xml index 2fe625ffb3..c086db7ba4 100644 --- a/opendaylight/md-sal/sal-restconf-broker/pom.xml +++ b/opendaylight/md-sal/sal-restconf-broker/pom.xml @@ -66,25 +66,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${project.build.directory}/generated-sources/ - - - - - diff --git a/opendaylight/md-sal/samples/l2switch/model/pom.xml b/opendaylight/md-sal/samples/l2switch/model/pom.xml index d0ef2e0c65..7c54309fa1 100644 --- a/opendaylight/md-sal/samples/l2switch/model/pom.xml +++ b/opendaylight/md-sal/samples/l2switch/model/pom.xml @@ -41,7 +41,7 @@ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - target/generated-sources/sal + ${salGeneratorPath} diff --git a/opendaylight/md-sal/samples/toaster-consumer/pom.xml b/opendaylight/md-sal/samples/toaster-consumer/pom.xml index 67fc824a7b..0c16a92586 100644 --- a/opendaylight/md-sal/samples/toaster-consumer/pom.xml +++ b/opendaylight/md-sal/samples/toaster-consumer/pom.xml @@ -16,8 +16,6 @@ 1.1-SNAPSHOT - ${project.build.directory}/generated-sources/config - @@ -84,25 +82,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${jmxGeneratorPath} - - - - - diff --git a/opendaylight/md-sal/samples/toaster-provider/pom.xml b/opendaylight/md-sal/samples/toaster-provider/pom.xml index 4e4cfeda2a..11ee47b8c7 100644 --- a/opendaylight/md-sal/samples/toaster-provider/pom.xml +++ b/opendaylight/md-sal/samples/toaster-provider/pom.xml @@ -16,7 +16,6 @@ - ${project.build.directory}/generated-sources/config 1.1-SNAPSHOT @@ -82,25 +81,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - generate-sources - - add-source - - - - ${jmxGeneratorPath} - - - - - diff --git a/opendaylight/md-sal/samples/toaster/pom.xml b/opendaylight/md-sal/samples/toaster/pom.xml index 59f8955d4b..eb13e64adc 100644 --- a/opendaylight/md-sal/samples/toaster/pom.xml +++ b/opendaylight/md-sal/samples/toaster/pom.xml @@ -49,24 +49,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.7 - - - generate-sources - - add-source - - - - target/generated-sources/sal - - - - - diff --git a/opendaylight/md-sal/statistics-manager/pom.xml b/opendaylight/md-sal/statistics-manager/pom.xml index b829990bd3..9ace8a119f 100644 --- a/opendaylight/md-sal/statistics-manager/pom.xml +++ b/opendaylight/md-sal/statistics-manager/pom.xml @@ -66,9 +66,6 @@ - - maven-clean-plugin - diff --git a/opendaylight/md-sal/topology-lldp-discovery/pom.xml b/opendaylight/md-sal/topology-lldp-discovery/pom.xml index 590e8ea91a..627934eb67 100644 --- a/opendaylight/md-sal/topology-lldp-discovery/pom.xml +++ b/opendaylight/md-sal/topology-lldp-discovery/pom.xml @@ -92,29 +92,6 @@ org.eclipse.xtend xtend-maven-plugin - - - - compile - - - ${basedir}/src/main/xtend-gen - - - - - - maven-clean-plugin - - - - ${basedir}/src/main/xtend-gen - - ** - - - - diff --git a/opendaylight/md-sal/topology-manager/pom.xml b/opendaylight/md-sal/topology-manager/pom.xml index 8035f420fb..8503864f62 100644 --- a/opendaylight/md-sal/topology-manager/pom.xml +++ b/opendaylight/md-sal/topology-manager/pom.xml @@ -68,9 +68,6 @@ org.eclipse.xtend xtend-maven-plugin - - maven-clean-plugin - diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index 43edced0a1..96522712da 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -75,7 +75,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStore import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl; import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution; @@ -119,7 +119,7 @@ public class NetconfMappingTest extends AbstractConfigTest { @Mock NetconfOperationRouter netconfOperationRouter; @Mock - NetconfOperationServiceSnapshot netconfOperationServiceSnapshot; + NetconfOperationServiceSnapshotImpl netconfOperationServiceSnapshot; private TransactionProvider transactionProvider; diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java index 76afe8eb39..0cc55719e1 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java @@ -10,14 +10,17 @@ package org.opendaylight.controller.netconf.persist.impl.osgi; import com.google.common.annotations.VisibleForTesting; import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory; import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler; import org.opendaylight.controller.netconf.persist.impl.ConfigPusher; import org.opendaylight.controller.netconf.persist.impl.PersisterAggregator; +import org.opendaylight.controller.netconf.util.CloseableUtil; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.Filter; +import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; import org.osgi.util.tracker.ServiceTrackerCustomizer; @@ -33,6 +36,7 @@ import java.util.concurrent.TimeUnit; public class ConfigPersisterActivator implements BundleActivator { private static final Logger logger = LoggerFactory.getLogger(ConfigPersisterActivator.class); + private static final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); public static final String MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY = "maxWaitForCapabilitiesMillis"; private static final long MAX_WAIT_FOR_CAPABILITIES_MILLIS_DEFAULT = TimeUnit.MINUTES.toMillis(2); @@ -43,9 +47,6 @@ public class ConfigPersisterActivator implements BundleActivator { public static final String STORAGE_ADAPTER_CLASS_PROP_SUFFIX = "storageAdapterClass"; - - private static final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); - private List autoCloseables; @@ -55,56 +56,32 @@ public class ConfigPersisterActivator implements BundleActivator { autoCloseables = new ArrayList<>(); PropertiesProviderBaseImpl propertiesProvider = new PropertiesProviderBaseImpl(context); - final PersisterAggregator persisterAggregator = PersisterAggregator.createFromProperties(propertiesProvider); autoCloseables.add(persisterAggregator); - final long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider); - final List configs = persisterAggregator.loadLastConfigs(); - final long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider); + long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider); + List configs = persisterAggregator.loadLastConfigs(); + long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider); logger.trace("Following configs will be pushed: {}", configs); - ServiceTrackerCustomizer configNetconfCustomizer = new ServiceTrackerCustomizer() { - @Override - public NetconfOperationServiceFactory addingService(ServiceReference reference) { - NetconfOperationServiceFactory service = reference.getBundle().getBundleContext().getService(reference); - final ConfigPusher configPusher = new ConfigPusher(service, maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis); - logger.debug("Configuration Persister got %s", service); - final Thread pushingThread = new Thread(new Runnable() { - @Override - public void run() { - configPusher.pushConfigs(configs); - logger.info("Configuration Persister initialization completed."); - ConfigPersisterNotificationHandler jmxNotificationHandler = new ConfigPersisterNotificationHandler(platformMBeanServer, persisterAggregator); - synchronized (ConfigPersisterActivator.this) { - autoCloseables.add(jmxNotificationHandler); - } - } - }, "config-pusher"); - synchronized (ConfigPersisterActivator.this){ - autoCloseables.add(new AutoCloseable() { - @Override - public void close() throws Exception { - pushingThread.interrupt(); - } - }); - } - pushingThread.start(); - return service; - } - @Override - public void modifiedService(ServiceReference reference, NetconfOperationServiceFactory service) { - } + InnerCustomizer innerCustomizer = new InnerCustomizer(configs, maxWaitForCapabilitiesMillis, + conflictingVersionTimeoutMillis, persisterAggregator); + OuterCustomizer outerCustomizer = new OuterCustomizer(context, innerCustomizer); + new ServiceTracker<>(context, NetconfOperationProvider.class, outerCustomizer).open(); + } - @Override - public void removedService(ServiceReference reference, NetconfOperationServiceFactory service) { - } - }; + private long getConflictingVersionTimeoutMillis(PropertiesProviderBaseImpl propertiesProvider) { + String timeoutProperty = propertiesProvider.getProperty(CONFLICTING_VERSION_TIMEOUT_MILLIS_PROPERTY); + return timeoutProperty == null ? CONFLICTING_VERSION_TIMEOUT_MILLIS_DEFAULT : Long.valueOf(timeoutProperty); + } - Filter filter = context.createFilter(getFilterString()); + private long getMaxWaitForCapabilitiesMillis(PropertiesProviderBaseImpl propertiesProvider) { + String timeoutProperty = propertiesProvider.getProperty(MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY); + return timeoutProperty == null ? MAX_WAIT_FOR_CAPABILITIES_MILLIS_DEFAULT : Long.valueOf(timeoutProperty); + } - ServiceTracker tracker = - new ServiceTracker<>(context, filter, configNetconfCustomizer); - tracker.open(); + @Override + public synchronized void stop(BundleContext context) throws Exception { + CloseableUtil.closeAll(autoCloseables); } @@ -116,32 +93,92 @@ public class ConfigPersisterActivator implements BundleActivator { ")"; } - private long getConflictingVersionTimeoutMillis(PropertiesProviderBaseImpl propertiesProvider) { - String timeoutProperty = propertiesProvider.getProperty(CONFLICTING_VERSION_TIMEOUT_MILLIS_PROPERTY); - return timeoutProperty == null ? CONFLICTING_VERSION_TIMEOUT_MILLIS_DEFAULT : Long.valueOf(timeoutProperty); - } + class OuterCustomizer implements ServiceTrackerCustomizer { + private final BundleContext context; + private final InnerCustomizer innerCustomizer; - private long getMaxWaitForCapabilitiesMillis(PropertiesProviderBaseImpl propertiesProvider) { - String timeoutProperty = propertiesProvider.getProperty(MAX_WAIT_FOR_CAPABILITIES_MILLIS_PROPERTY); - return timeoutProperty == null ? MAX_WAIT_FOR_CAPABILITIES_MILLIS_DEFAULT : Long.valueOf(timeoutProperty); - } + OuterCustomizer(BundleContext context, InnerCustomizer innerCustomizer) { + this.context = context; + this.innerCustomizer = innerCustomizer; + } - @Override - public synchronized void stop(BundleContext context) throws Exception { - Exception lastException = null; - for (AutoCloseable autoCloseable : autoCloseables) { + @Override + public NetconfOperationProvider addingService(ServiceReference reference) { + logger.trace("Got OuterCustomizer.addingService {}", reference); + // JMX was registered, track config-netconf-connector + Filter filter; try { - autoCloseable.close(); - } catch (Exception e) { - if (lastException == null) { - lastException = e; - } else { - lastException.addSuppressed(e); + filter = context.createFilter(getFilterString()); + } catch (InvalidSyntaxException e) { + throw new IllegalStateException(e); + } + new ServiceTracker<>(context, filter, innerCustomizer).open(); + return null; + } + + @Override + public void modifiedService(ServiceReference reference, NetconfOperationProvider service) { + + } + + @Override + public void removedService(ServiceReference reference, NetconfOperationProvider service) { + + } + } + + class InnerCustomizer implements ServiceTrackerCustomizer { + private final List configs; + private final PersisterAggregator persisterAggregator; + private final long maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis; + + + InnerCustomizer(List configs, long maxWaitForCapabilitiesMillis, long conflictingVersionTimeoutMillis, + PersisterAggregator persisterAggregator) { + this.configs = configs; + this.maxWaitForCapabilitiesMillis = maxWaitForCapabilitiesMillis; + this.conflictingVersionTimeoutMillis = conflictingVersionTimeoutMillis; + this.persisterAggregator = persisterAggregator; + } + + @Override + public NetconfOperationServiceFactory addingService(ServiceReference reference) { + logger.trace("Got InnerCustomizer.addingService {}", reference); + NetconfOperationServiceFactory service = reference.getBundle().getBundleContext().getService(reference); + + final ConfigPusher configPusher = new ConfigPusher(service, maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis); + logger.debug("Configuration Persister got {}", service); + final Thread pushingThread = new Thread(new Runnable() { + @Override + public void run() { + configPusher.pushConfigs(configs); + logger.info("Configuration Persister initialization completed."); + ConfigPersisterNotificationHandler jmxNotificationHandler = new ConfigPersisterNotificationHandler(platformMBeanServer, persisterAggregator); + synchronized (ConfigPersisterActivator.this) { + autoCloseables.add(jmxNotificationHandler); + } } + }, "config-pusher"); + synchronized (ConfigPersisterActivator.this) { + autoCloseables.add(new AutoCloseable() { + @Override + public void close() throws Exception { + pushingThread.interrupt(); + } + }); } + pushingThread.start(); + return service; + } + + @Override + public void modifiedService(ServiceReference reference, NetconfOperationServiceFactory service) { } - if (lastException != null) { - throw lastException; + + @Override + public void removedService(ServiceReference reference, NetconfOperationServiceFactory service) { } + } } + diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java index 493ecd9250..b1bf232928 100644 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java +++ b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterTest.java @@ -25,9 +25,7 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.xml.sax.SAXException; -import javax.management.MBeanServer; import java.io.IOException; -import java.lang.management.ManagementFactory; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; @@ -41,7 +39,6 @@ public class ConfigPersisterTest { private MockedBundleContext ctx; private ConfigPersisterActivator configPersisterActivator; - private static final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); private TestingExceptionHandler handler; diff --git a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockedBundleContext.java b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockedBundleContext.java index 8bc787bdef..95fd5f6549 100644 --- a/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockedBundleContext.java +++ b/opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/osgi/MockedBundleContext.java @@ -14,6 +14,7 @@ import org.mockito.MockitoAnnotations; import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder; import org.opendaylight.controller.config.persist.api.Persister; import org.opendaylight.controller.config.persist.api.PropertiesProvider; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory; import org.opendaylight.controller.netconf.persist.impl.DummyAdapter; @@ -39,7 +40,7 @@ final class MockedBundleContext { @Mock private BundleContext context; @Mock - private Filter filter; + private Filter outerFilter, innerFilter; @Mock private ServiceReference serviceReference; @Mock @@ -53,12 +54,21 @@ final class MockedBundleContext { MockitoAnnotations.initMocks(this); doReturn(null).when(context).getProperty(anyString()); initContext(maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis); - doReturn(filter).when(context).createFilter(ConfigPersisterActivator.getFilterString()); - String filterString = "filter"; - doReturn(filterString).when(filter).toString(); - doNothing().when(context).addServiceListener(any(ServiceListener.class), eq(filterString)); + + String outerFilterString = "(objectClass=org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider)"; + doReturn(outerFilter).when(context).createFilter(outerFilterString); + doNothing().when(context).addServiceListener(any(ServiceListener.class), eq(outerFilterString)); ServiceReference[] toBeReturned = {serviceReference}; - doReturn(toBeReturned).when(context).getServiceReferences((String) null, filterString); + doReturn(toBeReturned).when(context).getServiceReferences(NetconfOperationProvider.class.getName(), null); + + String innerFilterString = "innerfilter"; + doReturn(innerFilterString).when(outerFilter).toString(); + + doReturn(innerFilter).when(context).createFilter(ConfigPersisterActivator.getFilterString()); + doReturn(innerFilterString).when(innerFilter).toString(); + doNothing().when(context).addServiceListener(any(ServiceListener.class), eq(innerFilterString)); + + doReturn(toBeReturned).when(context).getServiceReferences((String) null, innerFilterString); doReturn(bundle).when(serviceReference).getBundle(); doReturn(context).when(bundle).getBundleContext(); doReturn("").when(serviceReference).toString(); @@ -66,6 +76,7 @@ final class MockedBundleContext { doReturn(service).when(serviceFactory).createService(anyString()); doReturn(Collections.emptySet()).when(service).getCapabilities(); doNothing().when(service).close(); + doReturn("serviceFactoryMock").when(serviceFactory).toString(); } public BundleContext getBundleContext() { diff --git a/opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml b/opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml index 7b872db9a6..2590ad8b11 100644 --- a/opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml +++ b/opendaylight/netconf/ietf-netconf-monitoring-extension/pom.xml @@ -31,10 +31,6 @@ org.opendaylight.yangtools yang-maven-plugin - - org.codehaus.mojo - build-helper-maven-plugin - org.apache.felix diff --git a/opendaylight/netconf/ietf-netconf-monitoring/pom.xml b/opendaylight/netconf/ietf-netconf-monitoring/pom.xml index f1e5764ca6..bd2f1cc807 100644 --- a/opendaylight/netconf/ietf-netconf-monitoring/pom.xml +++ b/opendaylight/netconf/ietf-netconf-monitoring/pom.xml @@ -38,10 +38,6 @@ org.opendaylight.yangtools yang-maven-plugin - - org.codehaus.mojo - build-helper-maven-plugin - org.apache.felix diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfOperationRouter.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfOperationRouter.java index e2a2d832c7..dcd2ffad55 100644 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfOperationRouter.java +++ b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfOperationRouter.java @@ -15,7 +15,5 @@ public interface NetconfOperationRouter extends AutoCloseable { Document onNetconfMessage(Document message, NetconfSession session) throws NetconfDocumentedException; - @Override - void close(); } diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfTerminationReason.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfTerminationReason.java index 9de3071060..a15f9e0925 100644 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfTerminationReason.java +++ b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfTerminationReason.java @@ -22,4 +22,9 @@ public class NetconfTerminationReason implements TerminationReason { public String getErrorMessage() { return reason; } + + @Override + public String toString() { + return reason; + } } diff --git a/opendaylight/netconf/netconf-client/pom.xml b/opendaylight/netconf/netconf-client/pom.xml index b0f5f74810..25ed0e7ab1 100644 --- a/opendaylight/netconf/netconf-client/pom.xml +++ b/opendaylight/netconf/netconf-client/pom.xml @@ -68,6 +68,19 @@ + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + package + + test-jar + + + + diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/AbstractNetconfClientNotifySessionListener.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/AbstractNetconfClientNotifySessionListener.java deleted file mode 100644 index 6ae966d1f7..0000000000 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/AbstractNetconfClientNotifySessionListener.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.netconf.client; - -import org.opendaylight.controller.netconf.api.NetconfMessage; -import org.opendaylight.controller.netconf.util.xml.XmlElement; -import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; - -/** - * Class extending {@link NetconfClientSessionListener} to provide notification capability. - */ -public abstract class AbstractNetconfClientNotifySessionListener extends SimpleNetconfClientSessionListener { - /* - * Maybe some capabilities could be expressed as internal NetconfClientSessionListener handlers. - * It would enable NetconfClient functionality to be extended by using namespace handlers. - * So far let just enable notification capability by extending and let parent class intact. - */ - - /** - * As class purpose is to provide notification capability to session listener - * onMessage method is not allowed to be further overridden. - * {@see #onNotification(NetconfClientSession, NetconfMessage)} - * - * @param session {@see NetconfClientSessionListener#onMessage(NetconfClientSession, NetconfMessage)} - * @param message {@see NetconfClientSessionListener#onMessage(NetconfClientSession, NetconfMessage)} - */ - @Override - public final void onMessage(NetconfClientSession session, NetconfMessage message) { - if (isNotification(message)) { - onNotification(session, message); - } else { - super.onMessage(session, message); - } - } - - /** - * Method intended to customize notification processing. - * - * @param session {@see NetconfClientSessionListener#onMessage(NetconfClientSession, NetconfMessage)} - * @param message {@see NetconfClientSessionListener#onMessage(NetconfClientSession, NetconfMessage)} - */ - public abstract void onNotification(NetconfClientSession session, NetconfMessage message); - - private boolean isNotification(NetconfMessage message) { - XmlElement xmle = XmlElement.fromDomDocument(message.getDocument()); - return XmlNetconfConstants.NOTIFICATION_ELEMENT_NAME.equals(xmle.getName()) ; - } -} diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java deleted file mode 100644 index 4cdca208bc..0000000000 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClient.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.netconf.client; - -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GlobalEventExecutor; - -import java.io.Closeable; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.Set; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.opendaylight.controller.netconf.api.NetconfMessage; -import org.opendaylight.protocol.framework.NeverReconnectStrategy; -import org.opendaylight.protocol.framework.ReconnectStrategy; -import org.opendaylight.protocol.framework.TimedReconnectStrategy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Preconditions; -import com.google.common.base.Stopwatch; -import com.google.common.collect.Sets; - -/** - * @deprecated Use {@link NetconfClientDispatcher.createClient()} or {@link NetconfClientDispatcher.createReconnectingClient()} instead. - */ -@Deprecated -public class NetconfClient implements Closeable { - - private static final Logger logger = LoggerFactory.getLogger(NetconfClient.class); - - public static final int DEFAULT_CONNECT_TIMEOUT = 5000; - private final NetconfClientDispatcher dispatch; - private final String label; - private final NetconfClientSession clientSession; - private final NetconfClientSessionListener sessionListener; - private final long sessionId; - private final InetSocketAddress address; - - // TODO test reconnecting constructor - public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectionAttempts, - int attemptMsTimeout, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { - this(clientLabelForLogging, address, getReconnectStrategy(connectionAttempts, attemptMsTimeout), - netconfClientDispatcher); - } - - private NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strat, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { - this.label = clientLabelForLogging; - dispatch = netconfClientDispatcher; - sessionListener = new SimpleNetconfClientSessionListener(); - Future clientFuture = dispatch.createClient(address, sessionListener, strat); - this.address = address; - clientSession = get(clientFuture); - this.sessionId = clientSession.getSessionId(); - } - - private NetconfClientSession get(Future clientFuture) throws InterruptedException { - try { - return clientFuture.get(); - } catch (CancellationException e) { - throw new RuntimeException("Cancelling " + this, e); - } catch (ExecutionException e) { - throw new IllegalStateException("Unable to create " + this, e); - } - } - - public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { - return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher); - } - - public static NetconfClient clientFor(String clientLabelForLogging, InetSocketAddress address, - ReconnectStrategy strategy, NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException { - return new NetconfClient(clientLabelForLogging,address,strategy,netconfClientDispatcher,listener); - } - - public NetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs, - NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { - this(clientLabelForLogging, address, - new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, connectTimeoutMs), netconfClientDispatcher); - } - - public NetconfClient(String clientLabelForLogging, InetSocketAddress address, - NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { - this(clientLabelForLogging, address, new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, - DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher); - } - - public NetconfClient(String clientLabelForLogging, InetSocketAddress address, ReconnectStrategy strategy, - NetconfClientDispatcher netconfClientDispatcher, NetconfClientSessionListener listener) throws InterruptedException{ - this.label = clientLabelForLogging; - dispatch = netconfClientDispatcher; - sessionListener = listener; - Future clientFuture = dispatch.createClient(address, sessionListener, strategy); - this.address = address; - clientSession = get(clientFuture); - this.sessionId = clientSession.getSessionId(); - } - - public Future sendRequest(NetconfMessage message) { - return ((SimpleNetconfClientSessionListener)sessionListener).sendRequest(message); - } - - /** - * @deprecated Use {@link sendRequest} instead - */ - @Deprecated - public NetconfMessage sendMessage(NetconfMessage message) throws ExecutionException, InterruptedException, TimeoutException { - return sendMessage(message, 5, 1000); - } - - /** - * @deprecated Use {@link sendRequest} instead - */ - @Deprecated - public NetconfMessage sendMessage(NetconfMessage message, int attempts, int attemptMsDelay) throws ExecutionException, InterruptedException, TimeoutException { - //logger.debug("Sending message: {}",XmlUtil.toString(message.getDocument())); - final Stopwatch stopwatch = new Stopwatch().start(); - - try { - return sendRequest(message).get(attempts * attemptMsDelay, TimeUnit.MILLISECONDS); - } finally { - stopwatch.stop(); - logger.debug("Total time spent waiting for response from {}: {} ms", address, stopwatch.elapsed(TimeUnit.MILLISECONDS)); - } - } - - @Override - public void close() throws IOException { - clientSession.close(); - } - - public NetconfClientDispatcher getNetconfClientDispatcher() { - return dispatch; - } - - private static ReconnectStrategy getReconnectStrategy(int connectionAttempts, int attemptMsTimeout) { - return new TimedReconnectStrategy(GlobalEventExecutor.INSTANCE, attemptMsTimeout, 1000, 1.0, null, - Long.valueOf(connectionAttempts), null); - } - - @Override - public String toString() { - final StringBuffer sb = new StringBuffer("NetconfClient{"); - sb.append("label=").append(label); - sb.append(", sessionId=").append(sessionId); - sb.append('}'); - return sb.toString(); - } - - public long getSessionId() { - return sessionId; - } - - public Set getCapabilities() { - Preconditions.checkState(clientSession != null, "Client was not initialized successfully"); - return Sets.newHashSet(clientSession.getServerCapabilities()); - } - - public NetconfClientSession getClientSession() { - return clientSession; - } -} diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java index bb372b3aff..cff214401c 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/NetconfClientSessionNegotiatorFactory.java @@ -58,8 +58,9 @@ public class NetconfClientSessionNegotiatorFactory implements SessionNegotiatorF if(this.additionalHeader.isPresent()) { helloMessage = new NetconfHelloMessage(helloMessage.getDocument(), additionalHeader.get()); - } else + } else { helloMessage = new NetconfHelloMessage(helloMessage.getDocument()); + } NetconfSessionPreferences proposal = new NetconfSessionPreferences(helloMessage); return new NetconfClientSessionNegotiator(proposal, promise, channel, timer, diff --git a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java index e96161c29a..504e4c9949 100644 --- a/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java +++ b/opendaylight/netconf/netconf-client/src/main/java/org/opendaylight/controller/netconf/client/SimpleNetconfClientSessionListener.java @@ -101,7 +101,7 @@ public class SimpleNetconfClientSessionListener implements NetconfClientSessionL } } - final synchronized Future sendRequest(NetconfMessage message) { + public final synchronized Future sendRequest(NetconfMessage message) { final RequestEntry req = new RequestEntry(GlobalEventExecutor.INSTANCE.newPromise(), message); requests.add(req); diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/SSHNetconfClientLiveTest.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/SSHNetconfClientLiveTest.java deleted file mode 100644 index 1357201f57..0000000000 --- a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/SSHNetconfClientLiveTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.controller.netconf.client; - -import io.netty.channel.nio.NioEventLoopGroup; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.opendaylight.controller.netconf.util.handler.ssh.authentication.LoginPassword; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; - -@Ignore -public class SSHNetconfClientLiveTest { - private static final Logger logger = LoggerFactory.getLogger(SSHNetconfClientLiveTest.class); - - NioEventLoopGroup nettyThreadgroup; - NetconfSshClientDispatcher netconfClientDispatcher; - InetSocketAddress address; - final int connectionAttempts = 10, attemptMsTimeout = 1000; - final int connectionTimeoutMillis = 20000; - - @Before - public void setUp() { - nettyThreadgroup = new NioEventLoopGroup(); - - netconfClientDispatcher = new NetconfSshClientDispatcher(new LoginPassword( - System.getProperty("username"), System.getProperty("password")), - nettyThreadgroup, nettyThreadgroup, connectionTimeoutMillis); - - address = new InetSocketAddress(System.getProperty("host"), Integer.parseInt(System.getProperty("port"))); - } - - @Ignore - @Test - public void test() throws Exception { - //runnable.run(); - } - - @Test - public void testInExecutor() throws Exception { - int threads = 4; - ExecutorService executorService = Executors.newFixedThreadPool(threads); - try { - for (int i= 0;i< threads;i++) { - InetSocketAddress address = new InetSocketAddress(System.getProperty("host"), - Integer.parseInt(System.getProperty("port"))); - NetconfRunnable runnable = new NetconfRunnable(address); - executorService.execute(runnable); - } - executorService.shutdown(); - executorService.awaitTermination(1, TimeUnit.MINUTES); - - - } finally { - executorService.shutdownNow(); - } - } - - class NetconfRunnable implements Runnable { - private final InetSocketAddress address; - - NetconfRunnable(InetSocketAddress address) { - this.address = address; - } - - @Override - public void run() { - try (NetconfClient netconfClient = new NetconfClient(address.toString(), address, connectionAttempts, - attemptMsTimeout, netconfClientDispatcher);) { - logger.info("OK {}", address); - } catch (InterruptedException | IOException e) { - logger.error("Failed {}", address, e); - } - } - }; -} diff --git a/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/test/TestingNetconfClient.java b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/test/TestingNetconfClient.java new file mode 100644 index 0000000000..32c6ea85d6 --- /dev/null +++ b/opendaylight/netconf/netconf-client/src/test/java/org/opendaylight/controller/netconf/client/test/TestingNetconfClient.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.netconf.client.test; + +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GlobalEventExecutor; + +import java.io.Closeable; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.util.Set; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.opendaylight.controller.netconf.api.NetconfMessage; +import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.client.NetconfClientSession; +import org.opendaylight.controller.netconf.client.NetconfClientSessionListener; +import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener; +import org.opendaylight.protocol.framework.NeverReconnectStrategy; +import org.opendaylight.protocol.framework.ReconnectStrategy; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Sets; + + +/** + * Synchronous netconf client suitable for testing + */ +public class TestingNetconfClient implements Closeable { + + public static final int DEFAULT_CONNECT_TIMEOUT = 5000; + + private final String label; + private final NetconfClientSession clientSession; + private final NetconfClientSessionListener sessionListener; + private final long sessionId; + + private TestingNetconfClient(String clientLabel, InetSocketAddress address, ReconnectStrategy strat, + NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this.label = clientLabel; + sessionListener = new SimpleNetconfClientSessionListener(); + Future clientFuture = netconfClientDispatcher.createClient(address, sessionListener, strat); + clientSession = get(clientFuture); + this.sessionId = clientSession.getSessionId(); + } + + private NetconfClientSession get(Future clientFuture) throws InterruptedException { + try { + return clientFuture.get(); + } catch (CancellationException e) { + throw new RuntimeException("Cancelling " + this, e); + } catch (ExecutionException e) { + throw new IllegalStateException("Unable to create " + this, e); + } + } + + public TestingNetconfClient(String clientLabelForLogging, InetSocketAddress address, int connectTimeoutMs, + NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this(clientLabelForLogging, address, + new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, connectTimeoutMs), netconfClientDispatcher); + } + + public TestingNetconfClient(String clientLabelForLogging, InetSocketAddress address, + NetconfClientDispatcher netconfClientDispatcher) throws InterruptedException { + this(clientLabelForLogging, address, new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, + DEFAULT_CONNECT_TIMEOUT), netconfClientDispatcher); + } + + public Future sendRequest(NetconfMessage message) { + return ((SimpleNetconfClientSessionListener)sessionListener).sendRequest(message); + } + + public NetconfMessage sendMessage(NetconfMessage message, int attemptMsDelay) throws ExecutionException, + InterruptedException, TimeoutException { + return sendRequest(message).get(attemptMsDelay, TimeUnit.MILLISECONDS); + } + + public NetconfMessage sendMessage(NetconfMessage message) throws ExecutionException, + InterruptedException, TimeoutException { + return sendMessage(message, DEFAULT_CONNECT_TIMEOUT); + } + + @Override + public void close() throws IOException { + clientSession.close(); + } + + @Override + public String toString() { + final StringBuffer sb = new StringBuffer("TestingNetconfClient{"); + sb.append("label=").append(label); + sb.append(", sessionId=").append(sessionId); + sb.append('}'); + return sb.toString(); + } + + public long getSessionId() { + return sessionId; + } + + public Set getCapabilities() { + Preconditions.checkState(clientSession != null, "Client was not initialized successfully"); + return Sets.newHashSet(clientSession.getServerCapabilities()); + } +} \ No newline at end of file diff --git a/opendaylight/netconf/netconf-impl/pom.xml b/opendaylight/netconf/netconf-impl/pom.xml index 76a0bd9908..4e78b2e4d6 100644 --- a/opendaylight/netconf/netconf-impl/pom.xml +++ b/opendaylight/netconf/netconf-impl/pom.xml @@ -88,6 +88,13 @@ netconf-client test + + ${project.groupId} + netconf-client + ${project.version} + test-jar + test + org.opendaylight.controller commons.logback_settings @@ -150,6 +157,14 @@ org.apache.maven.plugins maven-jar-plugin 2.4 + + + package + + test-jar + + + diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java index e0d7e319be..6a86ecd21f 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/CapabilityProviderImpl.java @@ -12,9 +12,9 @@ import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot; import org.opendaylight.controller.netconf.mapping.api.Capability; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceSnapshot; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java index ee9009762e..130818b12a 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerDispatcher.java @@ -12,13 +12,12 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.util.concurrent.Promise; - -import java.net.InetSocketAddress; - import org.opendaylight.controller.netconf.impl.util.DeserializerExceptionHandler; import org.opendaylight.controller.netconf.util.AbstractChannelInitializer; import org.opendaylight.protocol.framework.AbstractDispatcher; +import java.net.InetSocketAddress; + public class NetconfServerDispatcher extends AbstractDispatcher { private final ServerChannelInitializer initializer; @@ -44,12 +43,11 @@ public class NetconfServerDispatcher extends AbstractDispatcher promise) { - ch.pipeline().addAfter(DESERIALIZER_EX_HANDLER_KEY, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR, negotiatorFactory.getSessionNegotiator(listenerFactory, ch, promise)); + ch.pipeline().addAfter(DESERIALIZER_EX_HANDLER_KEY, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR, + negotiatorFactory.getSessionNegotiator(null, ch, promise)); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java index f8d9a45c20..86cfac0b60 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java @@ -8,8 +8,8 @@ package org.opendaylight.controller.netconf.impl; -import static com.google.common.base.Preconditions.checkState; - +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.api.NetconfOperationRouter; @@ -25,8 +25,7 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; +import static com.google.common.base.Preconditions.checkState; public class NetconfServerSessionListener implements NetconfSessionListener { public static final String MESSAGE_ID = "message-id"; @@ -34,10 +33,13 @@ public class NetconfServerSessionListener implements NetconfSessionListener { - private final NetconfOperationServiceFactoryListener factoriesListener; - private final DefaultCommitNotificationProducer commitNotifier; - - private final SessionIdProvider idProvider; - private final SessionMonitoringService monitor; + private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot; + private final CapabilityProvider capabilityProvider; + + public NetconfServerSessionListenerFactory(DefaultCommitNotificationProducer commitNotifier, + SessionMonitoringService monitor, + NetconfOperationServiceSnapshot netconfOperationServiceSnapshot, + CapabilityProvider capabilityProvider) { - public NetconfServerSessionListenerFactory(NetconfOperationServiceFactoryListener factoriesListener, - DefaultCommitNotificationProducer commitNotifier, - SessionIdProvider idProvider, SessionMonitoringService monitor) { - this.factoriesListener = factoriesListener; this.commitNotifier = commitNotifier; - this.idProvider = idProvider; this.monitor = monitor; + this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot; + this.capabilityProvider = capabilityProvider; } @Override public NetconfServerSessionListener getSessionListener() { - NetconfOperationServiceSnapshot netconfOperationServiceSnapshot = factoriesListener.getSnapshot(idProvider - .getCurrentSessionId()); - - CapabilityProvider capabilityProvider = new CapabilityProviderImpl(netconfOperationServiceSnapshot); - NetconfOperationRouter operationRouter = NetconfOperationRouterImpl.createOperationRouter( - netconfOperationServiceSnapshot, capabilityProvider, - commitNotifier); - - return new NetconfServerSessionListener(operationRouter, monitor); + netconfOperationServiceSnapshot, capabilityProvider, commitNotifier); + return new NetconfServerSessionListener(operationRouter, monitor, netconfOperationServiceSnapshot); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiator.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiator.java index f8024922cf..5c389fa966 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiator.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiator.java @@ -8,8 +8,10 @@ package org.opendaylight.controller.netconf.impl; -import java.net.InetSocketAddress; - +import com.google.common.base.Optional; +import io.netty.channel.Channel; +import io.netty.util.Timer; +import io.netty.util.concurrent.Promise; import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences; import org.opendaylight.controller.netconf.util.AbstractNetconfSessionNegotiator; import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage; @@ -17,11 +19,7 @@ import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAddi import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Optional; - -import io.netty.channel.Channel; -import io.netty.util.Timer; -import io.netty.util.concurrent.Promise; +import java.net.InetSocketAddress; public class NetconfServerSessionNegotiator extends AbstractNetconfSessionNegotiator { @@ -52,4 +50,4 @@ public class NetconfServerSessionNegotiator extends return new NetconfServerSession(sessionListener, channel, getSessionPreferences().getSessionId(), parsedHeader); } - } +} diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java index 4c551a6020..9ffb8da1dd 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionNegotiatorFactory.java @@ -19,7 +19,9 @@ import javax.xml.xpath.XPathExpression; import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences; import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener; +import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceSnapshot; import org.opendaylight.controller.netconf.util.NetconfUtil; import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessage; import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil; @@ -35,6 +37,8 @@ import org.w3c.dom.Node; import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import static org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider.NetconfOperationProviderUtil.getNetconfSessionIdForReporting; + public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorFactory { public static final String SERVER_HELLO_XML_LOCATION = "/server_hello.xml"; @@ -43,15 +47,20 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF private static final Document helloMessageTemplate = loadHelloMessageTemplate(); private final SessionIdProvider idProvider; - private final NetconfOperationServiceFactoryListener factoriesListener; + private final NetconfOperationProvider netconfOperationProvider; private final long connectionTimeoutMillis; + private final DefaultCommitNotificationProducer commitNotificationProducer; + private final SessionMonitoringService monitoringService; - public NetconfServerSessionNegotiatorFactory(Timer timer, NetconfOperationServiceFactoryListener factoriesListener, - SessionIdProvider idProvider, long connectionTimeoutMillis) { + public NetconfServerSessionNegotiatorFactory(Timer timer, NetconfOperationProvider netconfOperationProvider, + SessionIdProvider idProvider, long connectionTimeoutMillis, + DefaultCommitNotificationProducer commitNot, SessionMonitoringService monitoringService) { this.timer = timer; - this.factoriesListener = factoriesListener; + this.netconfOperationProvider = netconfOperationProvider; this.idProvider = idProvider; this.connectionTimeoutMillis = connectionTimeoutMillis; + this.commitNotificationProducer = commitNot; + this.monitoringService = monitoringService; } private static Document loadHelloMessageTemplate() { @@ -62,13 +71,30 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF return NetconfUtil.createMessage(resourceAsStream).getDocument(); } + /** + * + * @param defunctSessionListenerFactory will not be taken into account as session listener factory can + * only be created after snapshot is opened, thus this method constructs + * proper session listener factory. + * @param channel Underlying channel + * @param promise Promise to be notified + * @return session negotiator + */ @Override - public SessionNegotiator getSessionNegotiator(SessionListenerFactory sessionListenerFactory, Channel channel, - Promise promise) { + public SessionNegotiator getSessionNegotiator(SessionListenerFactory defunctSessionListenerFactory, + Channel channel, Promise promise) { long sessionId = idProvider.getNextSessionId(); + NetconfOperationServiceSnapshot netconfOperationServiceSnapshot = netconfOperationProvider.openSnapshot( + getNetconfSessionIdForReporting(sessionId)); + CapabilityProvider capabilityProvider = new CapabilityProviderImpl(netconfOperationServiceSnapshot); + + NetconfServerSessionPreferences proposal = new NetconfServerSessionPreferences( + createHelloMessage(sessionId, capabilityProvider), sessionId); + + NetconfServerSessionListenerFactory sessionListenerFactory = new NetconfServerSessionListenerFactory( + commitNotificationProducer, monitoringService, + netconfOperationServiceSnapshot, capabilityProvider); - NetconfServerSessionPreferences proposal = new NetconfServerSessionPreferences(createHelloMessage(sessionId), - sessionId); return new NetconfServerSessionNegotiator(proposal, promise, channel, timer, sessionListenerFactory.getSessionListener(), connectionTimeoutMillis); } @@ -78,7 +104,7 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF private static final XPathExpression capabilitiesXPath = XMLNetconfUtil .compileXPath("/netconf:hello/netconf:capabilities"); - private NetconfHelloMessage createHelloMessage(long sessionId) { + private NetconfHelloMessage createHelloMessage(long sessionId, CapabilityProvider capabilityProvider) { Document helloMessageTemplate = getHelloTemplateClone(); // change session ID @@ -90,8 +116,6 @@ public class NetconfServerSessionNegotiatorFactory implements SessionNegotiatorF final Element capabilitiesElement = (Element) XmlUtil.evaluateXPath(capabilitiesXPath, helloMessageTemplate, XPathConstants.NODE); - CapabilityProvider capabilityProvider = new CapabilityProviderImpl(factoriesListener.getSnapshot(sessionId)); - for (String capability : capabilityProvider.getCapabilities()) { final Element capabilityElement = XmlUtil.createElement(helloMessageTemplate, XmlNetconfConstants.CAPABILITY, Optional.absent()); capabilityElement.setTextContent(capability); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSession.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSession.java index 2b48f5d51c..f31233987e 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSession.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSession.java @@ -8,8 +8,6 @@ package org.opendaylight.controller.netconf.impl.mapping.operations; -import java.util.Collections; - import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -20,6 +18,8 @@ import org.w3c.dom.Element; import com.google.common.base.Optional; +import java.util.Collections; + public class DefaultCloseSession extends AbstractSingletonNetconfOperation { public static final String CLOSE_SESSION = "close-session"; private final AutoCloseable sessionResources; diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java index b8dc9550c7..bbd07e42bf 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java @@ -12,9 +12,9 @@ import io.netty.util.HashedWheelTimer; import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; -import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory; import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory; import org.opendaylight.controller.netconf.impl.SessionIdProvider; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -34,7 +34,6 @@ public class NetconfImplActivator implements BundleActivator { private NetconfOperationServiceFactoryTracker factoriesTracker; private DefaultCommitNotificationProducer commitNot; - private NetconfServerDispatcher dispatch; private NioEventLoopGroup eventLoopGroup; private HashedWheelTimer timer; private ServiceRegistration regMonitoring; @@ -50,25 +49,26 @@ public class NetconfImplActivator implements BundleActivator { SessionIdProvider idProvider = new SessionIdProvider(); timer = new HashedWheelTimer(); long connectionTimeoutMillis = NetconfConfigUtil.extractTimeoutMillis(context); - NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory( - timer, factoriesListener, idProvider, connectionTimeoutMillis); + commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer()); - NetconfMonitoringServiceImpl monitoringService = startMonitoringService(context, factoriesListener); + SessionMonitoringService monitoringService = startMonitoringService(context, factoriesListener); - NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory( - factoriesListener, commitNot, idProvider, monitoringService); + NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory( + timer, factoriesListener, idProvider, connectionTimeoutMillis, commitNot, monitoringService); eventLoopGroup = new NioEventLoopGroup(); NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer( - serverNegotiatorFactory, listenerFactory); - dispatch = new NetconfServerDispatcher(serverChannelInitializer, eventLoopGroup, eventLoopGroup); + serverNegotiatorFactory); + NetconfServerDispatcher dispatch = new NetconfServerDispatcher(serverChannelInitializer, eventLoopGroup, eventLoopGroup); logger.info("Starting TCP netconf server at {}", address); dispatch.createServer(address); + context.registerService(NetconfOperationProvider.class, factoriesListener, null); + } private void startOperationServiceFactoryTracker(BundleContext context, NetconfOperationServiceFactoryListenerImpl factoriesListener) { diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java index 505c74714a..a7560fadb6 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfMonitoringServiceImpl.java @@ -16,7 +16,9 @@ import io.netty.util.internal.ConcurrentSet; import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession; import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService; import org.opendaylight.controller.netconf.mapping.api.Capability; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceSnapshot; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Yang; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas; @@ -40,10 +42,10 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S private static final Logger logger = LoggerFactory.getLogger(NetconfMonitoringServiceImpl.class); private final Set sessions = new ConcurrentSet<>(); - private final NetconfOperationServiceFactoryListener factoriesListener; + private final NetconfOperationProvider netconfOperationProvider; - public NetconfMonitoringServiceImpl(NetconfOperationServiceFactoryListener factoriesListener) { - this.factoriesListener = factoriesListener; + public NetconfMonitoringServiceImpl(NetconfOperationProvider netconfOperationProvider) { + this.netconfOperationProvider = netconfOperationProvider; } @Override @@ -56,7 +58,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S @Override public void onSessionDown(NetconfManagementSession session) { logger.debug("Session {} down", session); - Preconditions.checkState(sessions.contains(session) == true, "Session %s not present", session); + Preconditions.checkState(sessions.contains(session), "Session %s not present", session); sessions.remove(session); } @@ -67,17 +69,23 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S @Override public Schemas getSchemas() { - // FIXME, session ID // capabilities should be split from operations (it will allow to move getSchema operation to monitoring module) - return transformSchemas(factoriesListener.getSnapshot(0)); + try (NetconfOperationServiceSnapshot snapshot = netconfOperationProvider.openSnapshot("netconf-monitoring")) { + return transformSchemas(snapshot.getServices()); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new IllegalStateException("Exception while closing", e); + } } - private Schemas transformSchemas(NetconfOperationServiceSnapshot snapshot) { + private Schemas transformSchemas(Set services) { Set caps = Sets.newHashSet(); List schemas = Lists.newArrayList(); - for (NetconfOperationService netconfOperationService : snapshot.getServices()) { + + for (NetconfOperationService netconfOperationService : services) { // TODO check for duplicates ? move capability merging to snapshot // Split capabilities from operations first and delete this duplicate code caps.addAll(netconfOperationService.getCapabilities()); @@ -86,8 +94,9 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S for (Capability cap : caps) { SchemaBuilder builder = new SchemaBuilder(); - if(cap.getCapabilitySchema().isPresent() == false) + if (cap.getCapabilitySchema().isPresent() == false) { continue; + } Preconditions.checkState(cap.getModuleNamespace().isPresent()); builder.setNamespace(new Uri(cap.getModuleNamespace().get())); @@ -102,7 +111,7 @@ public class NetconfMonitoringServiceImpl implements NetconfMonitoringService, S builder.setFormat(Yang.class); - builder.setLocation(transformLocations(cap.getLocation().or(Collections. emptyList()))); + builder.setLocation(transformLocations(cap.getLocation().or(Collections.emptyList()))); builder.setKey(new SchemaKey(Yang.class, identifier, version)); diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java index a358514453..80ba8388ef 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java @@ -25,6 +25,7 @@ import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceSnapshot; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -107,11 +108,11 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { String errorMessage = String.format("Unable to handle rpc %s on session %s", messageAsString, session); Map errorInfo = Maps.newHashMap(); - NetconfDocumentedException.ErrorTag tag = null; + NetconfDocumentedException.ErrorTag tag; if (e instanceof IllegalArgumentException) { errorInfo.put(NetconfDocumentedException.ErrorTag.operation_not_supported.toString(), e.getMessage()); tag = NetconfDocumentedException.ErrorTag.operation_not_supported; - } else if (e instanceof IllegalStateException) { + } else { errorInfo.put(NetconfDocumentedException.ErrorTag.operation_failed.toString(), e.getMessage()); tag = NetconfDocumentedException.ErrorTag.operation_failed; } @@ -130,7 +131,7 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter { } @Override - public void close() { + public void close() throws Exception { netconfOperationServiceSnapshot.close(); } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceFactoryListener.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceFactoryListener.java index 385ad09754..8e1052cfeb 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceFactoryListener.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceFactoryListener.java @@ -16,5 +16,5 @@ public interface NetconfOperationServiceFactoryListener { void onRemoveNetconfOperationServiceFactory(NetconfOperationServiceFactory service); - NetconfOperationServiceSnapshot getSnapshot(long sessionId); + } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceFactoryListenerImpl.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceFactoryListenerImpl.java index 134c38ba97..63cd0baf34 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceFactoryListenerImpl.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceFactoryListenerImpl.java @@ -7,12 +7,14 @@ */ package org.opendaylight.controller.netconf.impl.osgi; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory; + import java.util.HashSet; import java.util.Set; -import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory; - -public class NetconfOperationServiceFactoryListenerImpl implements NetconfOperationServiceFactoryListener { +public class NetconfOperationServiceFactoryListenerImpl implements NetconfOperationServiceFactoryListener, + NetconfOperationProvider { private final Set allFactories = new HashSet<>(); @Override @@ -26,8 +28,8 @@ public class NetconfOperationServiceFactoryListenerImpl implements NetconfOperat } @Override - public synchronized NetconfOperationServiceSnapshot getSnapshot(long sessionId) { - return new NetconfOperationServiceSnapshot(allFactories, sessionId); + public synchronized NetconfOperationServiceSnapshotImpl openSnapshot(String sessionIdForReporting) { + return new NetconfOperationServiceSnapshotImpl(allFactories, sessionIdForReporting); } } diff --git a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceSnapshot.java b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceSnapshotImpl.java similarity index 51% rename from opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceSnapshot.java rename to opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceSnapshotImpl.java index 5c08505091..ce312548b2 100644 --- a/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceSnapshot.java +++ b/opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationServiceSnapshotImpl.java @@ -10,62 +10,46 @@ package org.opendaylight.controller.netconf.impl.osgi; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceSnapshot; +import org.opendaylight.controller.netconf.util.CloseableUtil; import java.util.Collections; import java.util.HashSet; import java.util.Set; -public class NetconfOperationServiceSnapshot implements AutoCloseable { - private static final Logger logger = LoggerFactory.getLogger(NetconfOperationServiceSnapshot.class); +public class NetconfOperationServiceSnapshotImpl implements NetconfOperationServiceSnapshot { private final Set services; private final String netconfSessionIdForReporting; - public NetconfOperationServiceSnapshot(Set factories, long sessionId) { + public NetconfOperationServiceSnapshotImpl(Set factories, String sessionIdForReporting) { Set services = new HashSet<>(); - netconfSessionIdForReporting = getNetconfSessionIdForReporting(sessionId); + netconfSessionIdForReporting = sessionIdForReporting; for (NetconfOperationServiceFactory factory : factories) { services.add(factory.createService(netconfSessionIdForReporting)); } this.services = Collections.unmodifiableSet(services); } - private static String getNetconfSessionIdForReporting(long sessionId) { - return "netconf session id " + sessionId; - } + + @Override public String getNetconfSessionIdForReporting() { return netconfSessionIdForReporting; } + @Override public Set getServices() { return services; } @Override - public void close() { - RuntimeException firstException = null; - for (NetconfOperationService service : services) { - try { - service.close(); - } catch (RuntimeException e) { - logger.warn("Got exception while closing {}", service, e); - if (firstException == null) { - firstException = e; - } else { - firstException.addSuppressed(e); - } - } - } - if (firstException != null) { - throw firstException; - } + public void close() throws Exception { + CloseableUtil.closeAll(services); } @Override public String toString() { - return "NetconfOperationServiceSnapshot{" + netconfSessionIdForReporting + '}'; + return "NetconfOperationServiceSnapshotImpl{" + netconfSessionIdForReporting + '}'; } } diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java index c1a7b1478b..db5a359d7a 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java @@ -18,10 +18,9 @@ import org.apache.commons.io.IOUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.mockito.Mock; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; -import org.opendaylight.controller.netconf.client.NetconfClient; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; @@ -53,7 +52,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doNothing; -import static org.mockito.MockitoAnnotations.initMocks; +import static org.mockito.Mockito.mock; public class ConcurrentClientsTest { @@ -68,14 +67,20 @@ public class ConcurrentClientsTest { private DefaultCommitNotificationProducer commitNot; private NetconfServerDispatcher dispatch; - @Mock - private SessionMonitoringService monitoring; + HashedWheelTimer hashedWheelTimer; + public static SessionMonitoringService createMockedMonitoringService() { + SessionMonitoringService monitoring = mock(SessionMonitoringService.class); + doNothing().when(monitoring).onSessionUp(any(NetconfServerSession.class)); + doNothing().when(monitoring).onSessionDown(any(NetconfServerSession.class)); + return monitoring; + } + @Before public void setUp() throws Exception { - initMocks(this); + nettyGroup = new NioEventLoopGroup(); NetconfHelloMessageAdditionalHeader additionalHeader = new NetconfHelloMessageAdditionalHeader("uname", "10.10.10.1", "830", "tcp", "client"); netconfClientDispatcher = new NetconfClientDispatcher( nettyGroup, nettyGroup, additionalHeader, 5000); @@ -86,16 +91,13 @@ public class ConcurrentClientsTest { SessionIdProvider idProvider = new SessionIdProvider(); hashedWheelTimer = new HashedWheelTimer(); NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory( - hashedWheelTimer, factoriesListener, idProvider, 5000); + hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, createMockedMonitoringService()); commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer()); - doNothing().when(monitoring).onSessionUp(any(NetconfServerSession.class)); - doNothing().when(monitoring).onSessionDown(any(NetconfServerSession.class)); - NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory( - factoriesListener, commitNot, idProvider, monitoring); - NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory, listenerFactory); + + NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory); dispatch = new NetconfServerDispatcher(serverChannelInitializer, nettyGroup, nettyGroup); ChannelFuture s = dispatch.createServer(netconfAddress); @@ -259,13 +261,13 @@ public class ConcurrentClientsTest { @Override public void run() { try { - final NetconfClient netconfClient = new NetconfClient(clientId, netconfAddress, netconfClientDispatcher); + final TestingNetconfClient netconfClient = new TestingNetconfClient(clientId, netconfAddress, netconfClientDispatcher); long sessionId = netconfClient.getSessionId(); logger.info("Client with sessionid {} hello exchanged", sessionId); final NetconfMessage getMessage = XmlFileLoader .xmlFileToNetconfMessage("netconfMessages/getConfig.xml"); - NetconfMessage result = netconfClient.sendMessage(getMessage); + NetconfMessage result = netconfClient.sendRequest(getMessage).get(); logger.info("Client with sessionid {} got result {}", sessionId, result); netconfClient.close(); logger.info("Client with session id {} ended", sessionId); diff --git a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java index 9835c2393b..42bd033c71 100644 --- a/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java +++ b/opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/NetconfDispatcherImplTest.java @@ -15,7 +15,6 @@ import io.netty.util.HashedWheelTimer; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; import java.lang.management.ManagementFactory; @@ -28,22 +27,21 @@ public class NetconfDispatcherImplTest { private DefaultCommitNotificationProducer commitNot; private HashedWheelTimer hashedWheelTimer; + @Before public void setUp() throws Exception { nettyGroup = new NioEventLoopGroup(); commitNot = new DefaultCommitNotificationProducer( ManagementFactory.getPlatformMBeanServer()); - NetconfOperationServiceFactoryListener factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); + NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); SessionIdProvider idProvider = new SessionIdProvider(); hashedWheelTimer = new HashedWheelTimer(); NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory( - hashedWheelTimer, factoriesListener, idProvider, 5000); + hashedWheelTimer, factoriesListener, idProvider, 5000, commitNot, ConcurrentClientsTest.createMockedMonitoringService()); - NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory( - factoriesListener, commitNot, idProvider, null); - NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory, listenerFactory); + NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer(serverNegotiatorFactory); dispatch = new NetconfServerDispatcher( serverChannelInitializer, nettyGroup, nettyGroup); diff --git a/opendaylight/netconf/netconf-it/pom.xml b/opendaylight/netconf/netconf-it/pom.xml index aab939e8d9..3ca79be9d9 100644 --- a/opendaylight/netconf/netconf-it/pom.xml +++ b/opendaylight/netconf/netconf-it/pom.xml @@ -1,6 +1,9 @@ 4.0.0 + + 2.0.0 + netconf-subsystem @@ -33,11 +36,23 @@ netconf-client test + + ${project.groupId} + netconf-client + ${project.version} + test-jar + test + ${project.groupId} config-netconf-connector test + + ${project.groupId} + netty-config-api + test + ${project.groupId} config-manager @@ -59,6 +74,12 @@ netconf-impl test + + ${project.groupId} + netconf-impl + test + test-jar + ${project.groupId} netconf-monitoring @@ -114,6 +135,12 @@ org.opendaylight.controller commons.logback_settings + + org.ops4j.pax.tinybundles + tinybundles + ${tinybundles.version} + test + diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java index b261218bf1..b81f950cb3 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/AbstractNetconfConfigTest.java @@ -15,7 +15,6 @@ import org.junit.Before; import org.opendaylight.controller.config.manager.impl.AbstractConfigTest; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; -import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory; import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory; import org.opendaylight.controller.netconf.impl.SessionIdProvider; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; @@ -39,14 +38,10 @@ public class AbstractNetconfConfigTest extends AbstractConfigTest { SessionIdProvider idProvider = new SessionIdProvider(); NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory( - hashedWheelTimer, factoriesListener, idProvider, 5000); - - NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory( - factoriesListener, commitNotifier, idProvider, - sessionMonitoringService); + hashedWheelTimer, factoriesListener, idProvider, 5000, commitNotifier, sessionMonitoringService); NetconfServerDispatcher.ServerChannelInitializer serverChannelInitializer = new NetconfServerDispatcher.ServerChannelInitializer( - serverNegotiatorFactory, listenerFactory); + serverNegotiatorFactory); return new NetconfServerDispatcher(serverChannelInitializer, nettyThreadgroup, nettyThreadgroup); } diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java index 997cae0f7c..fc1c73f7b0 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java @@ -25,16 +25,16 @@ import org.opendaylight.controller.config.spi.ModuleFactory; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification; import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession; -import org.opendaylight.controller.netconf.client.NetconfClient; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl; import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; import org.opendaylight.controller.netconf.mapping.api.Capability; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; @@ -57,7 +57,7 @@ import java.util.Set; import static junit.framework.Assert.assertEquals; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -78,7 +78,7 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest { super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray( new ModuleFactory[0]))); - NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getFactoriesListener()); + NetconfMonitoringServiceImpl monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider()); NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore())); @@ -121,12 +121,12 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest { VerifyingNotificationListener notificationVerifier = createCommitNotificationListener(); VerifyingPersister mockedAggregator = mockAggregator(); - try (NetconfClient persisterClient = new NetconfClient("persister", tcpAddress, 4000, clientDispatcher)) { + try (TestingNetconfClient persisterClient = new TestingNetconfClient("persister", tcpAddress, 4000, clientDispatcher)) { try (ConfigPersisterNotificationHandler configPersisterNotificationHandler = new ConfigPersisterNotificationHandler( platformMBeanServer, mockedAggregator)) { - try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, clientDispatcher)) { + try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", tcpAddress, 4000, clientDispatcher)) { NetconfMessage response = netconfClient.sendMessage(loadGetConfigMessage()); assertResponse(response, " caps = Sets.newHashSet(); doReturn(caps).when(service).getCapabilities(); Set services = Sets.newHashSet(service); doReturn(services).when(snap).getServices(); - doReturn(snap).when(factoriesListener).getSnapshot(anyLong()); + doReturn(snap).when(factoriesListener).openSnapshot(anyString()); return factoriesListener; } diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java index 6989bf512f..e45a249ad4 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java @@ -14,10 +14,10 @@ import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; import org.opendaylight.controller.config.spi.ModuleFactory; -import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; -import org.opendaylight.controller.netconf.client.NetconfClient; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; +import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; @@ -91,7 +91,7 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest { @Test public void testSecure() throws Exception { NetconfClientDispatcher dispatch = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup, 5000); - try (NetconfClient netconfClient = new NetconfClient("tls-client", tlsAddress, 4000, dispatch)) { + try (TestingNetconfClient netconfClient = new TestingNetconfClient("tls-client", tlsAddress, 4000, dispatch)) { } } diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index 4ca9690211..ae4a9bf4b2 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -28,16 +28,16 @@ import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMX import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory; import org.opendaylight.controller.netconf.StubUserManager; import org.opendaylight.controller.netconf.api.NetconfMessage; -import org.opendaylight.controller.netconf.client.NetconfClient; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; import org.opendaylight.controller.netconf.ssh.NetconfSSHServer; import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider; @@ -71,7 +71,7 @@ import static java.util.Collections.emptyList; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertTrue; -import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; @@ -118,11 +118,11 @@ public class NetconfITTest extends AbstractNetconfConfigTest { } static NetconfMonitoringServiceImpl getNetconfMonitoringListenerService() { - NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class); - NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class); + NetconfOperationProvider netconfOperationProvider = mock(NetconfOperationProvider.class); + NetconfOperationServiceSnapshotImpl snap = mock(NetconfOperationServiceSnapshotImpl.class); doReturn(Collections.emptySet()).when(snap).getServices(); - doReturn(snap).when(factoriesListener).getSnapshot(anyLong()); - return new NetconfMonitoringServiceImpl(factoriesListener); + doReturn(snap).when(netconfOperationProvider).openSnapshot(anyString()); + return new NetconfMonitoringServiceImpl(netconfOperationProvider); } @After @@ -176,7 +176,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void testNetconfClientDemonstration() throws Exception { - try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, 4000, clientDispatcher)) { + try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", tcpAddress, 4000, clientDispatcher)) { Set capabilitiesFromNetconfServer = netconfClient.getCapabilities(); long sessionId = netconfClient.getSessionId(); @@ -191,8 +191,8 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void testTwoSessions() throws Exception { - try (NetconfClient netconfClient = new NetconfClient("1", tcpAddress, 10000, clientDispatcher)) { - try (NetconfClient netconfClient2 = new NetconfClient("2", tcpAddress, 10000, clientDispatcher)) { + try (TestingNetconfClient netconfClient = new TestingNetconfClient("1", tcpAddress, 10000, clientDispatcher)) { + try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("2", tcpAddress, 10000, clientDispatcher)) { } } } @@ -208,7 +208,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void rpcReplyContainsAllAttributesTest() throws Exception { - try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { final String rpc = "" + "" + ""; final Document doc = XmlUtil.readXmlToDocument(rpc); @@ -236,7 +236,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void rpcReplyErrorContainsAllAttributesTest() throws Exception { - try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { final String rpc = "" + "" + ""; final Document doc = XmlUtil.readXmlToDocument(rpc); @@ -260,7 +260,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { transaction.commit(); - try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { final String expectedNamespace = "urn:opendaylight:params:xml:ns:yang:controller:test:impl"; final String rpc = "" @@ -284,7 +284,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { /* @Test public void testStartExi() throws Exception { - try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { Document rpcReply = netconfClient.sendMessage(this.startExi) @@ -311,7 +311,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void testCloseSession() throws Exception { - try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { // edit config Document rpcReply = netconfClient.sendMessage(this.editConfig) @@ -327,7 +327,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void testEditConfig() throws Exception { - try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { // send edit_config.xml final Document rpcReply = netconfClient.sendMessage(this.editConfig).getDocument(); assertIsOK(rpcReply); @@ -336,7 +336,7 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void testValidate() throws Exception { - try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { // begin transaction Document rpcReply = netconfClient.sendMessage(getConfigCandidate).getDocument(); assertEquals("data", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName()); @@ -353,11 +353,11 @@ public class NetconfITTest extends AbstractNetconfConfigTest { assertEquals("ok", XmlElement.fromDomDocument(rpcReply).getOnlyChildElement().getName()); } - private Document assertGetConfigWorks(final NetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException { + private Document assertGetConfigWorks(final TestingNetconfClient netconfClient) throws InterruptedException, ExecutionException, TimeoutException { return assertGetConfigWorks(netconfClient, this.getConfig); } - private Document assertGetConfigWorks(final NetconfClient netconfClient, final NetconfMessage getConfigMessage) + private Document assertGetConfigWorks(final TestingNetconfClient netconfClient, final NetconfMessage getConfigMessage) throws InterruptedException, ExecutionException, TimeoutException { final NetconfMessage rpcReply = netconfClient.sendMessage(getConfigMessage); assertNotNull(rpcReply); @@ -367,14 +367,14 @@ public class NetconfITTest extends AbstractNetconfConfigTest { @Test public void testGetConfig() throws Exception { - try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { assertGetConfigWorks(netconfClient); } } @Test public void createYangTestBasedOnYuma() throws Exception { - try (NetconfClient netconfClient = createSession(tcpAddress, "1")) { + try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) { Document rpcReply = netconfClient.sendMessage( XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/editConfig_merge_yang-test.xml")) .getDocument(); @@ -392,8 +392,8 @@ public class NetconfITTest extends AbstractNetconfConfigTest { } } - private NetconfClient createSession(final InetSocketAddress address, final String expected) throws Exception { - final NetconfClient netconfClient = new NetconfClient("test " + address.toString(), address, 5000, clientDispatcher); + private TestingNetconfClient createSession(final InetSocketAddress address, final String expected) throws Exception { + final TestingNetconfClient netconfClient = new TestingNetconfClient("test " + address.toString(), address, 5000, clientDispatcher); assertEquals(expected, Long.toString(netconfClient.getSessionId())); return netconfClient; } diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java index 4af66532a1..e36261c6eb 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java @@ -7,54 +7,54 @@ */ package org.opendaylight.controller.netconf.it; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; +import com.google.common.base.Charsets; +import com.google.common.base.Optional; +import com.google.common.collect.Sets; import io.netty.channel.ChannelFuture; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.util.Collection; -import java.util.List; -import java.util.Set; - import junit.framework.Assert; - import org.junit.Before; import org.junit.Test; import org.junit.matchers.JUnitMatchers; import org.mockito.Mock; import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver; import org.opendaylight.controller.config.spi.ModuleFactory; -import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession; -import org.opendaylight.controller.netconf.client.NetconfClient; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl; +import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException; import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer; import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher; import org.opendaylight.controller.netconf.impl.osgi.NetconfMonitoringServiceImpl; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener; +import org.opendaylight.controller.netconf.mapping.api.NetconfOperationProvider; import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl; -import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot; +import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshotImpl; import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService; import org.opendaylight.controller.netconf.mapping.api.Capability; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService; import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringActivator; import org.opendaylight.controller.netconf.monitoring.osgi.NetconfMonitoringOperationService; import org.opendaylight.controller.netconf.util.test.XmlFileLoader; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; -import com.google.common.base.Charsets; -import com.google.common.base.Optional; -import com.google.common.collect.Sets; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; public class NetconfMonitoringITTest extends AbstractNetconfConfigTest { @@ -75,7 +75,7 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest { super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(NetconfITTest.getModuleFactoriesS().toArray( new ModuleFactory[0]))); - monitoringService = new NetconfMonitoringServiceImpl(getFactoriesListener()); + monitoringService = new NetconfMonitoringServiceImpl(getNetconfOperationProvider()); NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl(); factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore())); @@ -120,8 +120,8 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest { @Test public void testGetResponseFromMonitoring() throws Exception { - try (NetconfClient netconfClient = new NetconfClient("client-monitoring", tcpAddress, 4000, clientDispatcher)) { - try (NetconfClient netconfClient2 = new NetconfClient("client-monitoring2", tcpAddress, 4000, clientDispatcher)) { + try (TestingNetconfClient netconfClient = new TestingNetconfClient("client-monitoring", tcpAddress, 4000, clientDispatcher)) { + try (TestingNetconfClient netconfClient2 = new TestingNetconfClient("client-monitoring2", tcpAddress, 4000, clientDispatcher)) { NetconfMessage response = netconfClient.sendMessage(loadGetMessage()); assertSessionElementsInResponse(response.getDocument(), 2); } @@ -171,16 +171,17 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest { private void assertSessionElementsInResponse(Document document, int i) { int elementSize = document.getElementsByTagName("session-id").getLength(); - Assert.assertEquals(i, elementSize); + Assert.assertEquals("Incorrect number of session-id tags in " + XmlUtil.toString(document),i, elementSize); } private NetconfMessage loadGetMessage() throws Exception { return XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/get.xml"); } - public static NetconfOperationServiceFactoryListener getFactoriesListener() { - NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class); - NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class); + public static NetconfOperationProvider getNetconfOperationProvider() throws Exception { + NetconfOperationProvider factoriesListener = mock(NetconfOperationProvider.class); + NetconfOperationServiceSnapshotImpl snap = mock(NetconfOperationServiceSnapshotImpl.class); + doNothing().when(snap).close(); NetconfOperationService service = mock(NetconfOperationService.class); Set caps = Sets.newHashSet(); caps.add(new Capability() { @@ -218,7 +219,7 @@ public class NetconfMonitoringITTest extends AbstractNetconfConfigTest { doReturn(caps).when(service).getCapabilities(); Set services = Sets.newHashSet(service); doReturn(services).when(snap).getServices(); - doReturn(snap).when(factoriesListener).getSnapshot(anyLong()); + doReturn(snap).when(factoriesListener).openSnapshot(anyString()); return factoriesListener; } diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java index c75adbba8d..18275ad78b 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java @@ -7,6 +7,22 @@ */ package org.opendaylight.controller.netconf.it.pax; +import static org.junit.Assert.fail; +import static org.opendaylight.controller.test.sal.binding.it.TestHelper.baseModelBundles; +import static org.opendaylight.controller.test.sal.binding.it.TestHelper.bindingAwareSalBundles; +import static org.opendaylight.controller.test.sal.binding.it.TestHelper.configMinumumBundles; +import static org.opendaylight.controller.test.sal.binding.it.TestHelper.flowCapableModelBundles; +import static org.opendaylight.controller.test.sal.binding.it.TestHelper.junitAndMockitoBundles; +import static org.opendaylight.controller.test.sal.binding.it.TestHelper.mdSalCoreBundles; +import static org.ops4j.pax.exam.CoreOptions.mavenBundle; +import static org.ops4j.pax.exam.CoreOptions.options; +import static org.ops4j.pax.exam.CoreOptions.streamBundle; +import static org.ops4j.pax.exam.CoreOptions.systemPackages; +import static org.ops4j.pax.exam.CoreOptions.systemProperty; + +import javax.inject.Inject; +import javax.xml.parsers.ParserConfigurationException; + import com.google.common.base.Preconditions; import com.google.common.base.Throwables; import io.netty.channel.nio.NioEventLoopGroup; @@ -16,8 +32,9 @@ import org.junit.Test; import org.junit.matchers.JUnitMatchers; import org.junit.runner.RunWith; import org.opendaylight.controller.netconf.api.NetconfMessage; -import org.opendaylight.controller.netconf.client.NetconfClient; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; +import org.opendaylight.controller.netconf.client.test.TestingNetconfClient; +import org.opendaylight.controller.netconf.util.test.XmlFileLoader; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.ops4j.pax.exam.Configuration; @@ -25,29 +42,15 @@ import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.ops4j.pax.exam.options.DefaultCompositeOption; import org.ops4j.pax.exam.util.Filter; -import org.w3c.dom.Document; +import org.ops4j.pax.tinybundles.core.TinyBundles; +import org.osgi.framework.Constants; import org.xml.sax.SAXException; -import javax.inject.Inject; -import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; -import java.io.InputStream; import java.net.InetSocketAddress; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import static org.junit.Assert.fail; -import static org.opendaylight.controller.test.sal.binding.it.TestHelper.baseModelBundles; -import static org.opendaylight.controller.test.sal.binding.it.TestHelper.bindingAwareSalBundles; -import static org.opendaylight.controller.test.sal.binding.it.TestHelper.configMinumumBundles; -import static org.opendaylight.controller.test.sal.binding.it.TestHelper.flowCapableModelBundles; -import static org.opendaylight.controller.test.sal.binding.it.TestHelper.junitAndMockitoBundles; -import static org.opendaylight.controller.test.sal.binding.it.TestHelper.mdSalCoreBundles; -import static org.ops4j.pax.exam.CoreOptions.mavenBundle; -import static org.ops4j.pax.exam.CoreOptions.options; -import static org.ops4j.pax.exam.CoreOptions.systemPackages; -import static org.ops4j.pax.exam.CoreOptions.systemProperty; - @Ignore @RunWith(PaxExam.class) public class IdentityRefNetconfTest { @@ -71,7 +74,24 @@ public class IdentityRefNetconfTest { loggingModules(), mdSalCoreBundles(), bindingAwareSalBundles(), configMinumumBundles(), baseModelBundles(), flowCapableModelBundles(), - junitAndMockitoBundles()); + junitAndMockitoBundles(), + + // Classes from test-jars bundled for pax-exam test + streamBundle(TinyBundles.bundle() + .add(TestingNetconfClient.class) + .add(XmlFileLoader.class) + + .add("/netconfMessages/editConfig_identities.xml", + XmlFileLoader.class.getResource("/netconfMessages/editConfig_identities.xml")) + .add("/netconfMessages/commit.xml", + XmlFileLoader.class.getResource("/netconfMessages/commit.xml")) + .add("/netconfMessages/getConfig.xml", + XmlFileLoader.class.getResource("/netconfMessages/getConfig.xml")) + + .set(Constants.BUNDLE_SYMBOLICNAME, "TestingClient_bundle") + .set(Constants.EXPORT_PACKAGE, "org.opendaylight.controller.netconf.client.test, " + + "org.opendaylight.controller.netconf.util.test") + .build(TinyBundles.withBnd()))); } private Option loggingModules() { @@ -89,29 +109,26 @@ public class IdentityRefNetconfTest { private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 18383); - @Test public void testIdRef() throws Exception { - try { - Preconditions.checkNotNull(broker, "Controller not initialized"); - - NioEventLoopGroup nettyThreadgroup = new NioEventLoopGroup(); - NetconfClientDispatcher clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup, - CLIENT_CONNECTION_TIMEOUT_MILLIS); - - NetconfMessage edit = xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml"); - NetconfMessage commit = xmlFileToNetconfMessage("netconfMessages/commit.xml"); - NetconfMessage getConfig = xmlFileToNetconfMessage("netconfMessages/getConfig.xml"); - - try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, CLIENT_CONNECTION_TIMEOUT_MILLIS, clientDispatcher)) { - sendMessage(edit, netconfClient); - sendMessage(commit, netconfClient); - sendMessage(getConfig, netconfClient, "id-test", - "prefix:test-identity1", - "prefix:test-identity2", - "prefix:test-identity2", - "prefix:test-identity1"); - } + Preconditions.checkNotNull(broker, "Controller not initialized"); + + NioEventLoopGroup nettyThreadgroup = new NioEventLoopGroup(); + NetconfClientDispatcher clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup, + CLIENT_CONNECTION_TIMEOUT_MILLIS); + + NetconfMessage edit = xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml"); + NetconfMessage commit = xmlFileToNetconfMessage("netconfMessages/commit.xml"); + NetconfMessage getConfig = xmlFileToNetconfMessage("netconfMessages/getConfig.xml"); + + try (TestingNetconfClient netconfClient = new TestingNetconfClient("client", tcpAddress, CLIENT_CONNECTION_TIMEOUT_MILLIS, clientDispatcher)) { + sendMessage(edit, netconfClient); + sendMessage(commit, netconfClient); + sendMessage(getConfig, netconfClient, "id-test", + "prefix:test-identity1", + "prefix:test-identity2", + "prefix:test-identity2", + "prefix:test-identity1"); clientDispatcher.close(); } catch (Exception e) { @@ -119,8 +136,7 @@ public class IdentityRefNetconfTest { } } - - private void sendMessage(NetconfMessage edit, NetconfClient netconfClient, String... containingResponse) + private void sendMessage(NetconfMessage edit, TestingNetconfClient netconfClient, String... containingResponse) throws ExecutionException, InterruptedException, TimeoutException { NetconfMessage response = netconfClient.sendRequest(edit).get(); if (containingResponse == null) { @@ -134,16 +150,6 @@ public class IdentityRefNetconfTest { public static NetconfMessage xmlFileToNetconfMessage(final String fileName) throws IOException, SAXException, ParserConfigurationException { - return new NetconfMessage(xmlFileToDocument(fileName)); - } - - public static Document xmlFileToDocument(final String fileName) throws IOException, SAXException, - ParserConfigurationException { - // TODO xml messages from netconf-util test-jar cannot be loaded here(in OSGi), since test jar is not a bundle - try (InputStream resourceAsStream = IdentityRefNetconfTest.class.getClassLoader().getResourceAsStream(fileName)) { - Preconditions.checkNotNull(resourceAsStream); - final Document doc = XmlUtil.readXmlToDocument(resourceAsStream); - return doc; - } + return XmlFileLoader.xmlFileToNetconfMessage(fileName); } } diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationProvider.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationProvider.java new file mode 100644 index 0000000000..f5c50f8167 --- /dev/null +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationProvider.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.netconf.mapping.api; + +public interface NetconfOperationProvider { + + NetconfOperationServiceSnapshot openSnapshot(String sessionIdForReporting); + + public static class NetconfOperationProviderUtil { + + public static String getNetconfSessionIdForReporting(long sessionId) { + return "netconf session id " + sessionId; + } + + } + +} diff --git a/opendaylight/config/yang-test-plugin/src/main/resources/Header.txt b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationServiceSnapshot.java similarity index 54% rename from opendaylight/config/yang-test-plugin/src/main/resources/Header.txt rename to opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationServiceSnapshot.java index 068fd26844..eaa69379f7 100644 --- a/opendaylight/config/yang-test-plugin/src/main/resources/Header.txt +++ b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationServiceSnapshot.java @@ -4,4 +4,15 @@ * 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 - */ \ No newline at end of file + */ + +package org.opendaylight.controller.netconf.mapping.api; + +import java.util.Set; + +public interface NetconfOperationServiceSnapshot extends AutoCloseable { + String getNetconfSessionIdForReporting(); + + Set getServices(); + +} diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/CloseableUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/CloseableUtil.java new file mode 100644 index 0000000000..27960dfe16 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/CloseableUtil.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.netconf.util; + +public class CloseableUtil { + + public static void closeAll(Iterable autoCloseables) throws Exception { + Exception lastException = null; + for (AutoCloseable autoCloseable : autoCloseables) { + try { + autoCloseable.close(); + } catch (Exception e) { + if (lastException == null) { + lastException = e; + } else { + lastException.addSuppressed(e); + } + } + } + if (lastException != null) { + throw lastException; + } + + } +} diff --git a/opendaylight/netconf/pom.xml b/opendaylight/netconf/pom.xml index 2be64a8a98..ab71180ba9 100644 --- a/opendaylight/netconf/pom.xml +++ b/opendaylight/netconf/pom.xml @@ -47,7 +47,6 @@ 5.0.0 2.4.0 1.7.2 - ${project.build.directory}/generated-sources/sal @@ -138,6 +137,12 @@ netconf-impl ${netconf.version} + + ${project.groupId} + netconf-impl + ${netconf.version} + test-jar + ${project.groupId} netconf-monitoring @@ -239,24 +244,6 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.7 - - - generate-sources - - add-source - - - - ${salGeneratorPath} - - - - - diff --git a/opendaylight/northbound/java-client/pom.xml b/opendaylight/northbound/java-client/pom.xml index 4aa4e0328b..6de347fdde 100644 --- a/opendaylight/northbound/java-client/pom.xml +++ b/opendaylight/northbound/java-client/pom.xml @@ -127,7 +127,6 @@ org.codehaus.mojo build-helper-maven-plugin - 1.8 attach-artifacts