From 0fb6159a2bf4a0b361c0404b08910c47f6f277bf Mon Sep 17 00:00:00 2001 From: Tomas Olvecky Date: Thu, 5 Dec 2013 17:22:16 +0100 Subject: [PATCH] Refactor yang-jmx-generator and -plugin to support list of dependencies. Change-Id: I87aec9e234588d12ac5ea2dd26509de1c625bbb2 Signed-off-by: Tomas Olvecky --- .../plugin/ftl/FtlFilePersister.java | 35 ++-- .../plugin/ftl/TemplateFactory.java | 171 +++++++----------- .../plugin/ftl/model/ModuleField.java | 13 +- .../freeMarker/module_abs_template_new.ftl | 23 ++- .../plugin/JMXGeneratorTest.java | 54 +----- .../yangjmxgenerator/ModuleMXBeanEntry.java | 105 +++++++---- .../yangjmxgenerator/RuntimeBeanEntry.java | 15 +- .../AbstractDependencyAttribute.java | 86 +++++++++ .../attribute/Dependency.java | 45 +++++ .../attribute/DependencyAttribute.java | 110 +---------- .../attribute/ListAttribute.java | 39 ++-- .../attribute/ListDependenciesAttribute.java | 38 ++++ .../attribute/TOAttribute.java | 30 ++- .../ModuleMXBeanEntryTest.java | 65 ++++--- .../yangjmxgenerator/SchemaContextTest.java | 13 +- .../resources/test-config-threads-java.yang | 21 +++ .../src/main/yang/config-test-impl.yang | 9 + .../AttributeIfcSwitchStatement.java | 7 +- .../attributes/fromxml/ObjectXmlReader.java | 8 + .../attributes/mapping/ObjectMapper.java | 7 + .../attributes/resolving/ObjectResolver.java | 7 + .../attributes/toxml/ObjectXmlWriter.java | 8 + .../NetconfMappingTest.java | 17 +- .../resources/netconfMessages/editConfig.xml | 9 + 24 files changed, 553 insertions(+), 382 deletions(-) create mode 100644 opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/AbstractDependencyAttribute.java create mode 100644 opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java create mode 100644 opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListDependenciesAttribute.java diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersister.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersister.java index b0b6f3d74c..f721895921 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersister.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/FtlFilePersister.java @@ -7,19 +7,9 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl; -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; - +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; @@ -33,11 +23,18 @@ import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.directives import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.annotations.VisibleForTesting; - -import freemarker.template.Configuration; -import freemarker.template.Template; -import freemarker.template.TemplateException; +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 @@ -56,7 +53,7 @@ public class FtlFilePersister { ftlFile.getFtlTempleteLocation()); try { template.process(ftlFile, writer); - } catch (TemplateException e) { + } catch (Throwable e) { throw new IllegalStateException( "Template error while generating " + ftlFile, e); } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java index 3a6ff18081..6da68018f2 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/TemplateFactory.java @@ -21,13 +21,13 @@ import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc; import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry; -import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute.Dependency; -import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.Dependency; import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; -import org.opendaylight.controller.config.yangjmxgenerator.attribute.TypedAttribute; -import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.TypedAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribute; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation; import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Annotation.Parameter; @@ -39,6 +39,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.Meth import org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model.ModuleField; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper; 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 javax.management.openmbean.SimpleType; @@ -112,8 +113,8 @@ public class TemplateFactory { // convert attributes to getters for (AttributeIfc attributeIfc : entry.getAttributes()) { - String returnType = null; - returnType = getReturnType(entry, attributeIfc); + String returnType; + returnType = getReturnType(attributeIfc); String getterName = "get" + attributeIfc.getUpperCaseCammelCase(); MethodDeclaration getter = new MethodDeclaration(returnType, @@ -132,7 +133,7 @@ public class TemplateFactory { fields.add(field); } MethodDeclaration operation = new MethodDeclaration( - getReturnType(entry, rpc.getReturnType()), rpc.getName(), fields); + getReturnType(rpc.getReturnType()), rpc.getName(), fields); methods.add(operation); } @@ -150,28 +151,35 @@ public class TemplateFactory { return result; } - private static String getReturnType(RuntimeBeanEntry entry, AttributeIfc attributeIfc) { + // FIXME: put into Type.toString + static String serializeType(Type type) { + if (type instanceof ParameterizedType){ + ParameterizedType parameterizedType = (ParameterizedType) type; + StringBuffer sb = new StringBuffer(); + sb.append(parameterizedType.getRawType().getFullyQualifiedName()); + sb.append("<"); + boolean first = true; + for(Type parameter: parameterizedType.getActualTypeArguments()) { + if (first) { + first = false; + } else { + sb.append(","); + } + sb.append(serializeType(parameter)); + } + sb.append(">"); + return sb.toString(); + } else { + return type.getFullyQualifiedName(); + } + } + + + private static String getReturnType(AttributeIfc attributeIfc) { String returnType; if (attributeIfc instanceof TypedAttribute) { - returnType = ((TypedAttribute) attributeIfc).getType() - .getFullyQualifiedName(); - } else if (attributeIfc instanceof TOAttribute) { - String fullyQualifiedName = FullyQualifiedNameHelper - .getFullyQualifiedName(entry.getPackageName(), - attributeIfc.getUpperCaseCammelCase()); - - returnType = fullyQualifiedName; - } else if (attributeIfc instanceof ListAttribute) { - AttributeIfc innerAttr = ((ListAttribute) attributeIfc) - .getInnerAttribute(); - - String innerTpe = innerAttr instanceof TypedAttribute ? ((TypedAttribute) innerAttr) - .getType().getFullyQualifiedName() - : FullyQualifiedNameHelper.getFullyQualifiedName( - entry.getPackageName(), - attributeIfc.getUpperCaseCammelCase()); - - returnType = "java.util.List<" + innerTpe + ">"; + Type type = ((TypedAttribute) attributeIfc).getType(); + returnType = serializeType(type); } else if (attributeIfc == VoidAttribute.getInstance()) { return "void"; } else { @@ -292,8 +300,7 @@ public class TemplateFactory { public static GeneralInterfaceTemplate mXBeanInterfaceTemplateFromMbe( ModuleMXBeanEntry mbe) { MXBeanInterfaceAttributesProcessor attrProcessor = new MXBeanInterfaceAttributesProcessor(); - attrProcessor.processAttributes(mbe.getAttributes(), - mbe.getPackageName()); + attrProcessor.processAttributes(mbe.getAttributes()); GeneralInterfaceTemplate ifcTemplate = new GeneralInterfaceTemplate( getHeaderFromEntry(mbe), mbe.getPackageName(), mbe.getMXBeanInterfaceName(), Lists. newArrayList(), @@ -306,7 +313,7 @@ public class TemplateFactory { ModuleMXBeanEntry mbe) { Map retVal = Maps.newHashMap(); TOAttributesProcessor processor = new TOAttributesProcessor(); - processor.processAttributes(mbe.getAttributes(), mbe.getPackageName()); + processor.processAttributes(mbe.getAttributes()); for (org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory.TOAttributesProcessor.TOInternal to : processor .getTOs()) { List constructors = Lists.newArrayList(); @@ -345,7 +352,7 @@ public class TemplateFactory { yangPropertiesToTypesMap.put(returnType.getAttributeYangName(), returnType); } - processor.processAttributes(yangPropertiesToTypesMap, rbe.getPackageName()); + processor.processAttributes(yangPropertiesToTypesMap); for (org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.TemplateFactory.TOAttributesProcessor.TOInternal to : processor .getTOs()) { List constructors = Lists.newArrayList(); @@ -372,36 +379,29 @@ public class TemplateFactory { private final List tos = Lists.newArrayList(); - void processAttributes(Map attributes, - String packageName) { + void processAttributes(Map attributes) { for (Entry attrEntry : attributes.entrySet()) { AttributeIfc attributeIfc = attrEntry.getValue(); if (attributeIfc instanceof TOAttribute) { - createTOInternal(packageName, attributeIfc); + createTOInternal((TOAttribute) attributeIfc); } if (attributeIfc instanceof ListAttribute) { AttributeIfc innerAttr = ((ListAttribute) attributeIfc) .getInnerAttribute(); if (innerAttr instanceof TOAttribute) { - createTOInternal(packageName, innerAttr); + createTOInternal((TOAttribute) innerAttr); } } } } - private void createTOInternal(String packageName, - AttributeIfc attributeIfc) { - String fullyQualifiedName = FullyQualifiedNameHelper - .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase()); + private void createTOInternal(TOAttribute toAttribute) { - String type = fullyQualifiedName; - String name = attributeIfc.getUpperCaseCammelCase(); - Map attrs = ((TOAttribute) attributeIfc) - .getCapitalizedPropertiesToTypesMap(); - // recursive processing - processAttributes(attrs, packageName); + Map attrs = toAttribute.getCapitalizedPropertiesToTypesMap(); + // recursive processing of TO's attributes + processAttributes(attrs); - tos.add(new TOInternal(type, name, attrs, packageName)); + tos.add(new TOInternal(toAttribute.getType(), attrs)); } List getTOs() { @@ -409,20 +409,22 @@ public class TemplateFactory { } private static class TOInternal { - private final String type, name; + private final String fullyQualifiedName, name; private List fields; private List methods; - public TOInternal(String type, String name, + public TOInternal(Type type, Map attrs) { + this(type.getFullyQualifiedName(), type.getName(), attrs, type.getPackageName()); + } + + public TOInternal(String fullyQualifiedName, String name, Map attrs, String packageName) { - super(); - this.type = type; + this.fullyQualifiedName = fullyQualifiedName; this.name = name; processAttrs(attrs, packageName); } - private void processAttrs(Map attrs, - String packageName) { + private void processAttrs(Map attrs, String packageName) { fields = Lists.newArrayList(); methods = Lists.newArrayList(); @@ -431,25 +433,14 @@ public class TemplateFactory { String varName = BindingGeneratorUtil .parseToValidParamName(attrEntry.getKey()); - String fullyQualifiedName = null; + String fullyQualifiedName; if (attrEntry.getValue() instanceof TypedAttribute) { - Type innerType = ((TypedAttribute) attrEntry.getValue()) - .getType(); - fullyQualifiedName = innerType.getFullyQualifiedName(); - } else if (attrEntry.getValue() instanceof ListAttribute) { - AttributeIfc innerAttr = ((ListAttribute) attrEntry - .getValue()).getInnerAttribute(); - - String innerTpe = innerAttr instanceof TypedAttribute ? ((TypedAttribute) innerAttr) - .getType().getFullyQualifiedName() - : FullyQualifiedNameHelper - .getFullyQualifiedName(packageName, attrEntry.getValue().getUpperCaseCammelCase()); - - fullyQualifiedName = "java.util.List<" + innerTpe + ">"; - } else + Type type = ((TypedAttribute) attrEntry.getValue()).getType(); + fullyQualifiedName = serializeType(type); + } else { fullyQualifiedName = FullyQualifiedNameHelper .getFullyQualifiedName(packageName, attrEntry.getValue().getUpperCaseCammelCase()); - + } fields.add(new Field(fullyQualifiedName, varName)); String getterName = "get" + innerName; @@ -470,7 +461,7 @@ public class TemplateFactory { } String getType() { - return type; + return fullyQualifiedName; } String getName() { @@ -488,38 +479,16 @@ public class TemplateFactory { } private static class MXBeanInterfaceAttributesProcessor { - private static final String STRING_FULLY_QUALIFIED_NAME = "java.util.List"; private final List methods = Lists.newArrayList(); - void processAttributes(Map attributes, - String packageName) { + void processAttributes(Map attributes) { for (Entry attrEntry : attributes.entrySet()) { String returnType; AttributeIfc attributeIfc = attrEntry.getValue(); if (attributeIfc instanceof TypedAttribute) { - returnType = ((TypedAttribute) attributeIfc).getType() - .getFullyQualifiedName(); - } else if (attributeIfc instanceof TOAttribute) { - String fullyQualifiedName = FullyQualifiedNameHelper - .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase()); - - returnType = fullyQualifiedName; - } else if (attributeIfc instanceof ListAttribute) { - String fullyQualifiedName = null; - - AttributeIfc innerAttr = ((ListAttribute) attributeIfc) - .getInnerAttribute(); - if (innerAttr instanceof JavaAttribute) { - fullyQualifiedName = ((JavaAttribute) innerAttr) - .getType().getFullyQualifiedName(); - } else if (innerAttr instanceof TOAttribute) { - fullyQualifiedName = FullyQualifiedNameHelper - .getFullyQualifiedName(packageName, innerAttr.getUpperCaseCammelCase()); - } - - returnType = STRING_FULLY_QUALIFIED_NAME.concat("<") - .concat(fullyQualifiedName).concat(">"); + TypedAttribute typedAttribute = (TypedAttribute) attributeIfc; + returnType = serializeType(typedAttribute.getType()); } else { throw new UnsupportedOperationException( "Attribute not supported: " @@ -565,14 +534,14 @@ public class TemplateFactory { AttributeIfc attributeIfc = attrEntry.getValue(); if (attributeIfc instanceof TypedAttribute) { - type = ((TypedAttribute) attributeIfc).getType() - .getFullyQualifiedName(); + TypedAttribute typedAttribute = (TypedAttribute) attributeIfc; + type = serializeType(typedAttribute.getType()); } else if (attributeIfc instanceof TOAttribute) { String fullyQualifiedName = FullyQualifiedNameHelper .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase()); type = fullyQualifiedName; - } else if (attributeIfc instanceof ListAttribute) { + } else if (attributeIfc instanceof ListAttribute) { //FIXME: listAttribute might extend TypedAttribute String fullyQualifiedName = null; AttributeIfc innerAttr = ((ListAttribute) attributeIfc) .getInnerAttribute(); @@ -617,8 +586,8 @@ public class TemplateFactory { AttributeIfc attributeIfc = attrEntry.getValue(); if (attributeIfc instanceof TypedAttribute) { - type = ((TypedAttribute) attributeIfc).getType() - .getFullyQualifiedName(); + TypedAttribute typedAttribute = (TypedAttribute) attributeIfc; + type = serializeType(typedAttribute.getType()); } else if (attributeIfc instanceof TOAttribute) { String fullyQualifiedName = FullyQualifiedNameHelper .getFullyQualifiedName(packageName, attributeIfc.getUpperCaseCammelCase()); @@ -651,9 +620,9 @@ public class TemplateFactory { List annotations = Lists .newArrayList(overrideAnnotation); - if (attributeIfc instanceof DependencyAttribute) { + if (attributeIfc instanceof AbstractDependencyAttribute) { isDependency = true; - dependency = ((DependencyAttribute) attributeIfc) + dependency = ((AbstractDependencyAttribute) attributeIfc) .getDependency(); annotations.add(Annotation .createRequireIfcAnnotation(dependency.getSie())); diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java index 293696d10e..5624e169da 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/ftl/model/ModuleField.java @@ -7,11 +7,13 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.plugin.ftl.model; + +import org.opendaylight.controller.config.yangjmxgenerator.attribute.Dependency; + +import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute.Dependency; - public class ModuleField extends Field { private final String nullableDefault, attributeName; @@ -22,10 +24,14 @@ public class ModuleField extends Field { String attributeName, String nullableDefault, boolean isDependency, Dependency dependency) { super(modifiers, type, name); - this.nullableDefault = nullableDefault; this.dependent = isDependency; this.dependency = dependency; this.attributeName = attributeName; + if (type.startsWith(List.class.getName()) && nullableDefault == null) { + String generics = type.substring(List.class.getName().length()); + nullableDefault = "new " + ArrayList.class.getName() + generics + "()"; + } + this.nullableDefault = nullableDefault; } public ModuleField(String type, String name, String attributeName, @@ -49,4 +55,5 @@ public class ModuleField extends Field { public String getAttributeName() { return attributeName; } + } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl index d0646f467a..f7197d1582 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl +++ b/opendaylight/config/yang-jmx-generator-plugin/src/main/resources/freeMarker/module_abs_template_new.ftl @@ -52,8 +52,14 @@ package ${packageName}; public void validate(){ <#list moduleFields as field> <#if field.dependent==true && field.dependency.mandatory==true> + <#if field.type?starts_with("java.util.List")> + for(javax.management.ObjectName dep : ${field.name}) { + dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, dep, ${field.name}JmxAttribute); + } + <#else> dependencyResolver.validateDependency(${field.dependency.sie.fullyQualifiedName}.class, ${field.name}, ${field.name}JmxAttribute); + customValidation(); } @@ -65,10 +71,17 @@ package ${packageName}; // 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; } + @@ -79,12 +92,18 @@ package ${packageName}; <#list moduleFields as field> <#if field.dependent==true> - <#if field.dependency.mandatory==false> if(${field.name}!=null) { - ${field.name}Dependency = dependencyResolver.resolveInstance(${field.dependency.sie.exportedOsgiClassName}.class, ${field.name}, ${field.name}JmxAttribute); + <#if field.type?starts_with("java.util.List")> + ${field.name}Dependency = new java.util.ArrayList<${field.dependency.sie.exportedOsgiClassName}>(); + for(javax.management.ObjectName dep : ${field.name}) { + ${field.name}Dependency.add(dependencyResolver.resolveInstance(${field.dependency.sie.exportedOsgiClassName}.class, dep, ${field.name}JmxAttribute)); + } + <#else> + ${field.name}Dependency = dependencyResolver.resolveInstance(${field.dependency.sie.exportedOsgiClassName}.class, ${field.name}, ${field.name}JmxAttribute); + <#if field.dependency.mandatory==false> } diff --git a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java index 0d6ec3cccb..2f1437404a 100644 --- a/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java +++ b/opendaylight/config/yang-jmx-generator-plugin/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/plugin/JMXGeneratorTest.java @@ -75,6 +75,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +//TODO: refactor public class JMXGeneratorTest extends AbstractGeneratorTest { JMXGenerator jmxGenerator; @@ -84,19 +85,7 @@ public class JMXGeneratorTest extends AbstractGeneratorTest { File generatedResourcesDir; private static final List expectedModuleFileNames = ServiceInterfaceEntryTest - .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, " + - "AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, " + - "AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, " + - "AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, " + - "AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, " + - "AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, " + - "AsyncEventBusRuntimeRegistrator.java, DynamicThreadPoolModule.java, " + - "DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, " + - "DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, " + - "DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, " + - "EventBusModuleMXBean.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, " + - "InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, " + - "NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, Peer.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]"); + .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, AbstractThreadPoolRegistryImplModule.java, AbstractThreadPoolRegistryImplModuleFactory.java, AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, AsyncEventBusRuntimeRegistrator.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, Peer.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, ThreadPoolRegistryImplModule.java, ThreadPoolRegistryImplModuleFactory.java, ThreadPoolRegistryImplModuleMXBean.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]"); private static final List expectedBGPNames = ServiceInterfaceEntryTest .toFileNames("[AbstractBgpListenerImplModule.java, " + "AbstractBgpListenerImplModuleFactory.java, " + @@ -119,38 +108,7 @@ public class JMXGeneratorTest extends AbstractGeneratorTest { "NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, " + "NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java]"); private static final List expectedAllFileNames = ServiceInterfaceEntryTest - .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, " + - "AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, " + - "AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, " + - "AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, " + - "AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, " + - "AbstractNetconfTestFileImplModule.java, AbstractNetconfTestFileImplModuleFactory.java, " + - "AbstractNetconfTestFiles1ImplModule.java, AbstractNetconfTestFiles1ImplModuleFactory.java, " + - "AbstractNetconfTestImplModule.java, AbstractNetconfTestImplModuleFactory.java, " + - "AbstractTestFileImplModule.java, AbstractTestFileImplModuleFactory.java, " + - "AbstractTestFiles1ImplModule.java, AbstractTestFiles1ImplModuleFactory.java, " + - "AbstractTestImplModule.java, AbstractTestImplModuleFactory.java, AsyncEventBusModule.java, " + - "AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, " + - "AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, " + - "AsyncEventBusRuntimeRegistrator.java, AutoCloseableServiceInterface.java, " + - "BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java," + - " BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, " + - "BgpListenerImplRuntimeRegistrator.java, ComplexDtoBInner.java, ComplexList.java, Deep.java, " + - "DtoA.java, DtoA.java, DtoA.java, DtoA1.java, DtoAInner.java, DtoAInnerInner.java, DtoB.java, " + - "DtoC.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, " + - "DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, " + - "DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, " + - "EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, " + - "EventBusServiceInterface.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, " + - "InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, " + - "NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, " + - "NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, " + - "NetconfTestFileImplModule.java, NetconfTestFileImplModuleFactory.java, " + - "NetconfTestFileImplModuleMXBean.java, NetconfTestFileImplRuntimeMXBean.java, " + - "NetconfTestFileImplRuntimeRegistration.java, NetconfTestFileImplRuntimeRegistrator.java, " + - "NetconfTestFiles1ImplModule.java, NetconfTestFiles1ImplModuleFactory.java, " + - "NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, " + - "NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, NetconfTestImplModule.java, NetconfTestImplModuleFactory.java, NetconfTestImplModuleMXBean.java, NetconfTestImplRuntimeMXBean.java, NetconfTestImplRuntimeRegistration.java, NetconfTestImplRuntimeRegistrator.java, Peer.java, Peer.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java, ScheduledThreadPoolServiceInterface.java, SimpleList.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java, TestImplModule.java, TestImplModuleFactory.java, TestImplModuleMXBean.java, TestImplRuntimeMXBean.java, TestImplRuntimeRegistration.java, TestImplRuntimeRegistrator.java, ThreadFactoryServiceInterface.java, ThreadPoolServiceInterface.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]"); + .toFileNames("[AbstractAsyncEventBusModule.java, AbstractAsyncEventBusModuleFactory.java, AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, AbstractDynamicThreadPoolModule.java, AbstractDynamicThreadPoolModuleFactory.java, AbstractEventBusModule.java, AbstractEventBusModuleFactory.java, AbstractNamingThreadFactoryModule.java, AbstractNamingThreadFactoryModuleFactory.java, AbstractNetconfTestFileImplModule.java, AbstractNetconfTestFileImplModuleFactory.java, AbstractNetconfTestFiles1ImplModule.java, AbstractNetconfTestFiles1ImplModuleFactory.java, AbstractNetconfTestImplModule.java, AbstractNetconfTestImplModuleFactory.java, AbstractTestFileImplModule.java, AbstractTestFileImplModuleFactory.java, AbstractTestFiles1ImplModule.java, AbstractTestFiles1ImplModuleFactory.java, AbstractTestImplModule.java, AbstractTestImplModuleFactory.java, AbstractThreadPoolRegistryImplModule.java, AbstractThreadPoolRegistryImplModuleFactory.java, AsyncEventBusModule.java, AsyncEventBusModuleFactory.java, AsyncEventBusModuleMXBean.java, AsyncEventBusRuntimeMXBean.java, AsyncEventBusRuntimeRegistration.java, AsyncEventBusRuntimeRegistrator.java, AutoCloseableServiceInterface.java, BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java, BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, BgpListenerImplRuntimeRegistrator.java, ComplexDtoBInner.java, ComplexList.java, Deep.java, DtoA.java, DtoA.java, DtoA.java, DtoA1.java, DtoAInner.java, DtoAInnerInner.java, DtoB.java, DtoC.java, DynamicThreadPoolModule.java, DynamicThreadPoolModuleFactory.java, DynamicThreadPoolModuleMXBean.java, DynamicThreadPoolRuntimeMXBean.java, DynamicThreadPoolRuntimeRegistration.java, DynamicThreadPoolRuntimeRegistrator.java, EventBusModule.java, EventBusModuleFactory.java, EventBusModuleMXBean.java, EventBusServiceInterface.java, EventRuntimeMXBean.java, EventRuntimeRegistration.java, InnerStreamList.java, NamingThreadFactoryModule.java, NamingThreadFactoryModuleFactory.java, NamingThreadFactoryModuleMXBean.java, NamingThreadFactoryRuntimeMXBean.java, NamingThreadFactoryRuntimeRegistration.java, NamingThreadFactoryRuntimeRegistrator.java, NetconfTestFileImplModule.java, NetconfTestFileImplModuleFactory.java, NetconfTestFileImplModuleMXBean.java, NetconfTestFileImplRuntimeMXBean.java, NetconfTestFileImplRuntimeRegistration.java, NetconfTestFileImplRuntimeRegistrator.java, NetconfTestFiles1ImplModule.java, NetconfTestFiles1ImplModuleFactory.java, NetconfTestFiles1ImplModuleMXBean.java, NetconfTestFiles1ImplRuntimeMXBean.java, NetconfTestFiles1ImplRuntimeRegistration.java, NetconfTestFiles1ImplRuntimeRegistrator.java, NetconfTestImplModule.java, NetconfTestImplModuleFactory.java, NetconfTestImplModuleMXBean.java, NetconfTestImplRuntimeMXBean.java, NetconfTestImplRuntimeRegistration.java, NetconfTestImplRuntimeRegistrator.java, Peer.java, Peer.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java, ScheduledThreadPoolServiceInterface.java, SimpleList.java, StreamRuntimeMXBean.java, StreamRuntimeRegistration.java, TestFileImplModule.java, TestFileImplModuleFactory.java, TestFileImplModuleMXBean.java, TestFileImplRuntimeMXBean.java, TestFileImplRuntimeRegistration.java, TestFileImplRuntimeRegistrator.java, TestFiles1ImplModule.java, TestFiles1ImplModuleFactory.java, TestFiles1ImplModuleMXBean.java, TestFiles1ImplRuntimeMXBean.java, TestFiles1ImplRuntimeRegistration.java, TestFiles1ImplRuntimeRegistrator.java, TestImplModule.java, TestImplModuleFactory.java, TestImplModuleMXBean.java, TestImplRuntimeMXBean.java, TestImplRuntimeRegistration.java, TestImplRuntimeRegistrator.java, ThreadFactoryServiceInterface.java, ThreadPoolRegistryImplModule.java, ThreadPoolRegistryImplModuleFactory.java, ThreadPoolRegistryImplModuleMXBean.java, ThreadPoolServiceInterface.java, ThreadRuntimeMXBean.java, ThreadRuntimeRegistration.java, ThreadStreamRuntimeMXBean.java, ThreadStreamRuntimeRegistration.java]"); private static final List expectedGenerateMBEsListNames = ServiceInterfaceEntryTest .toFileNames("[AbstractBgpListenerImplModule.java, AbstractBgpListenerImplModuleFactory.java, BgpListenerImplModule.java, BgpListenerImplModuleFactory.java, BgpListenerImplModuleMXBean.java, BgpListenerImplRuntimeMXBean.java, BgpListenerImplRuntimeRegistration.java, BgpListenerImplRuntimeRegistrator.java, PeersRuntimeMXBean.java, PeersRuntimeRegistration.java]"); @@ -381,7 +339,11 @@ public class JMXGeneratorTest extends AbstractGeneratorTest { PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX + ".threads.java.DynamicThreadPoolModuleFactory",// PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX - + ".threads.java.NamingThreadFactoryModuleFactory"); + + ".threads.java.NamingThreadFactoryModuleFactory", // + PackageTranslatorTest.EXPECTED_PACKAGE_PREFIX + + ".threads.java.ThreadPoolRegistryImplModuleFactory"); + + assertThat(lines, equalTo(expectedLines)); } diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java index 70a4edde41..a7110b874c 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java @@ -8,11 +8,14 @@ package org.opendaylight.controller.config.yangjmxgenerator; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Optional; import com.google.common.collect.Sets; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.NameConflictException; @@ -21,6 +24,7 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; @@ -338,7 +342,7 @@ public class ModuleMXBeanEntry extends AbstractEntry { moduleLocalNameFromXPath); yangToAttributes = fillConfiguration(choiceCaseNode, currentModule, typeProviderWrapper, - qNamesToSIEs, schemaContext); + qNamesToSIEs, schemaContext, packageName); checkUniqueAttributesWithGeneratedClass( uniqueGeneratedClassesNames, when.getQName(), yangToAttributes); @@ -484,12 +488,12 @@ public class ModuleMXBeanEntry extends AbstractEntry { ChoiceCaseNode choiceCaseNode, Module currentModule, TypeProviderWrapper typeProviderWrapper, Map qNamesToSIEs, - SchemaContext schemaContext) { + SchemaContext schemaContext, String packageName) { Map yangToAttributes = new HashMap<>(); for (DataSchemaNode attrNode : choiceCaseNode.getChildNodes()) { AttributeIfc attributeValue = getAttributeValue(attrNode, currentModule, qNamesToSIEs, typeProviderWrapper, - schemaContext); + schemaContext, packageName); yangToAttributes.put(attributeValue.getAttributeYangName(), attributeValue); } @@ -549,11 +553,12 @@ public class ModuleMXBeanEntry extends AbstractEntry { } } - private static int getChildNodeSizeWithoutUses(ContainerSchemaNode csn) { + private static int getChildNodeSizeWithoutUses(DataNodeContainer csn) { int result = 0; for (DataSchemaNode dsn : csn.getChildNodes()) { - if (dsn.isAddedByUses() == false) + if (dsn.isAddedByUses() == false) { result++; + } } return result; } @@ -561,7 +566,7 @@ public class ModuleMXBeanEntry extends AbstractEntry { private static AttributeIfc getAttributeValue(DataSchemaNode attrNode, Module currentModule, Map qNamesToSIEs, - TypeProviderWrapper typeProviderWrapper, SchemaContext schemaContext) { + TypeProviderWrapper typeProviderWrapper, SchemaContext schemaContext, String packageName) { if (attrNode instanceof LeafSchemaNode) { // simple type @@ -570,49 +575,75 @@ public class ModuleMXBeanEntry extends AbstractEntry { } else if (attrNode instanceof ContainerSchemaNode) { // reference or TO ContainerSchemaNode containerSchemaNode = (ContainerSchemaNode) attrNode; - if (containerSchemaNode.getUses().size() == 1 - && getChildNodeSizeWithoutUses(containerSchemaNode) == 0) { - // reference - UsesNode usesNode = containerSchemaNode.getUses().iterator() - .next(); - checkState(usesNode.getRefines().size() == 1, - "Unexpected 'refine' child node size of " - + containerSchemaNode); - LeafSchemaNode refine = (LeafSchemaNode) usesNode.getRefines() - .values().iterator().next(); - checkState(refine.getUnknownSchemaNodes().size() == 1, - "Unexpected unknown schema node size of " + refine); - UnknownSchemaNode requiredIdentity = refine - .getUnknownSchemaNodes().iterator().next(); - checkState( - ConfigConstants.REQUIRED_IDENTITY_EXTENSION_QNAME.equals(requiredIdentity - .getNodeType()), - "Unexpected language extension " + requiredIdentity); - String prefixAndIdentityLocalName = requiredIdentity - .getNodeParameter(); - // import should point to a module - ServiceInterfaceEntry serviceInterfaceEntry = findSIE( - prefixAndIdentityLocalName, currentModule, - qNamesToSIEs, schemaContext); - boolean mandatory = refine.getConstraints().isMandatory(); - return new DependencyAttribute(attrNode, serviceInterfaceEntry, - mandatory, attrNode.getDescription()); + Optional dependencyAttributeOptional = extractDependency(containerSchemaNode, + attrNode, currentModule, qNamesToSIEs, schemaContext); + if (dependencyAttributeOptional.isPresent()) { + return dependencyAttributeOptional.get(); } else { - return TOAttribute.create(containerSchemaNode, - typeProviderWrapper); + return TOAttribute.create(containerSchemaNode, typeProviderWrapper, packageName); } + } else if (attrNode instanceof LeafListSchemaNode) { return ListAttribute.create((LeafListSchemaNode) attrNode, typeProviderWrapper); } else if (attrNode instanceof ListSchemaNode) { - return ListAttribute.create((ListSchemaNode) attrNode, - typeProviderWrapper); + ListSchemaNode listSchemaNode = (ListSchemaNode) attrNode; + Optional dependencyAttributeOptional = extractDependency(listSchemaNode, + attrNode, currentModule, qNamesToSIEs, schemaContext); + if (dependencyAttributeOptional.isPresent()) { + return dependencyAttributeOptional.get(); + } else { + return ListAttribute.create(listSchemaNode, typeProviderWrapper, packageName); + } } else { throw new UnsupportedOperationException( "Unknown configuration node " + attrNode.toString()); } } + private static Optional extractDependency(DataNodeContainer dataNodeContainer, + DataSchemaNode attrNode, + Module currentModule, + Map qNamesToSIEs, + SchemaContext schemaContext) { + if (dataNodeContainer.getUses().size() == 1 + && getChildNodeSizeWithoutUses(dataNodeContainer) == 0) { + // reference + UsesNode usesNode = dataNodeContainer.getUses().iterator() + .next(); + checkState(usesNode.getRefines().size() == 1, + "Unexpected 'refine' child node size of " + + dataNodeContainer); + LeafSchemaNode refine = (LeafSchemaNode) usesNode.getRefines() + .values().iterator().next(); + checkState(refine.getUnknownSchemaNodes().size() == 1, + "Unexpected unknown schema node size of " + refine); + UnknownSchemaNode requiredIdentity = refine + .getUnknownSchemaNodes().iterator().next(); + checkState( + ConfigConstants.REQUIRED_IDENTITY_EXTENSION_QNAME.equals(requiredIdentity + .getNodeType()), + "Unexpected language extension " + requiredIdentity); + String prefixAndIdentityLocalName = requiredIdentity + .getNodeParameter(); + // import should point to a module + ServiceInterfaceEntry serviceInterfaceEntry = findSIE( + prefixAndIdentityLocalName, currentModule, + qNamesToSIEs, schemaContext); + boolean mandatory = refine.getConstraints().isMandatory(); + AbstractDependencyAttribute reference; + if (dataNodeContainer instanceof ContainerSchemaNode ){ + reference = new DependencyAttribute(attrNode, serviceInterfaceEntry, + mandatory, attrNode.getDescription()); + } else { + reference = new ListDependenciesAttribute(attrNode, serviceInterfaceEntry, + mandatory, attrNode.getDescription()); + } + return Optional.of(reference); + } + return Optional.absent(); + } + private static ServiceInterfaceEntry findSIE( String prefixAndIdentityLocalName, Module currentModule, Map qNamesToSIEs, diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java index 9b82f123ca..f19a46d0f4 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeBeanEntry.java @@ -67,7 +67,7 @@ public class RuntimeBeanEntry { private final Set rpcs; @VisibleForTesting - public RuntimeBeanEntry(String packageName, + RuntimeBeanEntry(String packageName, DataSchemaNode nodeForReporting, String yangName, String javaNamePrefix, boolean isRoot, Optional keyYangName, List attributes, @@ -228,7 +228,7 @@ public class RuntimeBeanEntry { ContainerSchemaNode container = (ContainerSchemaNode) child; // this can be either TO or hierarchical RB TOAttribute toAttribute = TOAttribute.create(container, - typeProviderWrapper); + typeProviderWrapper, packageName); attributes.add(toAttribute); } else if (child instanceof ListSchemaNode) { if (isInnerStateBean(child)) { @@ -239,7 +239,7 @@ public class RuntimeBeanEntry { runtimeBeanEntries.add(hierarchicalChild); } else /* ordinary list attribute */{ ListAttribute listAttribute = ListAttribute.create( - (ListSchemaNode) child, typeProviderWrapper); + (ListSchemaNode) child, typeProviderWrapper, packageName); attributes.add(listAttribute); } @@ -280,7 +280,7 @@ public class RuntimeBeanEntry { } else if (rpcDefinition.getOutput().getChildNodes().size() == 1) { DataSchemaNode returnDSN = rpcDefinition.getOutput() .getChildNodes().iterator().next(); - returnType = getReturnTypeAttribute(returnDSN, typeProviderWrapper); + returnType = getReturnTypeAttribute(returnDSN, typeProviderWrapper, packageName); } else { throw new IllegalArgumentException( @@ -311,16 +311,17 @@ public class RuntimeBeanEntry { attributes, rpcs); } - private static AttributeIfc getReturnTypeAttribute(DataSchemaNode child, TypeProviderWrapper typeProviderWrapper) { + private static AttributeIfc getReturnTypeAttribute(DataSchemaNode child, TypeProviderWrapper typeProviderWrapper, + String packageName) { if (child instanceof LeafSchemaNode) { LeafSchemaNode leaf = (LeafSchemaNode) child; return new JavaAttribute(leaf, typeProviderWrapper); } else if (child instanceof ContainerSchemaNode) { ContainerSchemaNode container = (ContainerSchemaNode) child; - TOAttribute toAttribute = TOAttribute.create(container, typeProviderWrapper); + TOAttribute toAttribute = TOAttribute.create(container, typeProviderWrapper, packageName); return toAttribute; } else if (child instanceof ListSchemaNode) { - return ListAttribute.create((ListSchemaNode) child, typeProviderWrapper); + return ListAttribute.create((ListSchemaNode) child, typeProviderWrapper, packageName); } else if (child instanceof LeafListSchemaNode) { return ListAttribute.create((LeafListSchemaNode) child, typeProviderWrapper); } else { diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/AbstractDependencyAttribute.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/AbstractDependencyAttribute.java new file mode 100644 index 0000000000..eb1c9e41a6 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/AbstractDependencyAttribute.java @@ -0,0 +1,86 @@ +/* + * 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.attribute; + +import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; + +public abstract class AbstractDependencyAttribute extends AbstractAttribute implements TypedAttribute { + + protected final Dependency dependency; + protected final String nullableDescription, nullableDefault; + + public AbstractDependencyAttribute(DataSchemaNode attrNode, + ServiceInterfaceEntry sie, boolean mandatory, + String nullableDescription) { + super(attrNode); + dependency = new Dependency(sie, mandatory); + this.nullableDescription = nullableDescription; + nullableDefault = null; + } + + public Dependency getDependency() { + return dependency; + } + + @Override + public String getNullableDescription() { + return nullableDescription; + } + + @Override + public String getNullableDefault() { + return nullableDefault; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + if (!super.equals(o)) + return false; + + AbstractDependencyAttribute that = (AbstractDependencyAttribute) o; + + if (dependency != null ? !dependency.equals(that.dependency) + : that.dependency != null) + return false; + if (nullableDefault != null ? !nullableDefault + .equals(that.nullableDefault) : that.nullableDefault != null) + return false; + if (nullableDescription != null ? !nullableDescription + .equals(that.nullableDescription) + : that.nullableDescription != null) + return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (dependency != null ? dependency.hashCode() : 0); + result = 31 + * result + + (nullableDescription != null ? nullableDescription.hashCode() + : 0); + result = 31 * result + + (nullableDefault != null ? nullableDefault.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return getClass().getName() + "{" + getAttributeYangName() + "," + + "dependency=" + dependency + '}'; + } + + +} diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java new file mode 100644 index 0000000000..38de6e1528 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/Dependency.java @@ -0,0 +1,45 @@ +package org.opendaylight.controller.config.yangjmxgenerator.attribute; + +import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry; + +public class Dependency { + private final ServiceInterfaceEntry sie; + private final boolean mandatory; + + public Dependency(ServiceInterfaceEntry sie, boolean mandatory) { + this.sie = sie; + this.mandatory = mandatory; + } + + public ServiceInterfaceEntry getSie() { + return sie; + } + + public boolean isMandatory() { + return mandatory; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + Dependency that = (Dependency) o; + + if (mandatory != that.mandatory) + return false; + if (!sie.equals(that.sie)) + return false; + + return true; + } + + @Override + public int hashCode() { + int result = sie.hashCode(); + result = 31 * result + (mandatory ? 1 : 0); + return result; + } + } diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/DependencyAttribute.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/DependencyAttribute.java index 1912b75e0e..d8df78af0a 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/DependencyAttribute.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/DependencyAttribute.java @@ -15,19 +15,13 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import javax.management.ObjectName; import javax.management.openmbean.SimpleType; -public class DependencyAttribute extends AbstractAttribute implements - TypedAttribute { +public class DependencyAttribute extends AbstractDependencyAttribute { - private final Dependency dependency; - private final String nullableDescription, nullableDefault; public DependencyAttribute(DataSchemaNode attrNode, ServiceInterfaceEntry sie, boolean mandatory, String nullableDescription) { - super(attrNode); - dependency = new Dependency(sie, mandatory); - this.nullableDescription = nullableDescription; - nullableDefault = null; + super(attrNode, sie, mandatory, nullableDescription); } @Override @@ -35,109 +29,9 @@ public class DependencyAttribute extends AbstractAttribute implements return Types.typeForClass(ObjectName.class); } - public Dependency getDependency() { - return dependency; - } - - @Override - public String getNullableDescription() { - return nullableDescription; - } - - @Override - public String getNullableDefault() { - return nullableDefault; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - if (!super.equals(o)) - return false; - - DependencyAttribute that = (DependencyAttribute) o; - - if (dependency != null ? !dependency.equals(that.dependency) - : that.dependency != null) - return false; - if (nullableDefault != null ? !nullableDefault - .equals(that.nullableDefault) : that.nullableDefault != null) - return false; - if (nullableDescription != null ? !nullableDescription - .equals(that.nullableDescription) - : that.nullableDescription != null) - return false; - - return true; - } - - @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + (dependency != null ? dependency.hashCode() : 0); - result = 31 - * result - + (nullableDescription != null ? nullableDescription.hashCode() - : 0); - result = 31 * result - + (nullableDefault != null ? nullableDefault.hashCode() : 0); - return result; - } - - @Override - public String toString() { - return "DependencyAttribute{" + getAttributeYangName() + "," - + "dependency=" + dependency + '}'; - } - @Override public SimpleType getOpenType() { return SimpleType.OBJECTNAME; } - public static class Dependency { - private final ServiceInterfaceEntry sie; - private final boolean mandatory; - - public Dependency(ServiceInterfaceEntry sie, boolean mandatory) { - this.sie = sie; - this.mandatory = mandatory; - } - - public ServiceInterfaceEntry getSie() { - return sie; - } - - public boolean isMandatory() { - return mandatory; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - Dependency that = (Dependency) o; - - if (mandatory != that.mandatory) - return false; - if (!sie.equals(that.sie)) - return false; - - return true; - } - - @Override - public int hashCode() { - int result = sie.hashCode(); - result = 31 * result + (mandatory ? 1 : 0); - return result; - } - } - } diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListAttribute.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListAttribute.java index 083b0b53e9..73b557e291 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListAttribute.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListAttribute.java @@ -7,24 +7,27 @@ */ package org.opendaylight.controller.config.yangjmxgenerator.attribute; -import javax.management.openmbean.ArrayType; -import javax.management.openmbean.OpenDataException; -import javax.management.openmbean.OpenType; - import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper; +import org.opendaylight.yangtools.binding.generator.util.Types; +import org.opendaylight.yangtools.sal.binding.model.api.Type; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; -public class ListAttribute extends AbstractAttribute { +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.OpenDataException; +import javax.management.openmbean.OpenType; +import java.util.List; + +public class ListAttribute extends AbstractAttribute implements TypedAttribute { private final String nullableDescription, nullableDefault; - private final AttributeIfc innerAttribute; + private final TypedAttribute innerAttribute; public static ListAttribute create(ListSchemaNode node, - TypeProviderWrapper typeProvider) { + TypeProviderWrapper typeProvider, String packageName) { - AttributeIfc innerAttribute = TOAttribute.create(node, typeProvider); + TOAttribute innerAttribute = TOAttribute.create(node, typeProvider, packageName); return new ListAttribute(node, innerAttribute, node.getDescription()); } @@ -32,12 +35,12 @@ public class ListAttribute extends AbstractAttribute { public static ListAttribute create(LeafListSchemaNode node, TypeProviderWrapper typeProvider) { - AttributeIfc innerAttribute = new JavaAttribute(node, typeProvider); + JavaAttribute innerAttribute = new JavaAttribute(node, typeProvider); return new ListAttribute(node, innerAttribute, node.getDescription()); } - ListAttribute(DataSchemaNode attrNode, AttributeIfc innerAttribute, + ListAttribute(DataSchemaNode attrNode, TypedAttribute innerAttribute, String description) { super(attrNode); this.nullableDescription = description; @@ -99,14 +102,24 @@ public class ListAttribute extends AbstractAttribute { return true; } + + @Override + public Type getType() { + return Types.parameterizedTypeFor(Types.typeForClass(List.class), innerAttribute.getType()); + } + @Override public ArrayType getOpenType() { - OpenType inerOpenType = innerAttribute.getOpenType(); + OpenType innerOpenType = innerAttribute.getOpenType(); + return constructArrayType(innerOpenType); + } + + static ArrayType constructArrayType(OpenType innerOpenType){ try { - return new ArrayType<>(1, inerOpenType); + return new ArrayType<>(1, innerOpenType); } catch (OpenDataException e) { throw new RuntimeException("Unable to create " + ArrayType.class - + " with inner element of type " + inerOpenType, e); + + " with inner element of type " + innerOpenType, e); } } diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListDependenciesAttribute.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListDependenciesAttribute.java new file mode 100644 index 0000000000..641099aef3 --- /dev/null +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/ListDependenciesAttribute.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.config.yangjmxgenerator.attribute; + +import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry; +import org.opendaylight.yangtools.binding.generator.util.Types; +import org.opendaylight.yangtools.sal.binding.model.api.Type; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; + +import javax.management.ObjectName; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; +import java.util.List; + +public class ListDependenciesAttribute extends AbstractDependencyAttribute { + + public ListDependenciesAttribute(DataSchemaNode attrNode, ServiceInterfaceEntry sie, boolean mandatory, String nullableDescription) { + super(attrNode, sie, mandatory, nullableDescription); + } + + @Override + public Type getType() { + return Types.parameterizedTypeFor(Types.typeForClass(List.class), Types.typeForClass(ObjectName.class)); + } + + @Override + public ArrayType getOpenType() { + OpenType innerOpenType = SimpleType.OBJECTNAME; + return ListAttribute.constructArrayType(innerOpenType); + } + +} diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/TOAttribute.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/TOAttribute.java index 96656338df..6a540b50b2 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/TOAttribute.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/attribute/TOAttribute.java @@ -13,6 +13,8 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.TypeProviderWrapper; +import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl; +import org.opendaylight.yangtools.sal.binding.model.api.Type; import org.opendaylight.yangtools.yang.model.api.AugmentationTarget; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; @@ -29,11 +31,12 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -public class TOAttribute extends AbstractAttribute { +public class TOAttribute extends AbstractAttribute implements TypedAttribute { private final String nullableDescription, nullableDefault; private final Map yangNameToAttributeMap; private final Map attributeNameMap; + private final String packageName; private static final Set> ALLOWED_CHILDREN = Sets .newHashSet(); @@ -45,7 +48,7 @@ public class TOAttribute extends AbstractAttribute { } public static TOAttribute create( - T containerSchemaNode, TypeProviderWrapper typeProviderWrapper) { + T containerSchemaNode, TypeProviderWrapper typeProviderWrapper, String packageName) { // Transfer Object: get the leaves Map map = new HashMap<>(); Map attributeNameMap = new HashMap<>(); @@ -55,18 +58,18 @@ public class TOAttribute extends AbstractAttribute { String yangName = dataSchemaNode.getQName().getLocalName(); map.put(yangName, createInnerAttribute(dataSchemaNode, - typeProviderWrapper)); + typeProviderWrapper, packageName)); } catch (IllegalArgumentException e) { throw new IllegalStateException("Unable to create TO", e); } } return new TOAttribute(containerSchemaNode, map, attributeNameMap, - containerSchemaNode.getDescription()); + containerSchemaNode.getDescription(), packageName); } private static AttributeIfc createInnerAttribute( DataSchemaNode dataSchemaNode, - TypeProviderWrapper typeProviderWrapper) { + TypeProviderWrapper typeProviderWrapper, String packageName) { Class type = isAllowedType(dataSchemaNode); if (type.equals(LeafSchemaNode.class)) @@ -74,13 +77,13 @@ public class TOAttribute extends AbstractAttribute { typeProviderWrapper); else if (type.equals(ListSchemaNode.class)) return ListAttribute.create((ListSchemaNode) dataSchemaNode, - typeProviderWrapper); + typeProviderWrapper, packageName); else if (type.equals(LeafListSchemaNode.class)) return ListAttribute.create((LeafListSchemaNode) dataSchemaNode, typeProviderWrapper); else if (type.equals(ContainerSchemaNode.class)) return TOAttribute.create((ContainerSchemaNode) dataSchemaNode, - typeProviderWrapper); + typeProviderWrapper, packageName); throw new IllegalStateException("This should never happen"); } @@ -98,12 +101,13 @@ public class TOAttribute extends AbstractAttribute { private TOAttribute(DataSchemaNode attrNode, Map transferObject, - Map attributeNameMap, String nullableDescription) { + Map attributeNameMap, String nullableDescription, String packageName) { super(attrNode); yangNameToAttributeMap = transferObject; this.attributeNameMap = attributeNameMap; this.nullableDescription = nullableDescription; nullableDefault = null; + this.packageName = packageName; } public Map getAttributeNameMap() { @@ -197,6 +201,12 @@ public class TOAttribute extends AbstractAttribute { + yangNameToAttributeMap + '}'; } + @Override + public Type getType() { + // TODO: ReferencedTypeImpl from Types + return new ReferencedTypeImpl(packageName, getUpperCaseCammelCase()); + } + @Override public CompositeType getOpenType() { String description = getNullableDescription() == null ? getAttributeYangName() @@ -222,6 +232,10 @@ public class TOAttribute extends AbstractAttribute { } } + public String getPackageName() { + return packageName; + } + private static final class FunctionImpl implements Function, OpenType> { private final String[] itemNames; diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java index 661dbd7da3..e86c876169 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryTest.java @@ -7,38 +7,14 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; - -import java.net.URI; -import java.net.URISyntaxException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; - -import javax.management.openmbean.ArrayType; -import javax.management.openmbean.CompositeType; -import javax.management.openmbean.SimpleType; - +import com.google.common.collect.Sets; import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TypedAttribute; import org.opendaylight.yangtools.binding.generator.util.Types; @@ -48,13 +24,37 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; -import com.google.common.collect.Sets; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.SimpleType; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; public class ModuleMXBeanEntryTest extends AbstractYangTest { public static final String EVENTBUS_MXB_NAME = "eventbus"; public static final String ASYNC_EVENTBUS_MXB_NAME = "async-eventbus"; public static final String THREADFACTORY_NAMING_MXB_NAME = "threadfactory-naming"; public static final String THREADPOOL_DYNAMIC_MXB_NAME = "threadpool-dynamic"; + public static final String THREADPOOL_REGISTRY_IMPL_NAME = "threadpool-registry-impl"; public static final String BGP_LISTENER_IMPL_MXB_NAME = "bgp-listener-impl"; @@ -87,7 +87,7 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest { assertNotNull(namesToMBEs); Set expectedMXBeanNames = Sets.newHashSet(EVENTBUS_MXB_NAME, ASYNC_EVENTBUS_MXB_NAME, THREADFACTORY_NAMING_MXB_NAME, - THREADPOOL_DYNAMIC_MXB_NAME); + THREADPOOL_DYNAMIC_MXB_NAME, THREADPOOL_REGISTRY_IMPL_NAME); assertThat(namesToMBEs.keySet(), is(expectedMXBeanNames)); return namesToMBEs; } @@ -299,6 +299,15 @@ public class ModuleMXBeanEntryTest extends AbstractYangTest { } } + { // test multiple dependencies + ModuleMXBeanEntry threadPoolRegistry = namesToMBEs.get(THREADPOOL_REGISTRY_IMPL_NAME); + Map attributes = threadPoolRegistry.getAttributes(); + assertEquals(1, attributes.size()); + AttributeIfc threadpoolsAttr = attributes.get("threadpools"); + assertNotNull(threadpoolsAttr); + assertTrue(threadpoolsAttr instanceof ListDependenciesAttribute); + ListDependenciesAttribute threadpools = (ListDependenciesAttribute) threadpoolsAttr; + } } } diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/SchemaContextTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/SchemaContextTest.java index 24c025755b..14ec7e0fdc 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/SchemaContextTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/SchemaContextTest.java @@ -100,10 +100,15 @@ public class SchemaContextTest extends AbstractYangTest { @Test public void testReadingIdentities_threadsJavaModule() { - Map> expectedIdentitiesToBases = ImmutableMap - .of("eventbus", Optional.of(MODULE_TYPE_Q_NAME), "async-eventbus", Optional.of(MODULE_TYPE_Q_NAME), - "threadfactory-naming", Optional.of(MODULE_TYPE_Q_NAME), "threadpool-dynamic", - Optional.of(MODULE_TYPE_Q_NAME), "thread-rpc-context", Optional.absent()); + Map> expectedIdentitiesToBases = new HashMap(){{ + put(ModuleMXBeanEntryTest.EVENTBUS_MXB_NAME, Optional.of(MODULE_TYPE_Q_NAME)); + put(ModuleMXBeanEntryTest.ASYNC_EVENTBUS_MXB_NAME, Optional.of(MODULE_TYPE_Q_NAME)); + put(ModuleMXBeanEntryTest.THREADFACTORY_NAMING_MXB_NAME, Optional.of(MODULE_TYPE_Q_NAME)); + put(ModuleMXBeanEntryTest.THREADPOOL_DYNAMIC_MXB_NAME, Optional.of(MODULE_TYPE_Q_NAME)); + put("thread-rpc-context", Optional.absent()); + put(ModuleMXBeanEntryTest.THREADPOOL_REGISTRY_IMPL_NAME, Optional.of(MODULE_TYPE_Q_NAME)); + }}; + assertAllIdentitiesAreExpected(threadsJavaModule, expectedIdentitiesToBases); } diff --git a/opendaylight/config/yang-jmx-generator/src/test/resources/test-config-threads-java.yang b/opendaylight/config/yang-jmx-generator/src/test/resources/test-config-threads-java.yang index 2972cec04f..4af5b9569a 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/resources/test-config-threads-java.yang +++ b/opendaylight/config/yang-jmx-generator/src/test/resources/test-config-threads-java.yang @@ -241,4 +241,25 @@ module config-threads-java { } } } + + identity threadpool-registry-impl { + base config:module-type; + config:java-name-prefix ThreadPoolRegistryImpl; + } + + augment "/config:modules/config:module/config:configuration" { + case threadpool-registry-impl { + when "/config:modules/config:module/config:type = 'threadpool-registry-impl'"; + + // list of dependencies: + list threadpools { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity th2:threadpool; + } + } + } + } + } } diff --git a/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang b/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang index ba5021ea09..bd83a4cc70 100644 --- a/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang +++ b/opendaylight/config/yang-test/src/main/yang/config-test-impl.yang @@ -242,6 +242,15 @@ module config-test-impl { } } } + + list testing-deps { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity test:testing; + } + } + } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java index 4b6dcfd465..2b6f862bd7 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributeIfcSwitchStatement.java @@ -12,6 +12,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIf import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import javax.management.openmbean.ArrayType; @@ -37,7 +38,9 @@ public abstract class AttributeIfcSwitchStatement { } else if (attributeIfc instanceof DependencyAttribute) { return caseDependencyAttribute(((DependencyAttribute) attributeIfc).getOpenType()); } else if (attributeIfc instanceof ListAttribute) { - return caseListAttribute(((ListAttribute) attributeIfc).getOpenType()); + return caseListAttribute((ArrayType) attributeIfc.getOpenType()); + } else if (attributeIfc instanceof ListDependenciesAttribute) { + return caseListDependeciesAttribute((ArrayType) attributeIfc.getOpenType()); } else if (attributeIfc instanceof TOAttribute) { return caseTOAttribute(((TOAttribute) attributeIfc).getOpenType()); } @@ -45,6 +48,7 @@ public abstract class AttributeIfcSwitchStatement { throw getIllegalArgumentException(attributeIfc); } + private IllegalArgumentException getIllegalArgumentException(AttributeIfc attributeIfc) { return new IllegalArgumentException("Unknown attribute type " + attributeIfc.getClass() + ", " + attributeIfc + " with open type:" + attributeIfc.getOpenType()); @@ -74,6 +78,7 @@ public abstract class AttributeIfcSwitchStatement { protected abstract T caseListAttribute(ArrayType openType); + protected abstract T caseListDependeciesAttribute(ArrayType openType); private static class UnknownOpenTypeException extends RuntimeException { public UnknownOpenTypeException(String message) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java index bc3c74a88f..e2ea404e21 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectXmlReader.java @@ -12,6 +12,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; @@ -86,4 +87,11 @@ public class ObjectXmlReader extends AttributeIfcSwitchStatement openType) { + Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + AttributeReadingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME); + return new ArrayAttributeReadingStrategy(lastAttribute.getNullableDefault(), innerStrategy); + } + } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java index 853197c0b0..6e5bd0d3fe 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java @@ -13,6 +13,7 @@ import com.google.common.collect.Maps; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; @@ -121,4 +122,10 @@ public class ObjectMapper extends AttributeIfcSwitchStatement> caseListDependeciesAttribute(ArrayType openType) { + Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + return new ArrayAttributeMappingStrategy(openType, caseDependencyAttribute(SimpleType.OBJECTNAME)); + } + } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java index c321164cf6..f5a2511260 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java @@ -12,6 +12,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; @@ -109,4 +110,10 @@ public class ObjectResolver extends AttributeIfcSwitchStatement> caseListDependeciesAttribute(ArrayType openType) { + Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + return new ArrayAttributeResolvingStrategy(caseDependencyAttribute(SimpleType.OBJECTNAME), openType); + } + } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java index 99e969970c..ad587ea987 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectXmlWriter.java @@ -12,6 +12,7 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; +import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; import org.w3c.dom.Document; @@ -96,4 +97,11 @@ public class ObjectXmlWriter extends AttributeIfcSwitchStatement openType) { + Preconditions.checkState(lastAttribute instanceof ListDependenciesAttribute); + AttributeWritingStrategy innerStrategy = caseDependencyAttribute(SimpleType.OBJECTNAME); + return new ArrayAttributeWritingStrategy(innerStrategy); + } + } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index d91e38db33..1e01a9fc9a 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -136,6 +136,7 @@ public class NetconfMappingTest extends AbstractConfigTest { checkBinaryLeafEdited(response); checkTypeConfigAttribute(response); checkTypedefs(response); + checkTestingDeps(response); checkEnum(response); checkBigDecimal(response); @@ -163,11 +164,6 @@ public class NetconfMappingTest extends AbstractConfigTest { verifyNoMoreInteractions(netconfOperationRouter); } - private void checkBigDecimal(Element response) { - int size = response.getElementsByTagName("sleep-factor").getLength(); - assertEquals(1, size); - } - private void closeSession() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { DefaultCloseSession closeOp = new DefaultCloseSession(NETCONF_SESSION_ID); @@ -394,6 +390,17 @@ public class NetconfMappingTest extends AbstractConfigTest { fail("Enum attribute " + enumName + ":" + enumContent + " not present in " + XmlUtil.toString(response)); } + private void checkTestingDeps(Element response) { + int testingDepsSize = response.getElementsByTagName("testing-deps").getLength(); + assertEquals(2, testingDepsSize); + } + + private void checkBigDecimal(Element response) { + int size = response.getElementsByTagName("sleep-factor").getLength(); + assertEquals(1, size); + } + + private void checkTypeConfigAttribute(Element response) { XmlElement modulesElement = XmlElement.fromDomElement(response).getOnlyChildElement("data") diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml index caa0094c4b..9bf0042cc6 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml @@ -94,6 +94,15 @@ prefix:testing ref_dep + + + prefix:testing + ref_dep + + + prefix:testing + ref_dep_2 + -- 2.36.6