*.iws
.idea
xtend-gen
+yang-gen-config
+yang-gen-sal
classes
out/
.externalToolBuilders
<!-- enforcer version -->
<enforcer.version>1.3.1</enforcer.version>
<xtend.version>2.4.3</xtend.version>
- <xtend.dstdir>${project.build.directory}/generated-sources/xtend-gen</xtend.dstdir>
+ <xtend.dstdir>src/main/xtend-gen</xtend.dstdir>
+ <jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath>
+ <salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
</properties>
<dependencyManagement>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<sourceDirectory>${project.basedir}</sourceDirectory>
<includes>**\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat</includes>
- <excludes>**\/target\/,**\/bin\/,**\/target-ide\/</excludes>
+ <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/${jmxGeneratorPath}\/,**\/${salGeneratorPath}\/</excludes>
</configuration>
</plugin>
<plugin>
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ </plugin>
</plugins>
<pluginManagement>
<plugins>
</execution>
</executions>
</plugin>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>${xtend.dstdir}</directory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileset>
+ <fileset>
+ <directory>${jmxGeneratorPath}</directory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileset>
+ <fileset>
+ <directory>${salGeneratorPath}</directory>
+ <includes>
+ <include>**</include>
+ </includes>
+ </fileset>
+ </filesets>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${jmxGeneratorPath}</source>
+ <source>${salGeneratorPath}</source>
+ <source>${xtend.dstdir}</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</pluginManagement>
</build>
<maven>3.0.4</maven>
</prerequisites>
- <properties>
- <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
- <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
- </properties>
-
<dependencies>
<dependency>
<groupId>io.netty</groupId>
int orderingIdx = 0;
for (ModuleIdentifier moduleIdentifier : orderedModuleIdentifiers) {
+ logger.trace("Registering {}", moduleIdentifier);
ModuleInternalTransactionalInfo entry = commitInfo.getCommitted()
.get(moduleIdentifier);
if (entry == null) {
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
+import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
/**
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);
<packaging>bundle</packaging>
<properties>
- <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
- <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
<config.version>${config-api-version}</config.version>
<yangtools.version>${yang-maven-plugin-version}</yangtools.version>
<maven.bundle.version>${maven-bundle-plugin-version}</maven.bundle.version>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${jmxGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<maven>3.0.4</maven>
</prerequisites>
- <properties>
- <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
- </properties>
-
<build>
<pluginManagement>
<plugins>
</dependency>
</dependencies>
</plugin>
-
- <!-- tell eclipse about generated source folders -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${jmxGeneratorPath}</source>
- <source>${salGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</pluginManagement>
</build>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
+
</plugins>
</build>
</project>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
-
-
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<osgi.version>5.0.0</osgi.version>
<jacoco.version>0.6.2.201302030002</jacoco.version>
<slf4j.version>1.7.2</slf4j.version>
- <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
</properties>
<dependencies>
</dependency>
</dependencies>
</plugin>
- <!-- tell eclipse about generated source folders -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${salGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>config-subsystem</artifactId>
<artifactId>binding-type-provider</artifactId>
</dependency>
+ <dependency>
+ <groupId>net.sourceforge.pmd</groupId>
+ <artifactId>pmd</artifactId>
+ <version>5.1.0</version>
+ <scope>test</scope>
+ </dependency>
+
+
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>core</artifactId>
</dependency>
- <dependency>
- <groupId>org.freemarker</groupId>
- <artifactId>freemarker</artifactId>
- <version>2.3.20</version>
- </dependency>
-
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>config-api</artifactId>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.codehaus.gmaven.runtime</groupId>
+ <artifactId>gmaven-runtime-2.0</artifactId>
+ <version>1.5</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.sonatype.gossip</groupId>
+ <artifactId>gossip</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
</dependencies>
<build>
<plugins>
<plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.1</version>
+ <configuration>
+ <compilerId>groovy-eclipse-compiler</compilerId>
+ <verbose>false</verbose>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-eclipse-compiler</artifactId>
+ <version>2.8.0-01</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy-eclipse-batch</artifactId>
+ <version>2.1.8-01</version>
+ </dependency>
+ </dependencies>
</plugin>
+
</plugins>
</build>
</project>
*/
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<String> 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<File> writeMbe(ModuleMXBeanEntry mbe, File targetBaseDir,
+ File mainBaseDir) {
+ try {
+ List<File> generatedFiles = Lists.newArrayList();
+
+
+ Map<GeneratedObject, Boolean /*overwrite*/> gos = new HashMap<>();
+
+ // generate mx interface and abstract factory
+
+ // TOs
+ Map<String,GeneralClassTemplate> 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.<String>absent()), false);
+
+ // write runtime bean MXBeans and registrators
+ List<FtlTemplate> 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<File> 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<File> persistGeneratedObjects(File targetBaseDir, File mainBaseDir, Map<GeneratedObject, Boolean> gos) throws IOException {
+ List<File> generatedFiles = new ArrayList<>();
+ for (Entry<GeneratedObject, Boolean> entry : gos.entrySet()) {
+ boolean overwrite = entry.getValue();
+ File dst;
+ if (overwrite) {
+ dst = targetBaseDir;
+ } else {
+ dst = mainBaseDir;
+ }
+ Optional<Entry<FullyQualifiedName, File>> maybePersistEntry = entry.getKey().persist(dst, overwrite);
- File writeSie(ServiceInterfaceEntry sie, File targetBaseDir);
+ if (maybePersistEntry.isPresent()) {
+ generatedFiles.add(maybePersistEntry.get().getValue());
+ }
+ }
+ return generatedFiles;
+ }
- List<File> writeMbe(ModuleMXBeanEntry mbe, File targetBaseDir,
- File mainBaseDir, File resourceBaseDir);
+ private List<FtlTemplate> getRuntimeBeanFtlTemplates(Collection<RuntimeBeanEntry> runtimeBeans) {
+ if (runtimeBeans.isEmpty()) {
+ return Collections.emptyList();
+ }
+ List<FtlTemplate> allFtlFiles = new ArrayList<>();
+ { // registrators
+ Map<String, FtlTemplate> registratorNamesToFtls = RuntimeRegistratorFtlTemplate
+ .create(RuntimeRegistratorFtlTemplate.findRoot(runtimeBeans));
+ allFtlFiles.addAll(registratorNamesToFtls.values());
+ }
+ { // TOs, MXBean interfaces
+ for (RuntimeBeanEntry runtimeBeanEntry : runtimeBeans) {
+ Collection<FtlTemplate> ftlFiles = TemplateFactory
+ .getTOAndMXInterfaceFtlFiles(runtimeBeanEntry)
+ .values();
+ allFtlFiles.addAll(ftlFiles);
+ }
+ }
+ return allFtlFiles;
+ }
}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin;
-
-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<FtlTemplate> 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<File> writeMbe(ModuleMXBeanEntry mbe, File targetBaseDir,
- File mainBaseDir, File resourceBaseDir) {
- try {
- List<File> 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<RuntimeBeanEntry> runtimeBeans = mbe.getRuntimeBeans();
- if (runtimeBeans.size() > 0) {
- List<FtlTemplate> allFtlFiles = new ArrayList<>();
- { // registrators
- Map<String, FtlTemplate> registratorNamesToFtls = RuntimeRegistratorFtlTemplate
- .create(RuntimeRegistratorFtlTemplate.findRoot(runtimeBeans));
-
- allFtlFiles.addAll(registratorNamesToFtls.values());
- }
- { // TOs, MXBean interfaces
- for (RuntimeBeanEntry runtimeBeanEntry : runtimeBeans) {
- Collection<FtlTemplate> ftlFiles = TemplateFactory
- .getTOAndMXInterfaceFtlFiles(runtimeBeanEntry)
- .values();
- allFtlFiles.addAll(ftlFiles);
- }
- }
- boolean overwrite = true;
-
- FtlFilePersister ftlFilePersister = new FtlFilePersister();
- List<File> persisted = ftlFilePersister.persist(allFtlFiles,
- targetBaseDir, overwrite);
- // FIXME: check for intersection
- generatedFiles.addAll(persisted);
- }
-
- // purge nulls
- for (Iterator<File> 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);
- }
- }
-
-}
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;
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
private boolean generateModuleFactoryFile = true;
public JMXGenerator() {
- this.codeWriter = new FreeMarkerCodeWriterImpl();
+ this.codeWriter = new CodeWriter();
}
public JMXGenerator(CodeWriter codeWriter) {
ModuleMXBeanEntry mbe = mbeEntry.getValue();
try {
List<File> files1 = codeWriter.writeMbe(mbe, outputBaseDir,
- mainBaseDir, resourceBaseDir);
+ mainBaseDir);
generatedFiles.addFile(files1);
} catch (Exception e) {
throw new RuntimeException(
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<String> implementedIfcs = Lists
.newArrayList(ModuleFactory.class.getCanonicalName());
- private final String globallyUniqueName, moduleInstanceType;
- private final List<String> providedServices;
- private final ModuleMXBeanEntry mbe;
-
public AbstractFactoryTemplate(Header header, String packageName,
- String abstractFactoryName, String globallyUniqueName,
- String moduleInstanceType, List<Field> fields,
- List<String> providedServices, ModuleMXBeanEntry mbe) {
+ String abstractFactoryName,
+ List<Field> fields) {
super(header, packageName, abstractFactoryName, Collections
.<String> emptyList(), implementedIfcs, fields, Collections
.<MethodDefinition> emptyList(), true, false, Collections
.<Constructor> 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<String> 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;
}
}
*/
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;
return header;
}
+ @Override
+ public Optional<String> getHeaderString() {
+ if (header == null) {
+ return Optional.absent();
+ } else {
+ return Optional.of(header.toString());
+ }
+ }
+
@Override
public String getFullyQualifiedName() {
return FullyQualifiedNameHelper.getFullyQualifiedName(getPackageName(),
return typeDeclaration;
}
+
@Override
- public String getJavadoc() {
- return javadoc;
+ public Optional<String> getMaybeJavadoc() {
+ if (javadoc == null) {
+ return Optional.absent();
+ } else {
+ return Optional.of(javadoc);
+ }
}
public void setJavadoc(String javadoc) {
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<Constructor> getConstructors() {
+ return Collections.emptyList();
}
@Override
*/
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<ModuleField> moduleFields;
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;
}
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();
- }
-
}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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<FtlTemplate, String> serializeFtls(
- Collection<? extends FtlTemplate> ftlFiles) {
- Map<FtlTemplate, String> 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<File> persist(Collection<? extends FtlTemplate> ftlFiles,
- File dstFolder, boolean overwrite) throws IOException {
- Map<FtlTemplate, String> ftlFileStringMap = serializeFtls(ftlFiles);
- List<File> result = new ArrayList<>();
- for (Entry<FtlTemplate, String> 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;
- }
-
-}
*/
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<String> getHeaderString();
String getPackageName();
- String getJavadoc();
+ Optional<String> getMaybeJavadoc();
public List<Annotation> getAnnotations();
List<? extends Method> getMethods();
- /**
- * @return relative path to file to be created.
- */
- public File getRelativeFile();
-
- /**
- *
- * @return ftl template location
- */
- public String getFtlTempleteLocation();
+ List<Constructor> getConstructors();
}
*/
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.<String> emptyList(), Collections
.<Field> emptyList(), Collections
.<MethodDefinition> emptyList());
- this.moduleInstanceType = moduleInstanceType;
- }
-
- public String getModuleInstanceType() {
- return moduleInstanceType;
}
- public String getDynamicMBeanWithInstanceType() {
- return DynamicMBeanWithInstance.class.getCanonicalName();
- }
}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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.<String> emptyList(),
- Collections.<Field> emptyList(), Collections
- .<MethodDefinition> emptyList(), false, true,
- Collections.<Constructor> 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";
- }
-}
*/
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;
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;
public class TemplateFactory {
- public static Map<String, FtlTemplate> getFtlTemplates(
- ModuleMXBeanEntry entry) {
- Map<String, FtlTemplate> 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<String, FtlTemplate> getFtlStubTemplates(
- ModuleMXBeanEntry entry) {
- Map<String, FtlTemplate> 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<String, FtlTemplate> getFtlTemplates(
- ServiceInterfaceEntry entry) {
-
- Map<String, FtlTemplate> 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.
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) {
attrProcessor.processAttributes(mbe.getAttributes(),
mbe.getPackageName());
- Collection<String> transformed = Collections2.transform(mbe
- .getProvidedServices().keySet(),
- new Function<String, String>() {
- @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<ModuleField> moduleFields = attrProcessor.getModuleFields();
List<String> implementedIfcs = Lists.newArrayList(
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(
}
private static class AbstractModuleAttributesProcessor {
+ private static class Holder {
+ private final List<ModuleField> moduleFields;
+ private final List<MethodDefinition> methods;
+
+ private Holder(List<ModuleField> moduleFields, List<MethodDefinition> methods) {
+ this.moduleFields = Collections.unmodifiableList(moduleFields);
+ this.methods = Collections.unmodifiableList(methods);
+ }
+ }
- private final List<ModuleField> moduleFields = Lists.newArrayList();
- private final List<MethodDefinition> methods = Lists.newArrayList();
+ private final Holder holder;
- void processAttributes(Map<String, AttributeIfc> attributes,
- String packageName) {
+
+ private AbstractModuleAttributesProcessor(Map<String, AttributeIfc> attributes) {
+ this.holder = processAttributes(attributes);
+ }
+
+ private static Holder processAttributes(Map<String, AttributeIfc> attributes) {
+ List<ModuleField> moduleFields = new ArrayList<>();
+ List<MethodDefinition> methods = new ArrayList<>();
for (Entry<String, AttributeIfc> attrEntry : attributes.entrySet()) {
String type, nullableDefaultWrapped = null;
AttributeIfc attributeIfc = attrEntry.getValue();
String varName = BindingGeneratorUtil
.parseToValidParamName(attrEntry.getKey());
-
+ {
ModuleField field;
if (isIdentity) {
nullableDefaultWrapped, isDependency, dependency, isListOfDependencies, needsDepResolver);
}
moduleFields.add(field);
-
+ }
String getterName = "get"
+ attributeIfc.getUpperCaseCammelCase();
MethodDefinition getter = new MethodDefinition(type,
methods.add(setter);
}
+ return new Holder(moduleFields, methods);
}
List<ModuleField> getModuleFields() {
- return moduleFields;
+ return holder.moduleFields;
}
List<MethodDefinition> getMethods() {
- return methods;
+ return holder.methods;
}
}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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<Annotation> 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<Annotation> 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(" +", " ");
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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<Constructor> 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());
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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<Field> 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());
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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> <#if field.static==true>static </#if>"
- + "${field.type} ${field.name}<#if field.definition??> = ${field.definition}</#if>;"
- + System.lineSeparator() + " </#list>";
- Template t = new Template("name", new StringReader(templateStr),
- new Configuration());
-
- try {
- Map<String, Object> 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);
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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());
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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<? extends Method> 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());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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<ModuleField> 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());
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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<String> 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);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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());
- }
-}
*/
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;
return params;
}
+ public static Annotation createFromMap(Class<?> annotationClass, Map<String, String> parameters) {
+ List<Parameter> parameterList = new ArrayList<>();
+ for(Entry<String, String> 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");
Lists.newArrayList(new Parameter("value", q(description))));
}
+ public static Annotation createModuleQNameANnotation(QName qName) {
+ Map<String, String> 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<Annotation> createSieAnnotations(ServiceInterfaceEntry sie){
String exportedClassName = sie.getExportedOsgiClassName();
private static final String quote = "\"";
- private static String q(String nullableDescription) {
+ public static String q(String nullableDescription) {
return nullableDescription == null ? null : quote + nullableDescription
+ quote;
}
}
}
+ @Override
+ public String toString() {
+ return AnnotationSerializer.toString(this);
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.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(" +", " ");
+ }
+
+}
return isPublic;
}
+ @Override
+ public String toString() {
+ return ConstructorSerializer.toString(this);
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.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();
+ }
+}
import java.util.List;
+import static com.google.common.base.Preconditions.checkNotNull;
+
public class Field {
private final String type;
private final String name;
}
public Field(List<String> 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;
}
return type;
}
+ public String getGenericInnerType() {
+ return type.substring(type.indexOf("<") + 1, type.indexOf(">"));
+ }
+
public List<String> getModifiers() {
return modifiers;
}
public boolean isArray() {
return type.endsWith("[]");
}
+
+ @Override
+ public String toString() {
+ return FieldSerializer.toString(this);
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.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();
+ }
+}
@Override
public String toString() {
- return "yang module name: " + yangModuleName + " "
- + " yang module local name: " + yangModuleLocalName;
+ return HeaderSerializer.toString(this);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.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();
+ }
+
+}
public List<String> getModifiers() {
return Collections.emptyList();
}
+
+ @Override
+ public String toString() {
+ return MethodSerializer.toString(this);
+ }
}
public List<String> getModifiers() {
return modifiers;
}
+
+ @Override
+ public String toString() {
+ return MethodSerializer.toString(this);
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.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();
+ }
+}
return false;
}
+ @Override
+ public String toString() {
+ return ModuleFieldSerializer.toString(this);
+ }
+
public Dependency getDependency() {
return dependency;
}
return attributeName;
}
+
+ public boolean isList() {
+ return getType().startsWith("java.util.List");
+ }
+
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.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();
+ }
+}
*/
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 {
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
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory
+import com.google.common.base.Optional
+import org.opendaylight.controller.config.api.DependencyResolver
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance
+import org.opendaylight.controller.config.api.ModuleIdentifier
+import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface
+import org.opendaylight.controller.config.api.annotations.Description
+import org.opendaylight.controller.config.spi.Module
+import org.opendaylight.controller.config.spi.ModuleFactory
+import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractFactoryTemplate
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Field
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.*
+import org.opendaylight.yangtools.yang.common.QName
+import org.osgi.framework.BundleContext
+
+public class AbsFactoryGeneratedObjectFactory {
+
+ public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional<String> copyright) {
+ FullyQualifiedName absFactoryFQN = new FullyQualifiedName(mbe.packageName, mbe.abstractFactoryName)
+ FullyQualifiedName moduleFQN = new FullyQualifiedName(mbe.packageName, mbe.stubModuleName)
+ Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription())
+
+ AbstractFactoryTemplate abstractFactoryTemplate = TemplateFactory.abstractFactoryTemplateFromMbe(mbe)
+ Optional<String> header = abstractFactoryTemplate.headerString;
+ List<FullyQualifiedName> providedServices = mbe.providedServices.keySet().collect {
+ FullyQualifiedName.fromString(it)
+ }
+
+
+ return toGeneratedObject(absFactoryFQN, copyright,
+ header, classJavaDoc, mbe.yangModuleQName,
+ mbe.globallyUniqueName,
+ providedServices,
+ moduleFQN,
+ abstractFactoryTemplate.fields)
+ }
+
+ public GeneratedObject toGeneratedObject(FullyQualifiedName absFactoryFQN, Optional<String> copyright,
+ Optional<String> header, Optional<String> classJavaDoc, QName yangModuleQName,
+ String globallyUniqueName,
+ List<FullyQualifiedName> providedServices,
+ FullyQualifiedName moduleFQN,
+ List<Field> moduleFields) {
+ JavaFileInputBuilder b = new JavaFileInputBuilder()
+ Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName)
+ b.addClassAnnotation(moduleQNameAnnotation)
+
+ b.setFqn(absFactoryFQN)
+ b.setTypeName(TypeName.absClassType)
+
+ b.setCopyright(copyright);
+ b.setHeader(header);
+ b.setClassJavaDoc(classJavaDoc);
+ b.addImplementsFQN(new FullyQualifiedName(ModuleFactory))
+ if (classJavaDoc.isPresent()) {
+ b.addClassAnnotation("@${Description.canonicalName}(value=\"${classJavaDoc.get()}\")")
+ }
+
+ b.addToBody("public static final java.lang.String NAME = \"${globallyUniqueName}\";")
+ b.addToBody("private static final java.util.Set<Class<? extends ${AbstractServiceInterface.canonicalName}>> serviceIfcs;")
+
+ b.addToBody("@Override\n public final String getImplementationName() { \n return NAME; \n}")
+
+ b.addToBody(getServiceIfcsInitialization(providedServices))
+
+ // createModule
+ b.addToBody("""
+ @Override
+ public ${Module.canonicalName} createModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${BundleContext.canonicalName} bundleContext) {
+ return instantiateModule(instanceName, dependencyResolver, bundleContext);
+ }
+ """)
+
+ b.addToBody(getCreateModule(moduleFQN, moduleFields))
+
+ b.addToBody("""
+ public ${moduleFQN} instantiateModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${moduleFQN} oldModule, ${AutoCloseable.canonicalName} oldInstance, ${BundleContext.canonicalName} bundleContext) {
+ return new ${moduleFQN}(new ${ModuleIdentifier.canonicalName}(NAME, instanceName), dependencyResolver, oldModule, oldInstance);
+ }
+ """)
+
+ b.addToBody("""
+ public ${moduleFQN} instantiateModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${BundleContext.canonicalName} bundleContext) {
+ return new ${moduleFQN}(new ${ModuleIdentifier.canonicalName}(NAME, instanceName), dependencyResolver);
+ }
+ """)
+
+ b.addToBody("""
+ public ${moduleFQN} handleChangedClass(${DynamicMBeanWithInstance.canonicalName} old) throws Exception {
+ throw new UnsupportedOperationException("Class reloading is not supported");
+ }
+ """)
+
+ b.addToBody("""
+ @Override
+ public java.util.Set<${moduleFQN}> getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory dependencyResolverFactory, ${BundleContext.canonicalName} bundleContext) {
+ return new java.util.HashSet<${moduleFQN}>();
+ }
+ """)
+
+ return new GeneratedObjectBuilder(b.build()).toGeneratedObject()
+ }
+
+ private static String getCreateModule(FullyQualifiedName moduleFQN, List<Field> moduleFields) {
+ String result = """
+ @Override
+ public ${Module.canonicalName} createModule(String instanceName, ${DependencyResolver.canonicalName} dependencyResolver, ${DynamicMBeanWithInstance.canonicalName} old, ${BundleContext.canonicalName} bundleContext) throws Exception {
+ ${moduleFQN} oldModule = null;
+ try {
+ oldModule = (${moduleFQN}) old.getModule();
+ } catch(Exception e) {
+ return handleChangedClass(old);
+ }
+ ${moduleFQN} module = instantiateModule(instanceName, dependencyResolver, oldModule, old.getInstance(), bundleContext);
+ """
+ result += moduleFields.collect{"module.set${it.name}(oldModule.get${it.name}());"}.join("\n")
+ result += """
+ return module;
+ }
+ """
+ return result
+ }
+
+ private static String getServiceIfcsInitialization(List<FullyQualifiedName> providedServices) {
+ String generic = "Class<? extends ${AbstractServiceInterface.canonicalName}>"
+
+ String result = """static {
+ java.util.Set<${generic}> serviceIfcs2 = new java.util.HashSet<${generic}>();
+ """
+ result += providedServices.collect{"serviceIfcs2.add(${it}.class);"}.join("\n")
+ result += """serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2);
+ }
+ """
+
+ // add isModuleImplementingServiceInterface and getImplementedServiceIntefaces methods
+
+ result += """
+ @Override
+ public final boolean isModuleImplementingServiceInterface(Class<? extends ${AbstractServiceInterface.canonicalName}> serviceInterface) {
+ for (Class<?> ifc: serviceIfcs) {
+ if (serviceInterface.isAssignableFrom(ifc)){
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public java.util.Set<Class<? extends ${AbstractServiceInterface.canonicalName}>> getImplementedServiceIntefaces() {
+ return serviceIfcs;
+ }
+ """
+
+ return result
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory
+import com.google.common.base.Optional
+import org.opendaylight.controller.config.api.DependencyResolver
+import org.opendaylight.controller.config.api.ModuleIdentifier
+import org.opendaylight.controller.config.api.annotations.Description
+import org.opendaylight.controller.config.api.runtime.RootRuntimeBeanRegistrator
+import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.AbstractModuleTemplate
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.IdentityRefModuleField
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Method
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.*
+import org.opendaylight.yangtools.yang.common.QName
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+public class AbsModuleGeneratedObjectFactory {
+
+ public GeneratedObject toGeneratedObject(ModuleMXBeanEntry mbe, Optional<String> copyright) {
+ FullyQualifiedName abstractFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractModuleName())
+ Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription())
+ AbstractModuleTemplate abstractModuleTemplate = TemplateFactory.abstractModuleTemplateFromMbe(mbe)
+ Optional<String> header = abstractModuleTemplate.headerString;
+ List<FullyQualifiedName> implementedInterfaces = abstractModuleTemplate.getTypeDeclaration().getImplemented().collect {
+ FullyQualifiedName.fromString(it)
+ }
+ Optional<FullyQualifiedName> maybeRegistratorType
+ if (abstractModuleTemplate.isRuntime()) {
+ maybeRegistratorType = Optional.of(FullyQualifiedName.fromString(abstractModuleTemplate.getRegistratorType()))
+ } else {
+ maybeRegistratorType = Optional.absent()
+ }
+
+ return toGeneratedObject(abstractFQN, copyright, header, classJavaDoc, implementedInterfaces,
+ abstractModuleTemplate.getModuleFields(), maybeRegistratorType, abstractModuleTemplate.getMethods(),
+ mbe.yangModuleQName
+ )
+ }
+
+ public GeneratedObject toGeneratedObject(FullyQualifiedName abstractFQN,
+ Optional<String> copyright,
+ Optional<String> header,
+ Optional<String> classJavaDoc,
+ List<FullyQualifiedName> implementedInterfaces,
+ List<ModuleField> moduleFields,
+ Optional<FullyQualifiedName> maybeRegistratorType,
+ List<Method> methods,
+ QName yangModuleQName) {
+ JavaFileInputBuilder b = new JavaFileInputBuilder()
+
+ Annotation moduleQNameAnnotation = Annotation.createModuleQNameANnotation(yangModuleQName)
+ b.addClassAnnotation(moduleQNameAnnotation)
+
+ b.setFqn(abstractFQN)
+ b.setTypeName(TypeName.absClassType)
+
+ b.setCopyright(copyright);
+ b.setHeader(header);
+ b.setClassJavaDoc(classJavaDoc);
+ implementedInterfaces.each { b.addImplementsFQN(it) }
+ if (classJavaDoc.isPresent()) {
+ b.addClassAnnotation("@${Description.canonicalName}(value=\"${classJavaDoc.get()}\")")
+ }
+
+ // add logger:
+ b.addToBody(getLogger(abstractFQN));
+
+ b.addToBody("//attributes start");
+
+ b.addToBody(moduleFields.collect { it.toString() }.join("\n"))
+
+ b.addToBody("//attributes end");
+
+
+ b.addToBody(getCommonFields(abstractFQN));
+
+
+ b.addToBody(getNewConstructor(abstractFQN))
+ b.addToBody(getCopyFromOldConstructor(abstractFQN))
+
+ b.addToBody(getRuntimeRegistratorCode(maybeRegistratorType))
+ b.addToBody(getValidationMethods(moduleFields))
+
+ b.addToBody(getCachesOfResolvedDependencies(moduleFields))
+ b.addToBody(getCachesOfResolvedIdentityRefs(moduleFields))
+ b.addToBody(getGetInstance(moduleFields))
+ b.addToBody(getReuseLogic(moduleFields, abstractFQN))
+ b.addToBody(getEqualsAndHashCode(abstractFQN))
+
+ b.addToBody(getMethods(methods))
+
+ return new GeneratedObjectBuilder(b.build()).toGeneratedObject()
+ }
+
+ private static String getMethods(List<Method> methods) {
+ String result = """
+ // getters and setters
+ """
+ result += methods.collect{it.toString()}.join("\n")
+ return result
+ }
+
+ private static String getEqualsAndHashCode(FullyQualifiedName abstractFQN) {
+ return """
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ${abstractFQN.typeName} that = (${abstractFQN.typeName}) o;
+ return identifier.equals(that.identifier);
+ }
+
+ @Override
+ public int hashCode() {
+ return identifier.hashCode();
+ }
+ """
+ }
+
+ private static String getReuseLogic(List<ModuleField> moduleFields, FullyQualifiedName abstractFQN) {
+ String result = """
+ public boolean canReuseInstance(${abstractFQN.typeName} oldModule){
+ // allow reusing of old instance if no parameters was changed
+ return isSame(oldModule);
+ }
+
+ public ${AutoCloseable.canonicalName} reuseInstance(${AutoCloseable.canonicalName} oldInstance){
+ // implement if instance reuse should be supported. Override canReuseInstance to change the criteria.
+ return oldInstance;
+ }
+ """
+ // isSame method that detects changed fields
+ result += """
+ public boolean isSame(${abstractFQN.typeName} other) {
+ if (other == null) {
+ throw new IllegalArgumentException("Parameter 'other' is null");
+ }
+ """
+ // loop through fields, do deep equals on each field
+ result += moduleFields.collect { field ->
+ if (field.isListOfDependencies()) {
+ return """
+ if (${field.name}Dependency.equals(other.${field.name}Dependency) == false) {
+ return false;
+ }
+ for (int idx = 0; idx < ${field.name}Dependency.size(); idx++) {
+ if (${field.name}Dependency.get(idx) != other.${field.name}Dependency.get(idx)) {
+ return false;
+ }
+ }
+ """
+ } else if (field.isDependent()) {
+ return """
+ if (${field.name}Dependency != other.${field.name}Dependency) { // reference to dependency must be same
+ return false;
+ }
+ """
+ } else {
+ return """
+ if (java.util.Objects.deepEquals(${field.name}, other.${field.name}) == false) {
+ return false;
+ }
+ """
+ }
+ }.join("\n")
+
+
+ result += """
+ return true;
+ }
+ """
+
+ return result
+ }
+
+ private static String getGetInstance(List<ModuleField> moduleFields) {
+ String result = """
+ @Override
+ public final ${AutoCloseable.canonicalName} getInstance() {
+ if(instance==null) {
+ """
+ // create instance start
+
+ // loop through dependent fields, use dependency resolver to instantiate dependencies. Do it in loop in case field represents list of dependencies.
+ Map<ModuleField, String> resolveDependenciesMap = moduleFields.findAll {
+ it.isDependent()
+ }.collectEntries { ModuleField field ->
+ [field, field.isList() ?
+ """
+ ${field.name}Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>();
+ for(javax.management.ObjectName dep : ${field.name}) {
+ ${field.name}Dependency.add(dependencyResolver.resolveInstance(${
+ field.dependency.sie.exportedOsgiClassName
+ }.class, dep, ${field.name}JmxAttribute));
+ }
+ """
+ :
+ """
+ ${field.name}Dependency = dependencyResolver.resolveInstance(${
+ field.dependency.sie.exportedOsgiClassName
+ }.class, ${field.name}, ${field.name}JmxAttribute);
+ """
+ ]
+ }
+ // wrap each field resolvation statement with if !=null when dependency is not mandatory
+ def wrapWithNullCheckClosure = {Map<ModuleField, String> map, predicate -> map.collect { ModuleField key, String value ->
+ predicate(key) ? """
+ if(${key.name}!=null) {
+ ${value}
+ }
+ """ : value
+ }.join("\n")
+ }
+
+ result += wrapWithNullCheckClosure(resolveDependenciesMap, {ModuleField key ->
+ key.getDependency().isMandatory() == false} )
+
+ // add code to inject dependency resolver to fields that support it
+ Map<ModuleField, String> injectDepsMap = moduleFields.findAll { it.needsDepResolver }.collectEntries { field ->
+ if (field.isList()) {
+ return [field,"""
+ for(${field.genericInnerType} candidate : ${field.name}) {
+ candidate.injectDependencyResolver(dependencyResolver);
+ }
+ """]
+ } else {
+ return [field, "${field.name}.injectDependencyResolver(dependencyResolver);"]
+ }
+ }
+
+ result += wrapWithNullCheckClosure(injectDepsMap, {true})
+
+ // identity refs need to be injected with dependencyResolver and base class
+ Map<ModuleField, String> resolveIdentityMap = moduleFields.findAll { it.isIdentityRef() }.collectEntries { IdentityRefModuleField field ->
+ [field,
+ "set${field.attributeName}(${field.name}.resolveIdentity(dependencyResolver, ${field.identityBaseClass}.class));"]
+ }
+
+ result += wrapWithNullCheckClosure(resolveIdentityMap, {true})
+
+ // create instance end: reuse and recreate logic
+ result += """
+ if(oldInstance!=null && canReuseInstance(oldModule)) {
+ instance = reuseInstance(oldInstance);
+ } else {
+ if(oldInstance!=null) {
+ try {
+ oldInstance.close();
+ } catch(Exception e) {
+ logger.error("An error occurred while closing old instance " + oldInstance, e);
+ }
+ }
+ instance = createInstance();
+ if (instance == null) {
+ throw new IllegalStateException("Error in createInstance - null is not allowed as return value");
+ }
+ }
+ }
+ return instance;
+ }
+ public abstract ${AutoCloseable.canonicalName} createInstance();
+ """
+ return result
+ }
+
+ private static String getCommonFields(FullyQualifiedName abstractFQN) {
+ return """
+ private final ${abstractFQN.typeName} oldModule;
+ private final ${AutoCloseable.canonicalName} oldInstance;
+ private ${AutoCloseable.canonicalName} instance;
+ private final ${DependencyResolver.canonicalName} dependencyResolver;
+ private final ${ModuleIdentifier.canonicalName} identifier;
+ @Override
+ public ${ModuleIdentifier.canonicalName} getIdentifier() {
+ return identifier;
+ }
+ """
+ }
+
+ private static String getCachesOfResolvedIdentityRefs(List<ModuleField> moduleFields) {
+ return moduleFields.findAll { it.isIdentityRef() }.collect { IdentityRefModuleField field ->
+ "private ${field.identityClassType} ${field.identityClassName};"
+ }.join("\n")
+ }
+
+ private static String getCachesOfResolvedDependencies(List<ModuleField> moduleFields) {
+ return moduleFields.findAll { it.dependent }.collect { field ->
+ if (field.isList()) {
+ return """
+ private java.util.List<${field.dependency.sie.exportedOsgiClassName}> ${
+ field.name
+ }Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>();
+ protected final java.util.List<${field.dependency.sie.exportedOsgiClassName}> get${
+ field.attributeName
+ }Dependency(){
+ return ${field.name}Dependency;
+ }
+ """
+ } else {
+ return """
+ private ${field.dependency.sie.exportedOsgiClassName} ${field.name}Dependency;
+ protected final ${field.dependency.sie.exportedOsgiClassName} get${field.attributeName}Dependency(){
+ return ${field.name}Dependency;
+ }
+ """
+ }
+ }.join("\n")
+ }
+
+ private static String getRuntimeRegistratorCode(Optional<FullyQualifiedName> maybeRegistratorType) {
+ if (maybeRegistratorType.isPresent()) {
+ String registratorType = maybeRegistratorType.get()
+
+ return """
+ private ${registratorType} rootRuntimeBeanRegistratorWrapper;
+
+ public ${registratorType} getRootRuntimeBeanRegistratorWrapper(){
+ return rootRuntimeBeanRegistratorWrapper;
+ }
+
+ @Override
+ public void setRuntimeBeanRegistrator(${RootRuntimeBeanRegistrator.canonicalName} rootRuntimeRegistrator){
+ this.rootRuntimeBeanRegistratorWrapper = new ${registratorType}(rootRuntimeRegistrator);
+ }
+ """
+ } else {
+ return ""
+ }
+ }
+
+ private static String getValidationMethods(List<ModuleField> moduleFields) {
+ String result = """
+ @Override
+ public void validate() {
+ """
+ // validate each mandatory dependency
+ List<String> lines = moduleFields.findAll{(it.dependent && it.dependency.mandatory)}.collect { field ->
+ if (field.isList()) {
+ return "" +
+ "for(javax.management.ObjectName dep : ${field.name}) {\n" +
+ " dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, dep, ${field.name}JmxAttribute);\n" +
+ "}\n"
+ } else {
+ return "dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, ${field.name}, ${field.name}JmxAttribute);"
+ }
+ }
+ result += lines.findAll { it.isEmpty() == false }.join("\n")
+ result += """
+ customValidation();
+ }
+
+ protected void customValidation(){
+ }
+ """
+ return result
+ }
+
+ private static String getLogger(FullyQualifiedName fqn) {
+ return "private static final ${Logger.canonicalName} logger = ${LoggerFactory.canonicalName}.getLogger(${fqn.toString()}.class);"
+ }
+
+ // assumes that each parameter name corresponds to an field in this class, constructs lines setting this.field = field;
+ private static String getConstructorStart(FullyQualifiedName fqn,
+ LinkedHashMap<String, String> parameters, String after) {
+ return "public ${fqn.typeName}(" +
+ parameters.collect { it.key + " " + it.value }.join(",") +
+ ") {\n" +
+ parameters.values().collect { "this.${it}=${it};\n" }.join() +
+ after +
+ "}\n"
+ }
+
+ private static String getNewConstructor(FullyQualifiedName abstractFQN) {
+ LinkedHashMap<String, String> parameters = [
+ (ModuleIdentifier.canonicalName): "identifier",
+ (DependencyResolver.canonicalName): "dependencyResolver"
+ ]
+ String setToNulls = ["oldInstance", "oldModule"].collect { "this.${it}=null;\n" }.join()
+ return getConstructorStart(abstractFQN, parameters, setToNulls)
+ }
+
+ private static String getCopyFromOldConstructor(FullyQualifiedName abstractFQN) {
+ LinkedHashMap<String, String> parameters = [
+ (ModuleIdentifier.canonicalName): "identifier",
+ (DependencyResolver.canonicalName): "dependencyResolver",
+ (abstractFQN.typeName): "oldModule",
+ (AutoCloseable.canonicalName): "oldInstance"
+ ]
+ return getConstructorStart(abstractFQN, parameters, "")
+ }
+}
--- /dev/null
+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<String> copyright, Optional<String> header) {
+ FullyQualifiedName concreteFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getStubModuleName());
+ FullyQualifiedName abstractFQN = new FullyQualifiedName(mbe.getPackageName(), mbe.getAbstractModuleName());
+ Optional<String> classJavaDoc = Optional.fromNullable(mbe.getNullableDescription());
+ return toGeneratedObject(concreteFQN, abstractFQN, copyright, header, classJavaDoc);
+ }
+
+ GeneratedObject toGeneratedObject(FullyQualifiedName concreteFQN,
+ FullyQualifiedName abstractFQN,
+ Optional<String> copyright,
+ Optional<String> header,
+ Optional<String> 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<String, String> parameters = new LinkedHashMap<String, String>(){
+ {
+ 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<String, String> 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<String, String> parameters = new LinkedHashMap<String, String>(){
+ {
+ 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"+
+ "}";
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory
+
+import com.google.common.base.Optional
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.FtlTemplate
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.FullyQualifiedName
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObject
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.GeneratedObjectBuilder
+import org.opendaylight.controller.config.yangjmxgenerator.plugin.java.JavaFileInputBuilder
+
+public class GenericGeneratedObjectFactory {
+
+ public GeneratedObject toGeneratedObject(FtlTemplate template, Optional<String> copyright) {
+ JavaFileInputBuilder b = new JavaFileInputBuilder();
+ b.setHeader(template.headerString)
+ b.setFqn(new FullyQualifiedName(template.packageName, template.typeDeclaration.name))
+ b.setClassJavaDoc(template.maybeJavadoc)
+ template.annotations.each { b.addClassAnnotation(it) }
+ // type declaration
+ template.typeDeclaration.extended.each { b.addExtendsFQN(FullyQualifiedName.fromString(it)) }
+ template.typeDeclaration.implemented.each { b.addImplementsFQN(FullyQualifiedName.fromString(it)) }
+ b.setCopyright(copyright);
+ b.setTypeName(template.typeDeclaration.toTypeName())
+ // fields
+ template.fields.each { b.addToBody(it.toString()) }
+ // constructors
+ template.constructors.each { b.addToBody(it.toString()) }
+ // methods
+ template.methods.each { b.addToBody(it.toString()) }
+
+ return new GeneratedObjectBuilder(b.build()).toGeneratedObject();
+ }
+}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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<Entry<FullyQualifiedName,File>> 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<Entry<FullyQualifiedName,File>> 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();
+ }
+}
--- /dev/null
+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<String> comment) {
+ return maybeAddComment(comment, false);
+ }
+
+ private static String maybeAddComment(Optional<String> comment, boolean isJavadoc) {
+
+ if (comment.isPresent()) {
+ String input = comment.get();
+ return StringUtil.writeComment(input, isJavadoc);
+ } else {
+ return "";
+ }
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.java;
+
+import com.google.common.base.Optional;
+
+import java.util.List;
+
+public interface JavaFileInput {
+
+ FullyQualifiedName getFQN();
+
+ Optional<String> getCopyright();
+
+ Optional<String> getHeader();
+
+ TypeName getType();
+
+ Optional<String> getClassJavaDoc();
+
+ List<String> getClassAnnotations();
+
+ List<FullyQualifiedName> getExtends();
+
+ List<FullyQualifiedName> getImplements();
+
+ List<String> getBodyElements();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.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<String> copyright = Optional.absent(), header = Optional.absent(), classJavaDoc = Optional.absent();
+
+ private TypeName typeName = TypeName.classType;
+
+ private FullyQualifiedName fqn;
+
+ private final List<String> classAnnotations = new ArrayList<>();
+
+ private final List<FullyQualifiedName> extendsFQNs = new ArrayList<>();
+
+ private final List<FullyQualifiedName> implementsFQNs = new ArrayList<>();
+
+ private final List<String> 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<String> getCopyright() {
+ return copyright;
+ }
+
+ public void setCopyright(Optional<String> copyright) {
+ this.copyright = checkNotNull(copyright);
+ }
+
+ public Optional<String> getHeader() {
+ return header;
+ }
+
+ public void setHeader(Optional<String> header) {
+ this.header = checkNotNull(header);
+ }
+
+
+ public Optional<String> getClassJavaDoc() {
+ return classJavaDoc;
+ }
+
+ public void setClassJavaDoc(Optional<String> classJavaDoc) {
+ this.classJavaDoc = checkNotNull(classJavaDoc);
+ }
+
+
+ public FullyQualifiedName getFqn() {
+ return fqn;
+ }
+
+ public void setFqn(FullyQualifiedName fqn) {
+ this.fqn = fqn;
+ }
+
+ public List<FullyQualifiedName> getExtendsFQNs() {
+ return extendsFQNs;
+ }
+
+
+ public List<FullyQualifiedName> 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<String> getCopyright() {
+ return copyright;
+ }
+
+ @Override
+ public Optional<String> getHeader() {
+ return header;
+ }
+
+ @Override
+ public Optional<String> getClassJavaDoc() {
+ return classJavaDoc;
+ }
+
+ @Override
+ public TypeName getType() {
+ return typeName;
+ }
+
+ @Override
+ public List<FullyQualifiedName> getExtends() {
+ return Collections.unmodifiableList(extendsFQNs);
+ }
+
+ @Override
+ public List<FullyQualifiedName> getImplements() {
+ return Collections.unmodifiableList(implementsFQNs);
+ }
+
+ @Override
+ public List<String> getClassAnnotations() {
+ return Collections.unmodifiableList(classAnnotations);
+ }
+
+ @Override
+ public List<String> getBodyElements() {
+ return Collections.unmodifiableList(bodyElements);
+ }
+ };
+ }
+}
--- /dev/null
+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;
+ }
+}
--- /dev/null
+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<FullyQualifiedName> 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<String> 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<String> 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());
+ }
+
+}
--- /dev/null
+Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+
+This program and the accompanying materials are made available under the
+terms of the Eclipse Public License v1.0 which accompanies this distribution,
+and is available at http://www.eclipse.org/legal/epl-v10.html
+++ /dev/null
-<@headerD header=header/>
-package ${packageName};
-
-<@javadocD object=javadoc/>
-<@annotationsD object=annotations/>
-<#-- class/interface -->
-<@typeDeclarationD object=typeDeclaration/>
-{
-
-<@constructorsD object=constructors>
-</@constructorsD>
-<@fieldsD object=fields/>
-
-<@methodsD object=methods/>
-}
+++ /dev/null
-<@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<Class<? extends ${abstractServiceInterfaceType}>> serviceIfcs;
- <#if providedServices??>
- static {
- java.util.Set<Class<? extends ${abstractServiceInterfaceType}>> serviceIfcs2 = new java.util.HashSet<Class<? extends ${abstractServiceInterfaceType}>>();
- <#list providedServices as refId>
- serviceIfcs2.add(${refId});
- </#list>
- serviceIfcs = java.util.Collections.unmodifiableSet(serviceIfcs2);
- }
- </#if>
-
- @Override
- public final boolean isModuleImplementingServiceInterface(Class<? extends ${abstractServiceInterfaceType}> serviceInterface) {
- for (Class<?> ifc: serviceIfcs) {
- if (serviceInterface.isAssignableFrom(ifc)){
- return true;
- }
- }
- return false;
- }
-
- @Override
- public java.util.Set<Class<? extends ${abstractServiceInterfaceType}>> 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}());
- </#list>
-
- 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}>();
- }
-
-}
+++ /dev/null
-<@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;
- </#if>
-
- 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);
- }
- </#if>
-
- @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);
- </#if>
- </#if>
- </#list>
- 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;
- }
- </#if>
- </#if>
- </#list>
-
- // caches of resolved IdentityRefs
- <#list moduleFields as field>
- <#if field.identityRef==true>
- private ${field.identityClassType} ${field.identityClassName};
- </#if>
- </#list>
-
- @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>
-
- <#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>
-
- <#if field.dependency.mandatory==false>
- }
- </#if>
- </#if>
-
- <#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>
- }
- </#if>
-
- <#if field.identityRef==true>
- if(${field.name} != null) {
- set${field.attributeName}(${field.name}.resolveIdentity(dependencyResolver, ${field.identityBaseClass}.class));
- }
- </#if>
- </#list>
-
- 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)
- </#if>
- {
- return false;
- }
- </#if>
- </#list>
-
- 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();
- }
-}
+++ /dev/null
-<@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/>
- }
-}
*/
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");
+ 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");
assertNotNull(template);
}
- private ModuleMXBeanEntry mockMbe(String packageName) {
+ public static ModuleMXBeanEntry mockMbe(String packageName) {
ModuleMXBeanEntry mbe = mock(ModuleMXBeanEntry.class);
Map<String, AttributeIfc> a = Maps.newHashMap();
JavaAttribute attr = mockJavaAttr();
return mbe;
}
- private JavaAttribute mockJavaAttr() {
+ public static JavaAttribute mockJavaAttr() {
JavaAttribute attr = mock(JavaAttribute.class);
Type typeA = mock(Type.class);
doReturn("package").when(typeA).getName();
*/
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() {
FtlTemplate rootFtlFile = createdFtls.get(rootRegistratorName);
assertNotNull(rootFtlFile);
- Map<FtlTemplate, String> serializedFtls = ftlFilePersister
- .serializeFtls(createdFtls.values());
- assertThat(serializedFtls.size(), is(2));
+ assertThat(createdFtls.values().size(), is(2));
}
@Test
Map<String, FtlTemplate> createdFtls = RuntimeRegistratorFtlTemplate
.create(rootRB);
- Map<FtlTemplate, String> 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<String, FtlTemplate> createdFtls,
- RuntimeBeanEntry rb, Map<FtlTemplate, String> serializedFtls) {
- RuntimeRegistratorFtlTemplate rbFtlFile = (RuntimeRegistratorFtlTemplate) createdFtls
- .get(RuntimeRegistratorFtlTemplate.getJavaNameOfRuntimeRegistration(rb.getJavaNamePrefix()));
- assertNotNull(rbFtlFile);
- String unformatted = serializedFtls.get(rbFtlFile);
- assertNotNull(unformatted);
- return FormattingUtil.cleanUpEmptyLinesAndIndent(unformatted);
- }
-
}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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<String> extendedInterfaces = Arrays.asList("List", "Set");
- List<MethodDeclaration> methods = new ArrayList<>();
- methods.add(new MethodDeclaration("String", "executeOperation",
- Collections.<Field> emptyList()));
-
- List<String> mods = Lists.newArrayList();
- List<String> 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<FtlTemplate, String> 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);
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.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));
+ }
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.config.yangjmxgenerator.plugin.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<QName,ServiceInterfaceEntry> serviceInterfaceEntryMap = loadThreadsServiceInterfaceEntries("packages.sis");
+ Map<String, ModuleMXBeanEntry> namesToMBEs = loadThreadsJava(serviceInterfaceEntryMap, "packages.pack2");
+ ModuleMXBeanEntry dynamicThreadPool = namesToMBEs.get(THREADPOOL_DYNAMIC_MXB_NAME);
+ parseGeneratedFile(dynamicThreadPool);
+
+ }
+
+ private void parseGeneratedFile(ModuleMXBeanEntry moduleMXBeanEntry) throws IOException {
+ Optional<String> copyright = Optional.absent();
+ GeneratedObject generatedObject = new AbsModuleGeneratedObjectFactory().toGeneratedObject(moduleMXBeanEntry, copyright);
+ Entry<FullyQualifiedName,File> entry = generatedObject.persist(generatorOutputPath).get();
+
+ File dstFile = entry.getValue();
+ parse(dstFile);
+ }
+}
--- /dev/null
+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<String> copyright = Optional.absent();
+ Optional<String> header = Optional.absent();
+ GeneratedObject go = new ConcreteModuleGeneratedObjectFactory().toGeneratedObject(moduleMXBeanEntry, copyright, header);
+ Entry<FullyQualifiedName, File> 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;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.config.yangjmxgenerator.plugin.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();
- }
-}
--- /dev/null
+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));
+ }
+ }
+}
*/
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;
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<InputStream> yangISs = new ArrayList<>();
}
return result;
}
+
+ protected Map<QName, ServiceInterfaceEntry> loadThreadsServiceInterfaceEntries(String packageName) {
+ Map<IdentitySchemaNode, ServiceInterfaceEntry> identitiesToSIs = new HashMap<>();
+ return ServiceInterfaceEntry.create(threadsModule, packageName,identitiesToSIs);
+ }
+
+ protected Map<String /* identity local name */, ModuleMXBeanEntry> loadThreadsJava(Map<QName, ServiceInterfaceEntry> modulesToSIEs, String packageName) {
+ Map<String /* identity local name */, ModuleMXBeanEntry> namesToMBEs = ModuleMXBeanEntry
+ .create(threadsJavaModule, modulesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl
+ (context)), packageName);
+ Assert.assertNotNull(namesToMBEs);
+ Set<String> 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;
+ }
+
}
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;
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;
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";
protected Map<QName, ServiceInterfaceEntry> modulesToSIEs;
- protected Map<String /* identity local name */, ModuleMXBeanEntry> loadThreadsJava() {
- Map<String /* identity local name */, ModuleMXBeanEntry> namesToMBEs = ModuleMXBeanEntry
- .create(threadsJavaModule, modulesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl
- (context)), PACKAGE_NAME);
- assertNotNull(namesToMBEs);
- Set<String> 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<IdentitySchemaNode, ServiceInterfaceEntry> identitiesToSIs = new HashMap<>();
- modulesToSIEs = ServiceInterfaceEntry.create(threadsModule,
- "packages.sis",identitiesToSIs);
+ modulesToSIEs = loadThreadsServiceInterfaceEntries("packages.sis");
+ }
+
+
+ protected Map<String /* identity local name */, ModuleMXBeanEntry> loadThreadsJava() {
+ return loadThreadsJava(modulesToSIEs, PACKAGE_NAME);
}
@Test
<artifactId>maven-plugin-api</artifactId>
<version>3.0.5</version>
</dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
*/
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
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);
+ }
}
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 {
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();
- }
}
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
+
<plugin>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-test-plugin</artifactId>
<execution>
<goals>
<goal>delete-sources</goal>
+
<goal>process-sources</goal>
</goals>
</execution>
/*
- * 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
};
}
+
}
/*
- * 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 {
}
/*
- * 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
};
}
+
}
/*
- * 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 {
}
/*
- * 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
return NetconfTestImplModuleUtil.registerRuntimeBeans(this);
}
+
}
/*
- * 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 {
}
/*
- * 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
};
}
+
}
/*
- * 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 {
}
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
</project>
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.7</version>
- <executions>
- <execution>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>target/generated-sources/sal</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<!--module>test/sal-rest-connector-it</modulei -->
</modules>
</profile>
- <profile>
- <id>IDE</id>
- <activation>
- <property>
- <name>m2e.version</name>
- </property>
- </activation>
- <build>
- <!-- Put the IDE's build output in a folder other than target,
- so that IDE builds don't interact with Maven builds -->
- <directory>target-ide</directory>
- </build>
- </profile>
</profiles>
<properties>
- <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Plugin Versions -->
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
<version>${xtend.version}</version>
- <executions>
- <execution>
- <goals>
- <goal>compile</goal>
- </goals>
- <configuration>
- <outputDirectory>${basedir}/src/main/xtend-gen</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- <version>${maven.clean.plugin.version}</version>
- <configuration>
- <filesets>
- <fileset>
- <directory>${basedir}/src/main/xtend-gen</directory>
- <includes>
- <include>**</include>
- </includes>
- </fileset>
- </filesets>
- </configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- <source>${project.build.directory}/generated-sources/sal</source>
- <source>src/main/xtend-gen</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
-
-
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- <source>src/main/xtend-gen</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
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;
.toNormalizedNode(path, data);
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier normalizedPath = normalized.getKey();
- try {
- List<PathArgument> currentArguments = new ArrayList<>();
- DataNormalizationOperation<?> currentOp = codec.getDataNormalizer().getRootOperation();
- Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
- while (iterator.hasNext()) {
- PathArgument currentArg = iterator.next();
+ List<PathArgument> currentArguments = new ArrayList<>();
+ DataNormalizationOperation<?> currentOp = codec.getDataNormalizer().getRootOperation();
+ Iterator<PathArgument> 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<NormalizedNode<?, ?>> 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,
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.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 extends RpcService> T getDelegate(final RpcService proxy) {
+ try {
+ Class<? extends RpcService> _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<? extends RpcService> _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<? extends Object> _type = field.getType();
+ Class<? extends RpcService> _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<? extends Object> _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<? extends Object> _type = field.getType();
+ Class<? extends Object> _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<InstanceIdentifier<? extends Object>,? extends RpcService> getRoutingTable(final RpcService target, final Class<? extends BaseIdentity> tableClass) {
+ try {
+ Class<? extends RpcService> _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<InstanceIdentifier<? extends Object>,? 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<? extends BaseIdentity> tableClass, final Map<InstanceIdentifier<? extends Object>,? extends RpcService> routingTable) {
+ try {
+ Class<? extends RpcService> _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
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.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 <T extends RpcService> 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<InstanceIdentifier<?>, ? extends RpcService> getRoutingTable(RpcService target,
- Class<? extends BaseIdentity> 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<InstanceIdentifier<? extends Object>, ? extends RpcService>;
- }
-
- public static def void setRoutingTable(RpcService target, Class<? extends BaseIdentity> tableClass,
- Map<InstanceIdentifier<?>, ? 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);
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+
+package org.opendaylight.controller.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
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.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))
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+
+package org.opendaylight.controller.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<? extends Object> loadClass(final String name) throws ClassNotFoundException {
+ try {
+ return super.loadClass(name);
+ } catch (ClassNotFoundException e) {
+ return this.spiClassLoader.loadClass(name);
+ }
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.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);
- }
- }
-
-}
override publish(Notification notification, ExecutorService service) {\r
val allTypes = notification.notificationTypes\r
\r
- var Iterable<NotificationListener<?>> listenerToNotify = Collections.emptySet();\r
+ var Iterable<NotificationListener<? extends Object>> listenerToNotify = Collections.emptySet();\r
for (type : allTypes) {\r
listenerToNotify = listenerToNotify + listeners.get(type as Class<? extends Notification>)\r
}\r
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.binding.impl;
+
+import org.opendaylight.yangtools.yang.binding.RpcService;
+import org.osgi.framework.ServiceRegistration;
+
+@SuppressWarnings("all")
+public class RpcProxyContext {
+ public RpcProxyContext(final Class<? extends RpcService> proxyClass) {
+ this.proxyClass = proxyClass;
+ }
+
+ protected final Class<? extends RpcService> proxyClass;
+
+ protected RpcService _proxy;
+
+ public RpcService getProxy() {
+ return this._proxy;
+ }
+
+ public void setProxy(final RpcService proxy) {
+ this._proxy = proxy;
+ }
+
+ protected ServiceRegistration<? extends RpcService> _registration;
+
+ public ServiceRegistration<? extends RpcService> getRegistration() {
+ return this._registration;
+ }
+
+ public void setRegistration(final ServiceRegistration<? extends RpcService> registration) {
+ this._registration = registration;
+ }
+}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl
-
-import org.opendaylight.yangtools.yang.binding.RpcService
-import org.osgi.framework.ServiceRegistration
-
-class RpcProxyContext {
-
- new(Class<? extends RpcService> proxyClass) {
- this.proxyClass = proxyClass
- }
-
- protected val Class<? extends RpcService> proxyClass;
-
- @Property
- protected var RpcService proxy;
-
- @Property
- protected var ServiceRegistration<? extends RpcService> registration;
-}
\ No newline at end of file
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, //
}
}
+
@Override
- public RpcResult<CompositeNode> invokeRpc(final QName rpc, final CompositeNode domInput) {
+ public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(final QName rpc, final CompositeNode domInput) {
checkArgument(rpc != null);
checkArgument(domInput != null);
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);
}
}
}
@Override
- public Future<RpcResult<?>> forwardToDomBroker(final DataObject input) {
- if(biRpcRegistry != null) {
- CompositeNode xml = mappingService.toDataDom(input);
- CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
- RpcResult<CompositeNode> 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.<RpcResult<?>> immediateFuture(baResult);
+ public ListenableFuture<RpcResult<?>> forwardToDomBroker(final DataObject input) {
+ if(biRpcRegistry == null) {
+ return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
}
- return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
- }
+ CompositeNode xml = mappingService.toDataDom(input);
+ CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.<Node<?>> of(xml));
+
+ return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
+ @Override
+ public RpcResult<?> apply(RpcResult<CompositeNode> 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 {
}
@Override
- public Future<RpcResult<?>> forwardToDomBroker(final DataObject input) {
- if(biRpcRegistry != null) {
- CompositeNode xml = mappingService.toDataDom(input);
- CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.<Node<?>>of(xml));
- RpcResult<CompositeNode> result = biRpcRegistry.invokeRpc(rpc, wrappedXml);
- Object baResultValue = null;
- RpcResult<?> baResult = Rpcs.<Void>getRpcResult(result.isSuccessful(), null, result.getErrors());
- return Futures.<RpcResult<?>>immediateFuture(baResult);
+ public ListenableFuture<RpcResult<?>> forwardToDomBroker(final DataObject input) {
+ if(biRpcRegistry == null) {
+ return Futures.<RpcResult<?>> immediateFuture(Rpcs.getRpcResult(false));
}
- return Futures.<RpcResult<?>>immediateFuture(Rpcs.getRpcResult(false));
- }
+ CompositeNode xml = mappingService.toDataDom(input);
+ CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.<Node<?>>of(xml));
+
+ return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), new Function<RpcResult<CompositeNode>, RpcResult<?>>() {
+ @Override
+ public RpcResult<?> apply(RpcResult<CompositeNode> input) {
+ return Rpcs.<Void>getRpcResult(input.isSuccessful(), null, input.getErrors());
+ }
+ });
+ }
}
public boolean isRpcForwarding() {
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.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<InstanceIdentifier<? extends DataObject>,DataObject> {
+ protected DataObject merge(final InstanceIdentifier<? extends DataObject> path, final Iterable<DataObject> data) {
+ return data.iterator().next();
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.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<InstanceIdentifier<? extends DataObject>, DataObject> {
-
- override protected merge(InstanceIdentifier<? extends DataObject> path, Iterable<DataObject> data) {
- return data.iterator.next;
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.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 <P extends Path<P>, V extends Object> Collection<Entry<? extends P,? extends V>> getAllChildren(final Multimap<? extends P,? extends V> map, final P path) {
+ HashSet<Entry<? extends P,? extends V>> _hashSet = new HashSet<Entry<? extends P, ? extends V>>();
+ final HashSet<Entry<? extends P,? extends V>> ret = _hashSet;
+ final Collection<? extends Entry<? extends P,? extends V>> entries = map.entries();
+ for (final Entry<? extends P,? extends V> entry : entries) {
+ {
+ final P currentPath = entry.getKey();
+ if (path.contains(currentPath)) {
+ ret.add(entry);
+ } else if (currentPath.contains(path)){
+ ret.add(entry);
+ }
+ }
+ }
+ return ret;
+ }
+}
+
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.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 <P extends Path<P>, V> Collection<Entry<? extends P, ? extends V>> getAllChildren(
- Multimap<? extends P, ? extends V> 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;
- }
-}
private void startDomBroker() {
checkState(executor != null);
biBrokerImpl = new BrokerImpl();
- biBrokerImpl.setExecutor(executor);
biBrokerImpl.setRouter(new SchemaAwareRpcBroker("/", this));
}
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
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 {
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");
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() {
}
@Test
- public void bindingRoutedRpcProvider_DomInvokerTest() {
+ public void bindingRoutedRpcProvider_DomInvokerTest() throws Exception {
flowService//
.registerPath(NodeContext.class, BA_NODE_A_ID) //
CompositeNode addFlowDom = toDomRpc(ADD_FLOW_QNAME, addFlowA);
assertNotNull(addFlowDom);
- RpcResult<CompositeNode> domResult = biRpcInvoker.invokeRpc(ADD_FLOW_QNAME, addFlowDom);
+ RpcResult<CompositeNode> 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));
final AddFlowOutput output = builder.build();
org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration registration = biRpcRegistry.addRoutedRpcImplementation(ADD_FLOW_QNAME, new RpcImplementation() {
@Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
- CompositeNode result = testContext.getBindingToDomMappingService().toDataDom(output);
- return Rpcs.getRpcResult(true, result, ImmutableList.<RpcError>of());
+ public Set<QName> getSupportedRpcs() {
+ return ImmutableSet.of(ADD_FLOW_QNAME);
}
@Override
- public Set<QName> getSupportedRpcs() {
- return ImmutableSet.of(ADD_FLOW_QNAME);
+ public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
+ CompositeNode result = testContext.getBindingToDomMappingService().toDataDom(output);
+ return Futures.immediateFuture(Rpcs.getRpcResult(true, result, ImmutableList.<RpcError>of()));
}
});
registration.registerPath(NodeContext.QNAME, BI_NODE_C_ID);
-
+
SalFlowService baFlowInvoker = baRpcRegistry.getRpcService(SalFlowService.class);
Future<RpcResult<AddFlowOutput>> baResult = baFlowInvoker.addFlow(addFlow(BA_NODE_C_ID).setPriority(500).build());
assertNotNull(baResult);
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.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);
+ }
+}
+/*
+ * 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;
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);
Set<DataNormalizationOperation<?>> 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
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));
}
@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;
}
@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;
}
}
- 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<org.opendaylight.yangtools.yang.model.api.ChoiceNode> 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);
}
}
}
- 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());
+/*
+ * 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;
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;
DataNormalizationOperation<?> currentOp = operation;
Iterator<PathArgument> 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());
}
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<PathArgument> reworkedArgs = new ArrayList<>(normalizedPath.getPath());
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<dependencies>
+/*
+ * 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;
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<CompositeNode> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input);
+ ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input);
}
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.
*
* {@link RpcResult}
* <li> {@link Broker} returns the {@link RpcResult} to {@link Consumer}
* </ol>
- *
- *
*/
public interface RpcImplementation extends Provider.ProviderFunctionality {
Set<QName> 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
* <ul>
* <li>If input is not <code>null</code> and
* <code>false == rpc.equals(input.getNodeType)</code>
* </ul>
- * @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<CompositeNode> invokeRpc(QName rpc, CompositeNode input);
-
+ ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input);
}
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- <source>src/main/xtend-gen</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
<plugin>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
+/*
+ * 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;
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;
Iterator<PathArgument> 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();
*/
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
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
private val Set<ProviderContextImpl> providerSessions = Collections.synchronizedSet(
new HashSet<ProviderContextImpl>());
- // Implementation specific
- @Property
- private var ExecutorService executor = Executors.newFixedThreadPool(5);
@Property
private var BundleContext bundleContext;
-
+
@Property
private var AutoCloseable deactivator;
return session;
}
- protected def Future<RpcResult<CompositeNode>> invokeRpcAsync(QName rpc, CompositeNode input) {
- val result = executor.submit([|router.invokeRpc(rpc, input)] as Callable<RpcResult<CompositeNode>>);
- return result;
+ protected def ListenableFuture<RpcResult<CompositeNode>> invokeRpcAsync(QName rpc, CompositeNode input) {
+ return router.invokeRpc(rpc, input);
}
// Validation
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);
}
override addRpcRegistrationListener(RpcRegistrationListener listener) {
return router.addRpcRegistrationListener(listener);
}
-
+
override <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> 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)
+ }
+
}
return rpcs.getSupportedRpcs();
}
-
@Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
return rpcs.invokeRpc(rpc, input);
}
return rpcs.addRpcRegistrationListener(listener);
}
-
@Override
public ListenableFuture<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input) {
return null;
L listener) {
return rpcs.registerRouteChangeListener(listener);
}
-
-
}
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<String>, RoutedRpcDefaultImplementation {
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");
}
@Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
return findRpcImplemention(rpc).invokeRpc(rpc, input);
}
}
@Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
+ public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
checkState(defaultDelegate != null);
return defaultDelegate.invokeRpc(rpc, identifier, input);
}
}
@Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ public ListenableFuture<RpcResult<CompositeNode>> 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());
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;
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<RpcProvisionRegistry>
implements RpcProvisionRegistry {
return getDelegate().addRoutedRpcImplementation(rpcType, implementation);
}
- @Override
- public void setRoutedRpcDefaultDelegate(RoutedRpcDefaultImplementation defaultImplementation) {
- getDelegate().setRoutedRpcDefaultDelegate(defaultImplementation);
- }
+ @Override
+ public void setRoutedRpcDefaultDelegate(RoutedRpcDefaultImplementation defaultImplementation) {
+ getDelegate().setRoutedRpcDefaultDelegate(defaultImplementation);
+ }
- @Override
+ @Override
public <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(L listener) {
return getDelegate().registerRouteChangeListener(listener);
}
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return getDelegate().getSupportedRpcs();
+ }
- @Override
- public Set<QName> getSupportedRpcs() {
- return getDelegate().getSupportedRpcs();
- }
-
- @Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
- return getDelegate().invokeRpc(rpc,input);
- }
+ @Override
+ public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
+ return getDelegate().invokeRpc(rpc, input);
+ }
}
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<QName> getSupportedRpcs();
-
- public QName getRpcType();
-
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input);
+ QName getRpcType();
Map<InstanceIdentifier,RpcImplementation> getRoutes();
-
+
RpcImplementation getDefaultRoute();
}
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 {
@Override
public Set<QName> getSupportedRpcs();
-
- @Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input);
}
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/config</source>
- <source>src/main/xtend-gen</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
-
<plugin>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
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");
.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;
}
}
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
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
import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
-class NetconfDevice implements Provider, //
+class NetconfDevice implements Provider, //
DataReader<InstanceIdentifier, CompositeNode>, //
DataCommitHandler<InstanceIdentifier, CompositeNode>, //
RpcImplementation, //
AutoCloseable {
- var NetconfClient client;
-
@Property
var InetSocketAddress socketAddress;
Registration<DataReader<InstanceIdentifier, CompositeNode>> operReaderReg
Registration<DataReader<InstanceIdentifier, CompositeNode>> confReaderReg
Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> commitHandlerReg
+ List<RpcRegistration> rpcReg
+ @Property
val String name
- MountProvisionService mountService
- int messegeRetryCount = 5;
-
- int messageTimeoutCount = 5 * 1000;
-
- Set<QName> cachedCapabilities
+ MountProvisionService mountService
@Property
var NetconfClientDispatcher dispatcher
@Property
var SchemaSourceProvider<InputStream> 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;
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<Void>;
+ listener = new NetconfDeviceListener(this);
+
+ logger.info("Starting NETCONF Client {} for address {}", name, socketAddress);
+ dispatcher.createClient(socketAddress, listener, reconnectStrategy);
}
def Optional<SchemaContext> getSchemaContext() {
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<String> 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.<String>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<String> delegate, Set<QName> 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<RpcRegistration>();
+ for (rpc : mountInstance.schemaContext.operations) {
+ rpcs.add(mountInstance.addRpcImplementation(rpc.QName, this));
+ }
+ rpcReg = rpcs
+ }
+ }
+
+ private def updateDeviceState(boolean up, Set<QName> 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) {
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;
}
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() {
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());
}
override requestCommit(DataModification<InstanceIdentifier, CompositeNode> 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<String> capabilities) {
+ return FluentIterable.from(capabilities).filter[
contains("?") && contains("module=") && contains("revision=")].transform [
val parts = split("\\?");
val namespace = parts.get(0);
}
return QName.create(namespace, revision, moduleName);
].toSet();
- }
- return cachedCapabilities;
}
override close() {
- confReaderReg?.close()
- operReaderReg?.close()
- client?.close()
+ bringDown()
}
-
}
package class NetconfDeviceSchemaContextProvider {
*/
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<RpcResult<CompositeNode>> future;
+ final NetconfMessage request;
+
+ private Request(UncancellableFuture<RpcResult<CompositeNode>> 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<Request> 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<QName> caps = device.getCapabilities(session.getServerCapabilities());
+ LOG.trace("Server {} advertized capabilities {}", device.getName(), caps);
+
+ // Select the appropriate provider
+ final SchemaSourceProvider<String> 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.<String>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<Request> 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.<RpcError>emptyList()));
+ } else {
+ LOG.warn("Ignoring unsolicited message", message);
+ }
+ }
+
+ synchronized ListenableFuture<RpcResult<CompositeNode>> sendRequest(final NetconfMessage message) {
+ if (session == null) {
+ LOG.debug("Session to {} is disconnected, failing RPC request {}", device.getName(), message);
+ return Futures.<RpcResult<CompositeNode>>immediateFuture(new RpcResult<CompositeNode>() {
+ @Override
+ public boolean isSuccessful() {
+ return false;
+ }
+
+ @Override
+ public CompositeNode getResult() {
+ return null;
+ }
+
+ @Override
+ public Collection<RpcError> getErrors() {
+ // FIXME: indicate that the session is down
+ return Collections.emptySet();
+ }
+ });
+ }
+
+ final Request req = new Request(new UncancellableFuture<RpcResult<CompositeNode>>(true), message);
+ requests.add(req);
+
+ session.sendMessage(req.request).addListener(new FutureListener<Void>() {
+ @Override
+ public void operationComplete(final Future<Void> future) throws Exception {
+ if (!future.isSuccess()) {
+ // We expect that a session down will occur at this point
+ LOG.debug("Failed to send request {}", req.request, future.cause());
+ 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()) ;
+ }
}
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;
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<InstanceIdentifier, CompositeNode> {
-
- private final NetconfDevice device;
+class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction<InstanceIdentifier, CompositeNode> {
+ private static final Logger LOG = LoggerFactory.getLogger(NetconfDeviceTwoPhaseCommitTransaction.class);
private final DataModification<InstanceIdentifier, CompositeNode> modification;
- private final boolean candidateSupported = true;
+ private final NetconfDevice device;
+ private final boolean candidateSupported;
public NetconfDeviceTwoPhaseCommitTransaction(NetconfDevice device,
- DataModification<InstanceIdentifier, CompositeNode> modification) {
- super();
- this.device = device;
- this.modification = modification;
+ DataModification<InstanceIdentifier, CompositeNode> 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<InstanceIdentifier, CompositeNode> 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.<String>absent(), Optional.of(value)));
}
- private void sendDelete(InstanceIdentifier toDelete) {
+ private void sendDelete(InstanceIdentifier toDelete) throws InterruptedException, ExecutionException {
sendEditRpc(createEditStructure(toDelete, Optional.of("delete"), Optional.<CompositeNode> absent()));
}
- private void sendEditRpc(CompositeNode editStructure) {
+ private void sendEditRpc(CompositeNode editStructure) throws InterruptedException, ExecutionException {
CompositeNodeBuilder<ImmutableCompositeNode> builder = configurationRpcBuilder();
builder.setQName(NETCONF_EDIT_CONFIG_QNAME);
builder.add(editStructure);
- RpcResult<CompositeNode> rpcResult = device.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, builder.toInstance());
+ RpcResult<CompositeNode> rpcResult = device.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, builder.toInstance()).get();
Preconditions.checkState(rpcResult.isSuccessful(),"Rpc Result was unsuccessful");
-
}
private CompositeNodeBuilder<ImmutableCompositeNode> configurationRpcBuilder() {
public RpcResult<Void> finish() {
CompositeNodeBuilder<ImmutableCompositeNode> commitInput = ImmutableCompositeNode.builder();
commitInput.setQName(NETCONF_COMMIT_QNAME);
- RpcResult<?> rpcResult = device.invokeRpc(NetconfMapping.NETCONF_COMMIT_QNAME, commitInput.toInstance());
- return (RpcResult<Void>) rpcResult;
+ try {
+ final RpcResult<?> rpcResult = device.invokeRpc(NetconfMapping.NETCONF_COMMIT_QNAME, commitInput.toInstance()).get();
+ return new RpcResult<Void>() {
+
+ @Override
+ public boolean isSuccessful() {
+ return rpcResult.isSuccessful();
+ }
+
+ @Override
+ public Void getResult() {
+ return null;
+ }
+
+ @Override
+ public Collection<RpcError> getErrors() {
+ return rpcResult.getErrors();
+ }
+ };
+ } catch (final InterruptedException | ExecutionException e) {
+ LOG.warn("Failed to finish operation", e);
+ return new RpcResult<Void>() {
+ @Override
+ public boolean isSuccessful() {
+ return false;
+ }
+
+ @Override
+ public Void getResult() {
+ return null;
+ }
+
+ @Override
+ public Collection<RpcError> getErrors() {
+ // FIXME: wrap the exception
+ return Collections.emptySet();
+ }
+ };
+ }
}
@Override
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();
}
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");
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");
if(identifier.path.empty) {
return null;
}
-
+
for (component : identifier.path.reverseView) {
val Node<?> current = component.toNode(previous);
previous = current;
}
static def CompositeNode toCompositeNode(NetconfMessage message,Optional<SchemaContext> 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<SchemaContext> ctx) {
if (ctx.present) {
val schemaContext = ctx.get
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<CompositeNode> toRpcResult(NetconfMessage message,QName rpc,Optional<SchemaContext> 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) {
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.");
-
+
}
-
+
}
*/
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;
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<String> {
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
}
device.logger.trace("Loading YANG schema source for {}:{}", moduleName, revision);
- RpcResult<CompositeNode> 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<CompositeNode> 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();
}
return null;
}
- public static final boolean isSupportedFor(Set<QName> capabilities) {
+ public static final boolean isSupportedFor(Collection<QName> capabilities) {
return capabilities.contains(IETF_NETCONF_MONITORING);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.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<V> extends AbstractFuture<V> {
+ @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);
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.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<InputStream> {
-
- 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)));
- }
-}
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
</project>
<codeGeneratorClass>
org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
</codeGeneratorClass>
- <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
<additionalConfiguration>
<namespaceToPackage1>
urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
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;
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
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(){
return routingTableProvider;
}
+ @Override
public void setRoutingTableProvider(RoutingTableProvider routingTableProvider) {
this.routingTableProvider = routingTableProvider;
}
* @param input payload for the remote service
* @return
*/
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
RouteIdentifierImpl routeId = new RouteIdentifierImpl();
routeId.setType(rpc);
* payload
* @return
*/
- public RpcResult<CompositeNode> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
+ public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
RouteIdentifierImpl routeId = new RouteIdentifierImpl();
routeId.setType(rpc);
return sendMessage(input, routeId, address);
}
- private RpcResult<CompositeNode> sendMessage(CompositeNode input, RouteIdentifierImpl routeId, String address) {
+ private ListenableFuture<RpcResult<CompositeNode>> sendMessage(CompositeNode input, RouteIdentifierImpl routeId, String address) {
Message request = new Message.MessageBuilder()
.type(Message.MessageType.REQUEST)
.sender(Context.getInstance().getLocalUri())
}
}
- 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.<CompositeNode>getRpcResult(false, null, errors));
}
}
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;
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,
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;
}
@Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
return client.invokeRpc(rpc, input);
}
@Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
+ public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
return client.invokeRpc(rpc, identifier, input);
}
return routeIdSet;
}
-
-
}
-
}
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()) {
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;
*/
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;
/**
*
when(mockHandler.handle(any(Message.class))).
thenReturn(MessagingUtil.createEmptyMessage());
- RpcResult<CompositeNode> result = client.invokeRpc(null, null);
+ RpcResult<CompositeNode> result = client.invokeRpc(null, null).get();
Assert.assertTrue(result.isSuccessful());
Assert.assertTrue(result.getErrors().isEmpty());
when(mockHandler.handle(any(Message.class))).
thenThrow(new IOException());
- RpcResult<CompositeNode> result = client.invokeRpc(null, null);
+ RpcResult<CompositeNode> result = client.invokeRpc(null, null).get();
Assert.assertFalse(result.isSuccessful());
Assert.assertFalse(result.getErrors().isEmpty());
+ "\" 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;
}
}
- private def void addKeyValue(HashMap<QName, Object> map, DataSchemaNode node, String uriValue) {
+ private def void addKeyValue(HashMap<QName, Object> 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)
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${project.build.directory}/generated-sources/</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
</project>
org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
</codeGeneratorClass>
<outputBaseDir>
- target/generated-sources/sal
+ ${salGeneratorPath}
</outputBaseDir>
</generator>
<generator>
<properties>
<sal-binding-api.version>1.1-SNAPSHOT</sal-binding-api.version>
- <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
-
</properties>
<build>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${jmxGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
<properties>
- <jmxGeneratorPath>${project.build.directory}/generated-sources/config</jmxGeneratorPath>
<sal-binding-api.version>1.1-SNAPSHOT</sal-binding-api.version>
</properties>
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
- <executions>
- <execution>
- <id>add-source</id>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${jmxGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</build>
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.7</version>
- <executions>
- <execution>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>target/generated-sources/sal</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
<pluginManagement>
<plugins>
</instructions>
</configuration>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
</project>
<plugin>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>compile</goal>
- </goals>
- <configuration>
- <outputDirectory>${basedir}/src/main/xtend-gen</outputDirectory>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- <configuration>
- <filesets>
- <fileset>
- <directory>${basedir}/src/main/xtend-gen</directory>
- <includes>
- <include>**</include>
- </includes>
- </fileset>
- </filesets>
- </configuration>
</plugin>
</plugins>
</build>
<groupId>org.eclipse.xtend</groupId>
<artifactId>xtend-maven-plugin</artifactId>
</plugin>
- <plugin>
- <artifactId>maven-clean-plugin</artifactId>
- </plugin>
</plugins>
</build>
</project>
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;
@Mock
NetconfOperationRouter netconfOperationRouter;
@Mock
- NetconfOperationServiceSnapshot netconfOperationServiceSnapshot;
+ NetconfOperationServiceSnapshotImpl netconfOperationServiceSnapshot;
private TransactionProvider transactionProvider;
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;
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);
public static final String STORAGE_ADAPTER_CLASS_PROP_SUFFIX = "storageAdapterClass";
-
- private static final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
-
private List<AutoCloseable> autoCloseables;
autoCloseables = new ArrayList<>();
PropertiesProviderBaseImpl propertiesProvider = new PropertiesProviderBaseImpl(context);
-
final PersisterAggregator persisterAggregator = PersisterAggregator.createFromProperties(propertiesProvider);
autoCloseables.add(persisterAggregator);
- final long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider);
- final List<ConfigSnapshotHolder> configs = persisterAggregator.loadLastConfigs();
- final long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider);
+ long maxWaitForCapabilitiesMillis = getMaxWaitForCapabilitiesMillis(propertiesProvider);
+ List<ConfigSnapshotHolder> configs = persisterAggregator.loadLastConfigs();
+ long conflictingVersionTimeoutMillis = getConflictingVersionTimeoutMillis(propertiesProvider);
logger.trace("Following configs will be pushed: {}", configs);
- ServiceTrackerCustomizer<NetconfOperationServiceFactory, NetconfOperationServiceFactory> configNetconfCustomizer = new ServiceTrackerCustomizer<NetconfOperationServiceFactory, NetconfOperationServiceFactory>() {
- @Override
- public NetconfOperationServiceFactory addingService(ServiceReference<NetconfOperationServiceFactory> 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<NetconfOperationServiceFactory> 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<NetconfOperationServiceFactory> 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<NetconfOperationServiceFactory, NetconfOperationServiceFactory> tracker =
- new ServiceTracker<>(context, filter, configNetconfCustomizer);
- tracker.open();
+ @Override
+ public synchronized void stop(BundleContext context) throws Exception {
+ CloseableUtil.closeAll(autoCloseables);
}
")";
}
- 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<NetconfOperationProvider, NetconfOperationProvider> {
+ 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<NetconfOperationProvider> 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<NetconfOperationProvider> reference, NetconfOperationProvider service) {
+
+ }
+
+ @Override
+ public void removedService(ServiceReference<NetconfOperationProvider> reference, NetconfOperationProvider service) {
+
+ }
+ }
+
+ class InnerCustomizer implements ServiceTrackerCustomizer<NetconfOperationServiceFactory, NetconfOperationServiceFactory> {
+ private final List<ConfigSnapshotHolder> configs;
+ private final PersisterAggregator persisterAggregator;
+ private final long maxWaitForCapabilitiesMillis, conflictingVersionTimeoutMillis;
+
+
+ InnerCustomizer(List<ConfigSnapshotHolder> configs, long maxWaitForCapabilitiesMillis, long conflictingVersionTimeoutMillis,
+ PersisterAggregator persisterAggregator) {
+ this.configs = configs;
+ this.maxWaitForCapabilitiesMillis = maxWaitForCapabilitiesMillis;
+ this.conflictingVersionTimeoutMillis = conflictingVersionTimeoutMillis;
+ this.persisterAggregator = persisterAggregator;
+ }
+
+ @Override
+ public NetconfOperationServiceFactory addingService(ServiceReference<NetconfOperationServiceFactory> 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<NetconfOperationServiceFactory> reference, NetconfOperationServiceFactory service) {
}
- if (lastException != null) {
- throw lastException;
+
+ @Override
+ public void removedService(ServiceReference<NetconfOperationServiceFactory> reference, NetconfOperationServiceFactory service) {
}
+
}
}
+
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;
private MockedBundleContext ctx;
private ConfigPersisterActivator configPersisterActivator;
- private static final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
private TestingExceptionHandler handler;
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;
@Mock
private BundleContext context;
@Mock
- private Filter filter;
+ private Filter outerFilter, innerFilter;
@Mock
private ServiceReference<?> serviceReference;
@Mock
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();
doReturn(service).when(serviceFactory).createService(anyString());
doReturn(Collections.emptySet()).when(service).getCapabilities();
doNothing().when(service).close();
+ doReturn("serviceFactoryMock").when(serviceFactory).toString();
}
public BundleContext getBundleContext() {
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-maven-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
Document onNetconfMessage(Document message, NetconfSession session)
throws NetconfDocumentedException;
- @Override
- void close();
}
public String getErrorMessage() {
return reason;
}
+
+ @Override
+ public String toString() {
+ return reason;
+ }
}
</instructions>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.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()) ;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.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<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strat);
- this.address = address;
- clientSession = get(clientFuture);
- this.sessionId = clientSession.getSessionId();
- }
-
- private NetconfClientSession get(Future<NetconfClientSession> 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<NetconfClientSession> clientFuture = dispatch.createClient(address, sessionListener, strategy);
- this.address = address;
- clientSession = get(clientFuture);
- this.sessionId = clientSession.getSessionId();
- }
-
- public Future<NetconfMessage> 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<String> getCapabilities() {
- Preconditions.checkState(clientSession != null, "Client was not initialized successfully");
- return Sets.newHashSet(clientSession.getServerCapabilities());
- }
-
- public NetconfClientSession getClientSession() {
- return clientSession;
- }
-}
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,
}
}
- final synchronized Future<NetconfMessage> sendRequest(NetconfMessage message) {
+ public final synchronized Future<NetconfMessage> sendRequest(NetconfMessage message) {
final RequestEntry req = new RequestEntry(GlobalEventExecutor.INSTANCE.<NetconfMessage>newPromise(), message);
requests.add(req);
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.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);
- }
- }
- };
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.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<NetconfClientSession> clientFuture = netconfClientDispatcher.createClient(address, sessionListener, strat);
+ clientSession = get(clientFuture);
+ this.sessionId = clientSession.getSessionId();
+ }
+
+ private NetconfClientSession get(Future<NetconfClientSession> 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<NetconfMessage> 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<String> getCapabilities() {
+ Preconditions.checkState(clientSession != null, "Client was not initialized successfully");
+ return Sets.newHashSet(clientSession.getServerCapabilities());
+ }
+}
\ No newline at end of file
<artifactId>netconf-client</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-client</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.logback_settings</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
</plugin>
</plugins>
</build>
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;
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<NetconfServerSession, NetconfServerSessionListener> {
private final ServerChannelInitializer initializer;
public static final String DESERIALIZER_EX_HANDLER_KEY = "deserializerExHandler";
private final NetconfServerSessionNegotiatorFactory negotiatorFactory;
- private final NetconfServerSessionListenerFactory listenerFactory;
- public ServerChannelInitializer(NetconfServerSessionNegotiatorFactory negotiatorFactory,
- NetconfServerSessionListenerFactory listenerFactory) {
+
+ public ServerChannelInitializer(NetconfServerSessionNegotiatorFactory negotiatorFactory) {
this.negotiatorFactory = negotiatorFactory;
- this.listenerFactory = listenerFactory;
+
}
@Override
@Override
protected void initializeSessionNegotiator(SocketChannel ch, Promise<NetconfServerSession> 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));
}
}
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;
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<NetconfServerSession> {
public static final String MESSAGE_ID = "message-id";
static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionListener.class);
private final SessionMonitoringService monitoringService;
private final NetconfOperationRouter operationRouter;
+ private final AutoCloseable onSessionDownCloseable;
- public NetconfServerSessionListener(NetconfOperationRouter operationRouter, SessionMonitoringService monitoringService) {
+ public NetconfServerSessionListener(NetconfOperationRouter operationRouter, SessionMonitoringService monitoringService,
+ AutoCloseable onSessionDownCloseable) {
this.operationRouter = operationRouter;
this.monitoringService = monitoringService;
+ this.onSessionDownCloseable = onSessionDownCloseable;
}
@Override
}
@Override
- public void onSessionDown(NetconfServerSession netconfNetconfServerSession, Exception e) {
- logger.debug("Session {} down, reason: {}", netconfNetconfServerSession, e.getMessage());
+ public void onSessionDown(NetconfServerSession netconfNetconfServerSession, Exception cause) {
+ logger.debug("Session {} down, reason: {}", netconfNetconfServerSession, cause.getMessage());
+ onDown(netconfNetconfServerSession);
+ }
+
+ public void onDown(NetconfServerSession netconfNetconfServerSession) {
monitoringService.onSessionDown(netconfNetconfServerSession);
- operationRouter.close();
+ try {
+ operationRouter.close();
+ } catch (Exception closingEx) {
+ logger.debug("Ignoring exception while closing operationRouter", closingEx);
+ }
+ try {
+ onSessionDownCloseable.close();
+ } catch(Exception ex){
+ logger.debug("Ignoring exception while closing onSessionDownCloseable", ex);
+ }
}
@Override
NetconfTerminationReason netconfTerminationReason) {
logger.debug("Session {} terminated, reason: {}", netconfNetconfServerSession,
netconfTerminationReason.getErrorMessage());
- monitoringService.onSessionDown(netconfNetconfServerSession);
-
- operationRouter.close();
+ onDown(netconfNetconfServerSession);
}
@Override
import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouterImpl;
-import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
-import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceSnapshot;
import org.opendaylight.protocol.framework.SessionListenerFactory;
public class NetconfServerSessionListenerFactory implements SessionListenerFactory<NetconfServerSessionListener> {
- 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);
}
}
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;
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<NetconfServerSessionPreferences, NetconfServerSession, NetconfServerSessionListener> {
return new NetconfServerSession(sessionListener, channel, getSessionPreferences().getSessionId(), parsedHeader);
}
- }
+}
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;
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<NetconfHelloMessage, NetconfServerSession, NetconfServerSessionListener> {
public static final String SERVER_HELLO_XML_LOCATION = "/server_hello.xml";
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() {
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<NetconfServerSession> getSessionNegotiator(SessionListenerFactory<NetconfServerSessionListener> sessionListenerFactory, Channel channel,
- Promise<NetconfServerSession> promise) {
+ public SessionNegotiator<NetconfServerSession> getSessionNegotiator(SessionListenerFactory<NetconfServerSessionListener> defunctSessionListenerFactory,
+ Channel channel, Promise<NetconfServerSession> 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);
}
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
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.<String>absent());
capabilityElement.setTextContent(capability);
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;
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;
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;
private NetconfOperationServiceFactoryTracker factoriesTracker;
private DefaultCommitNotificationProducer commitNot;
- private NetconfServerDispatcher dispatch;
private NioEventLoopGroup eventLoopGroup;
private HashedWheelTimer timer;
private ServiceRegistration<NetconfMonitoringService> regMonitoring;
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) {
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;
private static final Logger logger = LoggerFactory.getLogger(NetconfMonitoringServiceImpl.class);
private final Set<NetconfManagementSession> 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
@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);
}
@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<NetconfOperationService> services) {
Set<Capability> caps = Sets.newHashSet();
List<Schema> 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());
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()));
builder.setFormat(Yang.class);
- builder.setLocation(transformLocations(cap.getLocation().or(Collections.<String> emptyList())));
+ builder.setLocation(transformLocations(cap.getLocation().or(Collections.<String>emptyList())));
builder.setKey(new SchemaKey(Yang.class, identifier, version));
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;
String errorMessage = String.format("Unable to handle rpc %s on session %s", messageAsString, session);
Map<String, String> 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;
}
}
@Override
- public void close() {
+ public void close() throws Exception {
netconfOperationServiceSnapshot.close();
}
void onRemoveNetconfOperationServiceFactory(NetconfOperationServiceFactory service);
- NetconfOperationServiceSnapshot getSnapshot(long sessionId);
+
}
*/
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<NetconfOperationServiceFactory> allFactories = new HashSet<>();
@Override
}
@Override
- public synchronized NetconfOperationServiceSnapshot getSnapshot(long sessionId) {
- return new NetconfOperationServiceSnapshot(allFactories, sessionId);
+ public synchronized NetconfOperationServiceSnapshotImpl openSnapshot(String sessionIdForReporting) {
+ return new NetconfOperationServiceSnapshotImpl(allFactories, sessionIdForReporting);
}
}
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<NetconfOperationService> services;
private final String netconfSessionIdForReporting;
- public NetconfOperationServiceSnapshot(Set<NetconfOperationServiceFactory> factories, long sessionId) {
+ public NetconfOperationServiceSnapshotImpl(Set<NetconfOperationServiceFactory> factories, String sessionIdForReporting) {
Set<NetconfOperationService> 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<NetconfOperationService> 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 + '}';
}
}
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;
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 {
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);
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);
@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);
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;
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);
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
+ <properties>
+ <tinybundles.version>2.0.0</tinybundles.version>
+ </properties>
<parent>
<artifactId>netconf-subsystem</artifactId>
<artifactId>netconf-client</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-client</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>config-netconf-connector</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netty-config-api</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>config-manager</artifactId>
<artifactId>netconf-impl</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-impl</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-monitoring</artifactId>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.logback_settings</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.tinybundles</groupId>
+ <artifactId>tinybundles</artifactId>
+ <version>${tinybundles.version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
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;
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);
}
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;
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;
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()));
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, "<modules");
assertResponse(response, "<services");
}
- public NetconfOperationServiceFactoryListener getFactoriesListener() {
- NetconfOperationServiceFactoryListener factoriesListener = mock(NetconfOperationServiceFactoryListener.class);
- NetconfOperationServiceSnapshot snap = mock(NetconfOperationServiceSnapshot.class);
+ public NetconfOperationProvider getNetconfOperationProvider() {
+ NetconfOperationProvider factoriesListener = mock(NetconfOperationProvider.class);
+ NetconfOperationServiceSnapshotImpl snap = mock(NetconfOperationServiceSnapshotImpl.class);
NetconfOperationService service = mock(NetconfOperationService.class);
Set<Capability> caps = Sets.newHashSet();
doReturn(caps).when(service).getCapabilities();
Set<NetconfOperationService> services = Sets.newHashSet(service);
doReturn(services).when(snap).getServices();
- doReturn(snap).when(factoriesListener).getSnapshot(anyLong());
+ doReturn(snap).when(factoriesListener).openSnapshot(anyString());
return factoriesListener;
}
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;
@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)) {
}
}
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;
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;
}
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.<NetconfOperationService>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
@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<String> capabilitiesFromNetconfServer = netconfClient.getCapabilities();
long sessionId = netconfClient.getSessionId();
@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)) {
}
}
}
@Test
public void rpcReplyContainsAllAttributesTest() throws Exception {
- try (NetconfClient netconfClient = createSession(tcpAddress, "1")) {
+ try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) {
final String rpc = "<rpc message-id=\"5\" a=\"a\" b=\"44\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
+ "<get/>" + "</rpc>";
final Document doc = XmlUtil.readXmlToDocument(rpc);
@Test
public void rpcReplyErrorContainsAllAttributesTest() throws Exception {
- try (NetconfClient netconfClient = createSession(tcpAddress, "1")) {
+ try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) {
final String rpc = "<rpc message-id=\"1\" a=\"adada\" b=\"4\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
+ "<commit/>" + "</rpc>";
final Document doc = XmlUtil.readXmlToDocument(rpc);
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 = "<rpc message-id=\"5\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">"
/*
@Test
public void testStartExi() throws Exception {
- try (NetconfClient netconfClient = createSession(tcpAddress, "1")) {
+ try (TestingNetconfClient netconfClient = createSession(tcpAddress, "1")) {
Document rpcReply = netconfClient.sendMessage(this.startExi)
@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)
@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);
@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());
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);
@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();
}
}
- 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;
}
*/
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 {
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()));
@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);
}
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<Capability> caps = Sets.newHashSet();
caps.add(new Capability() {
doReturn(caps).when(service).getCapabilities();
Set<NetconfOperationService> services = Sets.newHashSet(service);
doReturn(services).when(snap).getServices();
- doReturn(snap).when(factoriesListener).getSnapshot(anyLong());
+ doReturn(snap).when(factoriesListener).openSnapshot(anyString());
return factoriesListener;
}
*/
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;
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;
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 {
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() {
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",
- "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</afi>",
- "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</afi>",
- "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</safi>",
- "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</safi>");
- }
+ 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",
+ "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</afi>",
+ "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</afi>",
+ "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</safi>",
+ "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</safi>");
clientDispatcher.close();
} catch (Exception e) {
}
}
-
- 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) {
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);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.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;
+ }
+
+ }
+
+}
* 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<NetconfOperationService> getServices();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.util;
+
+public class CloseableUtil {
+
+ public static void closeAll(Iterable<? extends AutoCloseable> 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;
+ }
+
+ }
+}
<osgi.version>5.0.0</osgi.version>
<maven.bundle.version>2.4.0</maven.bundle.version>
<slf4j.version>1.7.2</slf4j.version>
- <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
</properties>
<dependencies>
<artifactId>netconf-impl</artifactId>
<version>${netconf.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>netconf-impl</artifactId>
+ <version>${netconf.version}</version>
+ <type>test-jar</type>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>netconf-monitoring</artifactId>
</dependency>
</dependencies>
</plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <version>1.7</version>
- <executions>
- <execution>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>${salGeneratorPath}</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
</plugins>
</pluginManagement>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
- <version>1.8</version>
<executions>
<execution>
<id>attach-artifacts</id>