From: Tony Tkacik Date: Mon, 26 May 2014 19:49:08 +0000 (+0000) Subject: Merge "BUG-624 make netconf tcp address optional in config.ini with default value... X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~22 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=c6ab5fdef3d0cc6fac96cb960839168ed7906b3a;hp=d8cb12ba12932c5b418a4fcaf814b42b439c486c Merge "BUG-624 make netconf tcp address optional in config.ini with default value set to 127.0.0.1:8383" --- diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 89fd22d5a2..7c47f3644d 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -17,8 +17,8 @@ 1.0.0 0.4.2-SNAPSHOT - 1.1.0 + 0.5.2-SNAPSHOT 4.1 @@ -78,6 +78,7 @@ 0.4.2-SNAPSHOT 0.4.2-SNAPSHOT 2010.09.24.4-SNAPSHOT + 2013.10.19.1-SNAPSHOT 2013.10.21.2-SNAPSHOT 2010.09.24.4-SNAPSHOT 2.3.2 @@ -927,6 +928,12 @@ ${netconf.version} test-jar + + org.opendaylight.controller + netconf-netty-util + ${netconf.version} + test-jar + org.opendaylight.controller netconf-ssh @@ -1470,6 +1477,11 @@ ietf-inet-types ${ietf-inet-types.version} + + org.opendaylight.yangtools.model + ietf-restconf + ${ietf-restconf.version} + org.opendaylight.yangtools.model ietf-topology @@ -1485,6 +1497,11 @@ ietf-yang-types ${ietf-yang-types.version} + + org.opendaylight.yangtools.model + ietf-yang-types-20130715 + 2013.07.15.1-SNAPSHOT + org.opendaylight.yangtools.model opendaylight-l2-types diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java index 8f85972d05..b7cdf94757 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ConfigRegistryImpl.java @@ -359,7 +359,7 @@ public class ConfigRegistryImpl implements AutoCloseable, ConfigRegistryImplMXBe } // register services to OSGi - Map annotationMapping = configTransactionController.getWritableRegistry().findServiceInterfaces(moduleIdentifier); + Map annotationMapping = configTransactionController.getWritableRegistry().findServiceInterfaces(moduleIdentifier); BundleContext bc = configTransactionController.getModuleFactoryBundleContext( entry.getModuleFactory().getImplementationName()); if (osgiRegistration == null) { diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/SearchableServiceReferenceWritableRegistry.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/SearchableServiceReferenceWritableRegistry.java index 7a41a3bfa2..4c5e391f74 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/SearchableServiceReferenceWritableRegistry.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/SearchableServiceReferenceWritableRegistry.java @@ -21,6 +21,6 @@ public interface SearchableServiceReferenceWritableRegistry extends ServiceRefer * @throws java.lang.IllegalArgumentException if any of service qNames is not found * @throws java.lang.NullPointerException if parameter is null */ - Map findServiceInterfaces(ModuleIdentifier moduleIdentifier); + Map findServiceInterfaces(ModuleIdentifier moduleIdentifier); } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java index ceea994154..52bb3f5ed1 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/ServiceReferenceRegistryImpl.java @@ -50,7 +50,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe private final Map serviceQNamesToAnnotations; // all Service Interface qNames for sanity checking private final Set allQNames; - Map> modulesToServiceRef = new HashMap<>(); + Map> modulesToServiceRef = new HashMap<>(); // actual reference database @@ -241,8 +241,8 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe } @Override - public Map findServiceInterfaces(ModuleIdentifier moduleIdentifier) { - Map result = modulesToServiceRef.get(moduleIdentifier); + public Map findServiceInterfaces(ModuleIdentifier moduleIdentifier) { + Map result = modulesToServiceRef.get(moduleIdentifier); if (result == null) { return Collections.emptyMap(); } @@ -417,7 +417,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe } // save to refNames refNames.put(serviceReference, moduleIdentifier); - Map refNamesToAnnotations = modulesToServiceRef.get(moduleIdentifier); + Map refNamesToAnnotations = modulesToServiceRef.get(moduleIdentifier); if (refNamesToAnnotations == null){ refNamesToAnnotations = new HashMap<>(); modulesToServiceRef.put(moduleIdentifier, refNamesToAnnotations); @@ -425,7 +425,7 @@ public class ServiceReferenceRegistryImpl implements CloseableServiceReferenceRe ServiceInterfaceAnnotation annotation = serviceQNamesToAnnotations.get(serviceReference.getServiceInterfaceQName()); checkNotNull(annotation, "Possible error in code, cannot find annotation for " + serviceReference); - refNamesToAnnotations.put(serviceReference.getRefName(), annotation); + refNamesToAnnotations.put(annotation, serviceReference.getRefName()); return result; } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BeanToOsgiServiceManager.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BeanToOsgiServiceManager.java index fbc7eb6cbe..b592fa3c79 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BeanToOsgiServiceManager.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BeanToOsgiServiceManager.java @@ -37,7 +37,7 @@ public class BeanToOsgiServiceManager { */ public OsgiRegistration registerToOsgi(AutoCloseable instance, ModuleIdentifier moduleIdentifier, BundleContext bundleContext, - Map serviceNamesToAnnotations) { + Map serviceNamesToAnnotations) { return new OsgiRegistration(instance, moduleIdentifier, bundleContext, serviceNamesToAnnotations); } @@ -57,11 +57,11 @@ public class BeanToOsgiServiceManager { @GuardedBy("this") private final Set> serviceRegistrations; @GuardedBy("this") - private final Map serviceNamesToAnnotations; + private final Map serviceNamesToAnnotations; public OsgiRegistration(AutoCloseable instance, ModuleIdentifier moduleIdentifier, BundleContext bundleContext, - Map serviceNamesToAnnotations) { + Map serviceNamesToAnnotations) { this.instance = instance; this.moduleIdentifier = moduleIdentifier; this.serviceNamesToAnnotations = serviceNamesToAnnotations; @@ -69,13 +69,13 @@ public class BeanToOsgiServiceManager { } private static Set> registerToSR(AutoCloseable instance, BundleContext bundleContext, - Map serviceNamesToAnnotations) { + Map serviceNamesToAnnotations) { Set> serviceRegistrations = new HashSet<>(); - for (Entry entry : serviceNamesToAnnotations.entrySet()) { - Class requiredInterface = entry.getValue().osgiRegistrationType(); + for (Entry entry : serviceNamesToAnnotations.entrySet()) { + Class requiredInterface = entry.getKey().osgiRegistrationType(); checkState(requiredInterface.isInstance(instance), instance.getClass().getName() + " instance should implement " + requiredInterface.getName()); - Dictionary propertiesForOsgi = createProps(entry.getKey()); + Dictionary propertiesForOsgi = createProps(entry.getValue()); ServiceRegistration serviceRegistration = bundleContext .registerService(requiredInterface.getName(), instance, propertiesForOsgi); serviceRegistrations.add(serviceRegistration); @@ -95,7 +95,7 @@ public class BeanToOsgiServiceManager { serviceRegistrations.clear(); } - public synchronized void updateRegistrations(Map newAnnotationMapping, + public synchronized void updateRegistrations(Map newAnnotationMapping, BundleContext bundleContext, AutoCloseable newInstance) { boolean notEquals = this.instance != newInstance; notEquals |= newAnnotationMapping.equals(serviceNamesToAnnotations) == false; 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 0cc950af65..773025c3cf 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 @@ -10,7 +10,6 @@ package org.opendaylight.controller.config.yangjmxgenerator; import java.util.Collection; import java.util.Collections; import java.util.Map; - import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper; import org.opendaylight.yangtools.yang.common.QName; @@ -73,6 +72,7 @@ public class ModuleMXBeanEntry extends AbstractEntry { private final Map providedServices; private Collection runtimeBeans; + private String nullableDummyContainerName; ModuleMXBeanEntry(ModuleMXBeanEntryInitial initials, Map yangToAttributes, Map providedServices2, Collection runtimeBeans) { @@ -183,6 +183,15 @@ public class ModuleMXBeanEntry extends AbstractEntry { + '\'' + '}'; } + public String getNullableDummyContainerName() { + return nullableDummyContainerName; + } + + public void setNullableDummyContainerName(String nullableDummyContainerName) { + this.nullableDummyContainerName = nullableDummyContainerName; + } + + static final class ModuleMXBeanEntryInitial { private String localName; diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java index 676c8eca6e..6da8dfc663 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntryBuilder.java @@ -7,12 +7,27 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static java.lang.String.format; +import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName; + import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.Collections2; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.annotation.Nullable; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AbstractDependencyAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.DependencyAttribute; @@ -35,26 +50,13 @@ import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.ModuleImport; import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.UsesNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.google.common.base.Preconditions.checkState; -import static java.lang.String.format; -import static org.opendaylight.controller.config.yangjmxgenerator.ConfigConstants.createConfigQName; - final class ModuleMXBeanEntryBuilder { private Module currentModule; @@ -233,7 +235,7 @@ final class ModuleMXBeanEntryBuilder { return true; } - private void processChoiceCaseNode(Map result, + private void processChoiceCaseNode(Map result, Map uniqueGeneratedClassesNames, String configModulePrefix, Map moduleIdentities, Map unaugmentedModuleIdentities, AugmentationSchema augmentation, @@ -266,15 +268,17 @@ final class ModuleMXBeanEntryBuilder { // runtime-data Collection runtimeBeans = null; + HAS_CHILDREN_AND_QNAME dataNodeContainer = getDataNodeContainer(choiceCaseNode); + if (expectedConfigurationAugmentationSchemaPath.equals(augmentation.getTargetPath())) { logger.debug("Parsing configuration of {}", moduleLocalNameFromXPath); - yangToAttributes = fillConfiguration(choiceCaseNode, currentModule, typeProviderWrapper, qNamesToSIEs, + yangToAttributes = fillConfiguration(dataNodeContainer, currentModule, typeProviderWrapper, qNamesToSIEs, schemaContext, packageName); checkUniqueAttributesWithGeneratedClass(uniqueGeneratedClassesNames, when.getQName(), yangToAttributes); } else if (expectedStateAugmentationSchemaPath.equals(augmentation.getTargetPath())) { logger.debug("Parsing state of {}", moduleLocalNameFromXPath); try { - runtimeBeans = fillRuntimeBeans(choiceCaseNode, currentModule, typeProviderWrapper, packageName, + runtimeBeans = fillRuntimeBeans(dataNodeContainer, currentModule, typeProviderWrapper, packageName, moduleLocalNameFromXPath, javaNamePrefix); } catch (NameConflictException e) { throw new NameConflictException(e.getConflictingName(), when.getQName(), when.getQName()); @@ -289,14 +293,20 @@ final class ModuleMXBeanEntryBuilder { } else { throw new IllegalArgumentException("Cannot parse augmentation " + augmentation); } + boolean hasDummyContainer = choiceCaseNode.equals(dataNodeContainer) == false; + + String nullableDummyContainerName = hasDummyContainer ? dataNodeContainer.getQName().getLocalName() : null; if (result.containsKey(moduleLocalNameFromXPath)) { - // either fill runtimeBeans or yangToAttributes + // either fill runtimeBeans or yangToAttributes, merge ModuleMXBeanEntry moduleMXBeanEntry = result.get(moduleLocalNameFromXPath); if (yangToAttributes != null && moduleMXBeanEntry.getAttributes() == null) { moduleMXBeanEntry.setYangToAttributes(yangToAttributes); } else if (runtimeBeans != null && moduleMXBeanEntry.getRuntimeBeans() == null) { moduleMXBeanEntry.setRuntimeBeans(runtimeBeans); } + checkState(Objects.equals(nullableDummyContainerName, moduleMXBeanEntry.getNullableDummyContainerName()), + "Mismatch in module " + moduleMXBeanEntry.toString() + " - dummy container must be present/missing in" + + " both state and configuration"); } else { ModuleMXBeanEntry.ModuleMXBeanEntryInitial initial = new ModuleMXBeanEntry.ModuleMXBeanEntryInitialBuilder() .setIdSchemaNode(moduleIdentity).setPackageName(packageName).setJavaNamePrefix(javaNamePrefix) @@ -309,6 +319,7 @@ final class ModuleMXBeanEntryBuilder { moduleMXBeanEntry.setYangModuleName(currentModule.getName()); moduleMXBeanEntry.setYangModuleLocalname(moduleLocalNameFromXPath); + moduleMXBeanEntry.setNullableDummyContainerName(nullableDummyContainerName); result.put(moduleLocalNameFromXPath, moduleMXBeanEntry); } } @@ -352,29 +363,52 @@ final class ModuleMXBeanEntryBuilder { } private void checkUniqueTOAttr(Map uniqueGeneratedClassNames, QName parentQName, TOAttribute attr) { - final String upperCaseCammelCase = attr.getUpperCaseCammelCase(); - if (uniqueGeneratedClassNames.containsKey(upperCaseCammelCase)) { - QName firstDefinedQName = uniqueGeneratedClassNames.get(upperCaseCammelCase); - throw new NameConflictException(upperCaseCammelCase, firstDefinedQName, parentQName); + final String upperCaseCamelCase = attr.getUpperCaseCammelCase(); + if (uniqueGeneratedClassNames.containsKey(upperCaseCamelCase)) { + QName firstDefinedQName = uniqueGeneratedClassNames.get(upperCaseCamelCase); + throw new NameConflictException(upperCaseCamelCase, firstDefinedQName, parentQName); } else { - uniqueGeneratedClassNames.put(upperCaseCammelCase, parentQName); + uniqueGeneratedClassNames.put(upperCaseCamelCase, parentQName); } } - private Collection fillRuntimeBeans(ChoiceCaseNode choiceCaseNode, Module currentModule, + private Collection fillRuntimeBeans(DataNodeContainer dataNodeContainer, Module currentModule, TypeProviderWrapper typeProviderWrapper, String packageName, String moduleLocalNameFromXPath, String javaNamePrefix) { - return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName, choiceCaseNode, moduleLocalNameFromXPath, + return RuntimeBeanEntry.extractClassNameToRuntimeBeanMap(packageName, dataNodeContainer, moduleLocalNameFromXPath, typeProviderWrapper, javaNamePrefix, currentModule).values(); } - private Map fillConfiguration(ChoiceCaseNode choiceCaseNode, Module currentModule, + /** + * Since each case statement within a module must provide unique child nodes, it is allowed to wrap + * the actual configuration with a container node with name equal to case name. + * + * @param choiceCaseNode state or configuration case statement + * @return either choiceCaseNode or its only child container + */ + private HAS_CHILDREN_AND_QNAME getDataNodeContainer(ChoiceCaseNode choiceCaseNode) { + Set childNodes = choiceCaseNode.getChildNodes(); + if (childNodes.size() == 1) { + DataSchemaNode onlyChild = childNodes.iterator().next(); + if (onlyChild instanceof ContainerSchemaNode) { + ContainerSchemaNode onlyContainer = (ContainerSchemaNode) onlyChild; + if (Objects.equals(onlyContainer.getQName().getLocalName(), choiceCaseNode.getQName().getLocalName())) { + // the actual configuration is inside dummy container + return (HAS_CHILDREN_AND_QNAME) onlyContainer; + } + } + } + return (HAS_CHILDREN_AND_QNAME) choiceCaseNode; + } + + private Map fillConfiguration(DataNodeContainer dataNodeContainer, Module currentModule, TypeProviderWrapper typeProviderWrapper, Map qNamesToSIEs, SchemaContext schemaContext, String packageName) { Map yangToAttributes = new HashMap<>(); - for (DataSchemaNode attrNode : choiceCaseNode.getChildNodes()) { + Set childNodes = dataNodeContainer.getChildNodes(); + for (DataSchemaNode attrNode : childNodes) { AttributeIfc attributeValue = getAttributeValue(attrNode, currentModule, qNamesToSIEs, typeProviderWrapper, schemaContext, packageName); yangToAttributes.put(attributeValue.getAttributeYangName(), attributeValue); @@ -483,7 +517,7 @@ final class ModuleMXBeanEntryBuilder { String prefix = m.group(1); ModuleImport moduleImport = findModuleImport(currentModule, prefix); foundModule = schemaContext.findModuleByName(moduleImport.getModuleName(), moduleImport.getRevision()); - checkState(foundModule != null, format("Module not found in SchemaContext by %s", moduleImport)); + checkNotNull(foundModule, format("Module not found in SchemaContext by %s", moduleImport)); localSIName = m.group(2); } else { foundModule = currentModule; // no prefix => SIE is in currentModule 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 cd14458b0f..c941d1504d 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 @@ -7,9 +7,24 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.collect.Lists; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.JavaAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribute; @@ -18,7 +33,6 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribu import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.FullyQualifiedNameHelper; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.NameConflictException; import org.opendaylight.yangtools.yang.common.QName; -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; @@ -32,22 +46,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; import org.opendaylight.yangtools.yang.model.api.UsesNode; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; - /** * Holds information about runtime bean to be generated. There are two kinds of * RuntimeBeanEntry instances: if isRoot flag is set to true, this bean @@ -68,7 +66,7 @@ public class RuntimeBeanEntry { @VisibleForTesting RuntimeBeanEntry(String packageName, - DataSchemaNode nodeForReporting, String yangName, + DataNodeContainer nodeForReporting, String yangName, String javaNamePrefix, boolean isRoot, Optional keyYangName, List attributes, List children, Set rpcs) { @@ -112,7 +110,7 @@ public class RuntimeBeanEntry { * not contain special configuration for it. */ public static Map extractClassNameToRuntimeBeanMap( - String packageName, ChoiceCaseNode container, + String packageName, DataNodeContainer container, String moduleYangName, TypeProviderWrapper typeProviderWrapper, String javaNamePrefix, Module currentModule) { @@ -390,7 +388,7 @@ public class RuntimeBeanEntry { } private static RuntimeBeanEntry createRoot(String packageName, - DataSchemaNode nodeForReporting, String attributeYangName, + DataNodeContainer nodeForReporting, String attributeYangName, List attributes, String javaNamePrefix, List children, Set rpcs) { return new RuntimeBeanEntry(packageName, nodeForReporting, diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java index 76d97703af..b9f2ba9cd1 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/AbstractYangTest.java @@ -7,8 +7,19 @@ */ package org.opendaylight.controller.config.yangjmxgenerator; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.format; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + import com.google.common.base.Preconditions; import com.google.common.collect.Sets; +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 org.junit.Assert; import org.junit.Before; import org.opendaylight.controller.config.yangjmxgenerator.plugin.util.YangModelSearchUtils; @@ -19,18 +30,6 @@ 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 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; protected Map namesToModules; // are module names globally diff --git a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeRegistratorTest.java b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeRegistratorTest.java index 6dd64441df..7765b28bb5 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeRegistratorTest.java +++ b/opendaylight/config/yang-jmx-generator/src/test/java/org/opendaylight/controller/config/yangjmxgenerator/RuntimeRegistratorTest.java @@ -11,27 +11,25 @@ import static org.apache.commons.lang3.StringUtils.capitalize; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import com.google.common.base.Optional; import java.net.URI; import java.util.Collections; import java.util.List; - import org.junit.Test; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; import org.opendaylight.yangtools.sal.binding.model.api.Type; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; -import com.google.common.base.Optional; - public class RuntimeRegistratorTest { // TODO add more tests protected RuntimeBeanEntry prepareRootRB(List children) { - DataSchemaNode dataSchemaNodeForReporting = mock(DataSchemaNode.class); - doReturn("DataSchemaNode").when(dataSchemaNodeForReporting).toString(); - return new RuntimeBeanEntry("pa.cka.ge", dataSchemaNodeForReporting, + DataNodeContainer nodeContainer = mock(DataNodeContainer.class); + doReturn("DataSchemaNode").when(nodeContainer).toString(); + return new RuntimeBeanEntry("pa.cka.ge", nodeContainer, "module-name", "ModuleName", true, Optional. absent(), Collections. emptyList(), children, Collections. emptySet()); @@ -39,9 +37,9 @@ public class RuntimeRegistratorTest { protected RuntimeBeanEntry prepareChildRB(List children, String prefix) { - DataSchemaNode dataSchemaNodeForReporting = mock(DataSchemaNode.class); - doReturn("DataSchemaNode").when(dataSchemaNodeForReporting).toString(); - return new RuntimeBeanEntry("pa.cka.ge", dataSchemaNodeForReporting, + DataNodeContainer nodeContainer = mock(DataNodeContainer.class); + doReturn("DataSchemaNode").when(nodeContainer).toString(); + return new RuntimeBeanEntry("pa.cka.ge", nodeContainer, prefix + "child-name", capitalize(prefix) + "ChildName", false, Optional. absent(), Collections. emptyList(), children, diff --git a/opendaylight/config/yang-jmx-generator/src/test/resources/config-bgp-listener-impl.yang b/opendaylight/config/yang-jmx-generator/src/test/resources/config-bgp-listener-impl.yang index fca83fd6be..0a011b772c 100644 --- a/opendaylight/config/yang-jmx-generator/src/test/resources/config-bgp-listener-impl.yang +++ b/opendaylight/config/yang-jmx-generator/src/test/resources/config-bgp-listener-impl.yang @@ -23,20 +23,22 @@ module config-bgp-listener-impl { augment "/config:modules/config:module/config:state" { case bgp-listener-impl { when "/config:modules/config:module/config:type = 'bgp-listener-impl'"; - list peers { - config:inner-state-bean; - leaf port { - type inet:port-number; - default 179; + container bgp-listener-impl { + list peers { + config:inner-state-bean; + leaf port { + type inet:port-number; + default 179; + } + leaf core-size { + type uint32; + } } - leaf core-size { - type uint32; - } - } - leaf as-number { - mandatory true; - type inet:as-number; + leaf as-number { + mandatory true; + type inet:as-number; + } } } } 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 4af5b9569a..e189ef7d66 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 @@ -192,42 +192,44 @@ module config-threads-java { augment "/config:modules/config:module/config:configuration" { case threadpool-dynamic { when "/config:modules/config:module/config:type = 'threadpool-dynamic'"; - leaf core-size { - type uint32; - } + container threadpool-dynamic { + leaf core-size { + type uint32; + } - leaf keep-alive { - type uint32; - units seconds; - default 10; - } + leaf keep-alive { + type uint32; + units seconds; + default 10; + } - leaf maximum-size { - type uint32; - description "maximum-size description"; - } + leaf maximum-size { + type uint32; + description "maximum-size description"; + } - leaf binary { - type binary; - } + leaf binary { + type binary; + } - container threadfactory { - description "threadfactory description"; - uses config:service-ref { - refine type { - mandatory true; - config:required-identity th2:threadfactory; + container threadfactory { + description "threadfactory description"; + uses config:service-ref { + refine type { + mandatory true; + config:required-identity th2:threadfactory; + } } } - } - leaf-list users { - type string; - } + leaf-list users { + type string; + } - leaf-list users-numbers { - type uint32; - description "numbers of users description"; + leaf-list users-numbers { + type uint32; + description "numbers of users description"; + } } } } @@ -235,9 +237,11 @@ module config-threads-java { augment "/config:modules/config:module/config:state" { case threadpool-dynamic { when "/config:modules/config:module/config:type = 'threadpool-dynamic'"; - // root runtime bean - leaf created-sessions { - type uint32; + container threadpool-dynamic { + // root runtime bean + leaf created-sessions { + type uint32; + } } } } 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 c82da58c15..4b006bc72e 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 @@ -162,177 +162,179 @@ module config-test-impl { augment "/config:modules/config:module/config:configuration" { case impl-netconf { when "/config:modules/config:module/config:type = 'impl-netconf'"; - leaf binaryLeaf { - type binary; - default ZGVmYXVsdEJpbg==; - } - - leaf type { - type string; - default "default-string"; - } + container impl-netconf { + leaf binaryLeaf { + type binary; + default ZGVmYXVsdEJpbg==; + } - leaf extended { - type tt:extend-once; - default 1; - } + leaf type { + type string; + default "default-string"; + } - leaf extended-twice { - type tt:extend-twice; - default 2; - } + leaf extended { + type tt:extend-once; + default 1; + } - leaf extended-enum { - type tt:extend-enum; - default ONE; - } + leaf extended-twice { + type tt:extend-twice; + default 2; + } - leaf ip { - type inet:ip-address; - default 0:0:0:0:0:0:0:1; - } + leaf extended-enum { + type tt:extend-enum; + default ONE; + } - leaf union-test-attr { - type tt:unionTest; - default 456; - } + leaf ip { + type inet:ip-address; + default 0:0:0:0:0:0:0:1; + } - leaf sleep-factor { - type decimal64 { - fraction-digits 2; + leaf union-test-attr { + type tt:unionTest; + default 456; } - default 2.00; - } - container dto-c { - leaf simple-arg { - type uint32; + leaf sleep-factor { + type decimal64 { + fraction-digits 2; + } + default 2.00; } - container dto-a-inner { + container dto-c { leaf simple-arg { type uint32; } - container dto-a-inner-inner { + container dto-a-inner { leaf simple-arg { type uint32; } + + container dto-a-inner-inner { + leaf simple-arg { + type uint32; + } + } } } - } - - leaf simpleInt { - type uint32; - } - - leaf simpleBoolean { - type boolean; - default false; - } - - leaf simple-long { - type int64; - default -45; - } - - leaf simple-long-2 { - type uint32; - default 445; - } - leaf simple-BigInteger { - type uint64; - default 545454; - } + leaf simpleInt { + type uint32; + } - leaf simple-byte { - type int8; - default -4; - } + leaf simpleBoolean { + type boolean; + default false; + } - leaf simple-short { - type uint8; - default 45; - } + leaf simple-long { + type int64; + default -45; + } - leaf simple-test { - type uint16; - default 99; - } + leaf simple-long-2 { + type uint32; + default 445; + } - leaf-list simple-list { - type uint16; - } + leaf simple-BigInteger { + type uint64; + default 545454; + } - container dto_d { - leaf simple-int1 { - type uint32; + leaf simple-byte { + type int8; + default -4; } - leaf simple-int2 { - type uint32; + leaf simple-short { + type uint8; + default 45; } - leaf simple-int3 { + leaf simple-test { type uint16; + default 99; } leaf-list simple-list { type uint16; } - list complex-dto-bInner { - leaf-list simple-list { - type uint16; + container dto_d { + leaf simple-int1 { + type uint32; } + + leaf simple-int2 { + type uint32; + } + leaf simple-int3 { type uint16; } - container deep { + leaf-list simple-list { + type uint16; + } + + list complex-dto-bInner { + leaf-list simple-list { + type uint16; + } leaf simple-int3 { type uint16; - default 0; + } + + container deep { + leaf simple-int3 { + type uint16; + default 0; + } } } } - } - list complex-list { - list simple-list { - leaf simple-int3 { - type uint16; + list complex-list { + list simple-list { + leaf simple-int3 { + type uint16; + } } } - } - list peers { - leaf port { - type string; - } - leaf core-size { - type uint32; - } - leaf simple-int3 { - type uint16; - } - } + list peers { + leaf port { + type string; + } + leaf core-size { + type uint32; + } + leaf simple-int3 { + type uint16; + } + } - container testing-dep { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity test:testing; + container testing-dep { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity test:testing; + } } } - } - list testing-deps { - uses config:service-ref { - refine type { - mandatory true; - config:required-identity test:testing; + list testing-deps { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity test:testing; + } } } } @@ -342,97 +344,99 @@ module config-test-impl { augment "/config:modules/config:module/config:state" { case impl-netconf { when "/config:modules/config:module/config:type = 'impl-netconf'"; - // rpc - rpcx:rpc-context-instance "test-rpc"; - - // root runtime bean - leaf created-sessions { - type uint32; - } - - container asdf { - leaf simpleInt { - type uint16; - } + container impl-netconf { + // rpc + rpcx:rpc-context-instance "test-rpc"; - leaf simpleString { - type string; + // root runtime bean + leaf created-sessions { + type uint32; } - } + container asdf { + leaf simpleInt { + type uint16; + } - list inner-running-data-additional { - config:inner-state-bean; + leaf simpleString { + type string; + } + } - // rpc - rpcx:rpc-context-instance "inner-test-rpc"; - key "simpleString"; + list inner-running-data-additional { + config:inner-state-bean; - leaf simple-int3 { - type uint16; - } + // rpc + rpcx:rpc-context-instance "inner-test-rpc"; - leaf simpleString { - type string; - } + key "simpleString"; - container deep4 { - leaf boool { - type boolean; + leaf simple-int3 { + type uint16; } - } - } - - list inner-running-data { - config:inner-state-bean; - key "simple-int3"; - - leaf simple-int3 { - type uint16; + leaf simpleString { + type string; } - container deep2 { - leaf boool { - type boolean; + container deep4 { + leaf boool { + type boolean; + } } - } + } - list inner-inner-running-data { + list inner-running-data { config:inner-state-bean; - rpcx:rpc-context-instance "inner-inner-test-rpc"; - rpcx:rpc-context-instance "complex-output-rpc"; - key "simple-int3"; leaf simple-int3 { - type uint16; - } + type uint16; + } - leaf-list list-of-strings { - type string; - } + container deep2 { + leaf boool { + type boolean; + } + } - list not-state-bean { - leaf element { - type string; + list inner-inner-running-data { + config:inner-state-bean; + + rpcx:rpc-context-instance "inner-inner-test-rpc"; + rpcx:rpc-context-instance "complex-output-rpc"; + + key "simple-int3"; + + leaf simple-int3 { + type uint16; } - list not-state-bean-internal { - // This should be ignored - config:inner-state-bean; + leaf-list list-of-strings { + type string; + } - leaf element2 { + list not-state-bean { + leaf element { type string; } + + list not-state-bean-internal { + // This should be ignored + config:inner-state-bean; + + leaf element2 { + type string; + } + } } - } - container deep3 { - leaf boool { - type boolean; + container deep3 { + leaf boool { + type boolean; + } } } } diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index 48e661f196..52aa6d276b 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -1187,6 +1187,10 @@ org.opendaylight.yangtools.model ietf-inet-types + + org.opendaylight.yangtools.model + ietf-restconf + org.opendaylight.yangtools.model ietf-topology @@ -1195,6 +1199,10 @@ org.opendaylight.yangtools.model ietf-yang-types + + org.opendaylight.yangtools.model + ietf-yang-types-20130715 + org.opendaylight.yangtools.model opendaylight-l2-types diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java index 9276238e01..2c95252ac7 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/NodeMapping.java @@ -7,6 +7,7 @@ */ package org.opendaylight.controller.sal.compatibility; +import java.math.BigInteger; import java.util.Date; import java.util.HashSet; import java.util.List; @@ -334,8 +335,8 @@ public final class NodeMapping { public static MacAddress toADMacAddress(final NodeId id) { final String nodeId = id.getValue().replaceAll("openflow:", ""); - long lNodeId = Long.parseLong(nodeId); - lNodeId = Long.valueOf(lNodeId).longValue(); + BigInteger nodeIdRaw = new BigInteger(nodeId); + long lNodeId = nodeIdRaw.longValue(); byte[] bytesFromDpid = ToSalConversionsUtils.bytesFromDpid(lNodeId); return new MacAddress(bytesFromDpid); } diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java new file mode 100644 index 0000000000..b9a2f5bff0 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/NodeMappingTest.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.compatibility.test; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.controller.sal.compatibility.NodeMapping; +import org.opendaylight.controller.sal.core.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; + +/** + * test of {@link NodeMapping} utility class + */ +public class NodeMappingTest { + + /** + * Test method for + * {@link org.opendaylight.controller.sal.compatibility.NodeMapping#toADMacAddress(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId)} + * . + */ + @Test + public void testToADMacAddress() { + NodeId[] nodeIds = new NodeId[] { + // 0x0000|0000 0000002a (answer to the ultimate question of life, universe and everything) + new NodeId("42"), + // 0x7fff|ffff ffffffff (max long -> 2**63 - 1) + new NodeId("9223372036854775807"), + // 0x7fff|7fff ffffffff + new NodeId("9223231299366420479"), + // 0x8fff|7fff ffffffff (more than biggest positive long) + new NodeId("10376152803973267455"), + // 0xca13|764a e9ace65a (BUG-770) + new NodeId("14561112084339025498") + }; + + byte[][] expectedMacs = new byte[][] { + {0, 0, 0, 0, 0, 0x2a}, + {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}, + {(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}, + {(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}, + {(byte) 0x76, (byte) 0x4a, (byte) 0xe9, (byte) 0xac, (byte) 0xe6, (byte) 0x5a} + }; + + Assert.assertEquals(expectedMacs.length, nodeIds.length); + + for (int i = 0; i < expectedMacs.length; i++) { + NodeId nodeId = nodeIds[i]; + MacAddress mac = NodeMapping.toADMacAddress(nodeId); + Assert.assertArrayEquals(expectedMacs[i], mac.getMacAddress()); + } + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java index 750defc0e9..0f0ce0dc9d 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java @@ -26,6 +26,8 @@ import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.google.common.base.Optional; import com.google.common.base.Preconditions; @@ -36,6 +38,8 @@ import com.google.common.base.Preconditions; public final class RuntimeMappingModule extends org.opendaylight.controller.config.yang.md.sal.binding.impl.AbstractRuntimeMappingModule { + private static final Logger LOG = LoggerFactory.getLogger(RuntimeMappingModule.class); + private BundleContext bundleContext; public RuntimeMappingModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, @@ -163,10 +167,17 @@ public final class RuntimeMappingModule extends } @Override - public void close() throws Exception { + public void close() { if(delegate != null) { delegate = null; - bundleContext.ungetService(reference); + + try { + bundleContext.ungetService(reference); + } catch (IllegalStateException e) { + // Indicates the BundleContext is no longer valid which can happen normally on shutdown. + LOG.debug( "Error unregistering service", e ); + } + bundleContext= null; reference = null; } diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java index 33a9869a6b..f30c8ddcaa 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizer.java @@ -92,11 +92,11 @@ public class DataNormalizer { } // Write Augmentation data resolution - if (legacyData.getChildren().size() == 1) { + if (legacyData.getValue().size() == 1) { final DataNormalizationOperation potentialOp; try { - final QName childType = legacyData.getChildren().get(0).getNodeType(); + final QName childType = legacyData.getValue().get(0).getNodeType(); potentialOp = currentOp.getChild(childType); } catch (DataNormalizationException e) { throw new IllegalArgumentException(String.format("Failed to get child operation for %s", legacyData), e); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java index ba7414d42e..fd24944018 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java @@ -16,28 +16,29 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -/** -* -*/ public final class SchemaServiceImplSingletonModule extends - org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImplSingletonModule { +org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImplSingletonModule { + + private static final Logger LOG = LoggerFactory.getLogger(SchemaServiceImplSingletonModule.class); BundleContext bundleContext; - public SchemaServiceImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, - org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + public SchemaServiceImplSingletonModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, + final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); } - public SchemaServiceImplSingletonModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, - org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, - SchemaServiceImplSingletonModule oldModule, java.lang.AutoCloseable oldInstance) { + public SchemaServiceImplSingletonModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, + final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, + final SchemaServiceImplSingletonModule oldModule, final java.lang.AutoCloseable oldInstance) { super(identifier, dependencyResolver, oldModule, oldInstance); } @Override - public boolean canReuseInstance(AbstractSchemaServiceImplSingletonModule oldModule) { + public boolean canReuseInstance(final AbstractSchemaServiceImplSingletonModule oldModule) { return true; } @@ -45,7 +46,7 @@ public final class SchemaServiceImplSingletonModule extends return bundleContext; } - public void setBundleContext(BundleContext bundleContext) { + public void setBundleContext(final BundleContext bundleContext) { this.bundleContext = bundleContext; } @@ -61,8 +62,7 @@ public final class SchemaServiceImplSingletonModule extends return new GlobalSchemaServiceProxy(getBundleContext(), ref); } - GlobalBundleScanningSchemaServiceImpl newInstance = new GlobalBundleScanningSchemaServiceImpl(); - newInstance.setContext(getBundleContext()); + GlobalBundleScanningSchemaServiceImpl newInstance = new GlobalBundleScanningSchemaServiceImpl(getBundleContext()); newInstance.start(); return newInstance; } @@ -73,7 +73,7 @@ public final class SchemaServiceImplSingletonModule extends private ServiceReference reference; private SchemaService delegate; - public GlobalSchemaServiceProxy(BundleContext bundleContext, ServiceReference ref) { + public GlobalSchemaServiceProxy(final BundleContext bundleContext, final ServiceReference ref) { this.bundleContext = bundleContext; this.reference = ref; this.delegate = bundleContext.getService(reference); @@ -83,29 +83,42 @@ public final class SchemaServiceImplSingletonModule extends public void close() throws Exception { if (delegate != null) { delegate = null; - bundleContext.ungetService(reference); + + try { + bundleContext.ungetService(reference); + } catch (IllegalStateException e) { + // Indicates the service was already unregistered which can happen normally + // on shutdown. + LOG.debug( "Error unregistering service", e ); + } + reference = null; bundleContext = null; } } - public void addModule(Module arg0) { + @Override + public void addModule(final Module arg0) { delegate.addModule(arg0); } + @Override public SchemaContext getGlobalContext() { return delegate.getGlobalContext(); } + @Override public SchemaContext getSessionContext() { return delegate.getSessionContext(); } - public ListenerRegistration registerSchemaServiceListener(SchemaServiceListener arg0) { + @Override + public ListenerRegistration registerSchemaServiceListener(final SchemaServiceListener arg0) { return delegate.registerSchemaServiceListener(arg0); } - public void removeModule(Module arg0) { + @Override + public void removeModule(final Module arg0) { delegate.removeModule(arg0); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java index 827e4ca63d..3de07fc2ab 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java @@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.collect.Maps; public abstract class TranslatingDataChangeEvent implements - DataChangeEvent { +DataChangeEvent { private TranslatingDataChangeEvent() { } @@ -98,7 +98,6 @@ public abstract class TranslatingDataChangeEvent implements return null; } - @SuppressWarnings({ "rawtypes", "unchecked" }) private final static class OperationalChangeEvent extends TranslatingDataChangeEvent { private final AsyncDataChangeEvent> delegate; @@ -106,7 +105,7 @@ public abstract class TranslatingDataChangeEvent implements private Map updatedCache; public OperationalChangeEvent(final AsyncDataChangeEvent> change, - final DataNormalizer normalizer) { + final DataNormalizer normalizer) { this.delegate = change; this.normalizer = normalizer; } @@ -179,7 +178,7 @@ public abstract class TranslatingDataChangeEvent implements private Map updatedCache; public ConfigurationChangeEvent(final AsyncDataChangeEvent> change, - final DataNormalizer normalizer) { + final DataNormalizer normalizer) { this.delegate = change; this.normalizer = normalizer; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java index 4e3aa49113..15479be462 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java @@ -1,21 +1,27 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedLong; +/** + * An implementation of apply operation which fails to do anything, + * consistently. An instance of this class is used by the data tree + * if it does not have a SchemaContext attached and hence cannot + * perform anything meaningful. + */ final class AlwaysFailOperation implements ModificationApplyOperation { - @Override - public Optional apply(final NodeModification modification, - final Optional storeMeta, final UnsignedLong subtreeVersion) { + public Optional apply(final ModifiedNode modification, + final Optional storeMeta, final Version subtreeVersion) { throw new IllegalStateException("Schema Context is not available."); } @Override - public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional storeMetadata) { + public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional storeMetadata) { throw new IllegalStateException("Schema Context is not available."); } @@ -25,7 +31,7 @@ final class AlwaysFailOperation implements ModificationApplyOperation { } @Override - public void verifyStructure(final NodeModification modification) throws IllegalArgumentException { + public void verifyStructure(final ModifiedNode modification) { throw new IllegalStateException("Schema Context is not available."); } } \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/DataNodeContainerModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/DataNodeContainerModificationStrategy.java index aea070c120..dc891482ab 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/DataNodeContainerModificationStrategy.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/DataNodeContainerModificationStrategy.java @@ -39,6 +39,12 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +/** + * Base strategy for applying changes to a ContainerNode, irrespective of its + * actual type. + * + * @param Type of the container node + */ abstract class DataNodeContainerModificationStrategy extends NormalizedNodeContainerModificationStrategy { private final T schema; diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java index f04e379dd9..d3495b542a 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java @@ -16,6 +16,7 @@ import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; @@ -34,9 +35,9 @@ final class InMemoryDataTree implements DataTree { private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true); private ModificationApplyOperation applyOper = new AlwaysFailOperation(); private SchemaContext currentSchemaContext; - private StoreMetadataNode rootNode; + private TreeNode rootNode; - public InMemoryDataTree(StoreMetadataNode rootNode, final SchemaContext schemaContext) { + public InMemoryDataTree(final TreeNode rootNode, final SchemaContext schemaContext) { this.rootNode = Preconditions.checkNotNull(rootNode); if (schemaContext != null) { @@ -80,28 +81,28 @@ final class InMemoryDataTree implements DataTree { } @Override - public void validate(DataTreeModification modification) throws DataPreconditionFailedException { + public void validate(final DataTreeModification modification) throws DataPreconditionFailedException { Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass()); final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification; - m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.of(rootNode)); + m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.of(rootNode)); } @Override - public synchronized DataTreeCandidate prepare(DataTreeModification modification) { + public synchronized DataTreeCandidate prepare(final DataTreeModification modification) { Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass()); final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification; - final NodeModification root = m.getRootModification(); + final ModifiedNode root = m.getRootModification(); - if (root.getModificationType() == ModificationType.UNMODIFIED) { + if (root.getType() == ModificationType.UNMODIFIED) { return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root); } rwLock.writeLock().lock(); try { - // FIXME: rootNode needs to be a read-write snapshot here... - final Optional newRoot = m.getStrategy().apply(m.getRootModification(), Optional.of(rootNode), StoreUtils.increase(rootNode.getSubtreeVersion())); + final Optional newRoot = m.getStrategy().apply(m.getRootModification(), + Optional.of(rootNode), rootNode.getSubtreeVersion().next()); Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node"); return new InMemoryDataTreeCandidate(PUBLIC_ROOT_PATH, root, rootNode, newRoot.get()); } finally { @@ -110,7 +111,7 @@ final class InMemoryDataTree implements DataTree { } @Override - public synchronized void commit(DataTreeCandidate candidate) { + public synchronized void commit(final DataTreeCandidate candidate) { if (candidate instanceof NoopDataTreeCandidate) { return; } @@ -118,7 +119,7 @@ final class InMemoryDataTree implements DataTree { Preconditions.checkArgument(candidate instanceof InMemoryDataTreeCandidate, "Invalid candidate class %s", candidate.getClass()); final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate)candidate; - LOG.debug("Updating Store snapshot version: {} with version:{}", rootNode.getSubtreeVersion(), c.getAfterRoot().getSubtreeVersion()); + LOG.debug("Updating datastore from {} to {}", rootNode, c.getAfterRoot()); if (LOG.isTraceEnabled()) { LOG.trace("Data Tree is {}", StoreUtils.toStringTree(c.getAfterRoot().getData())); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java index 72562f0a72..bafea6bd97 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java @@ -2,6 +2,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidateNode; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -13,38 +14,42 @@ import com.google.common.collect.Iterables; final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate { private static abstract class AbstractNode implements DataTreeCandidateNode { - private final StoreMetadataNode newMeta; - private final StoreMetadataNode oldMeta; - private final NodeModification mod; + private final ModifiedNode mod; + private final TreeNode newMeta; + private final TreeNode oldMeta; - protected AbstractNode(final NodeModification mod, - final StoreMetadataNode oldMeta, final StoreMetadataNode newMeta) { + protected AbstractNode(final ModifiedNode mod, + final TreeNode oldMeta, final TreeNode newMeta) { this.newMeta = newMeta; this.oldMeta = oldMeta; this.mod = Preconditions.checkNotNull(mod); } - protected final NodeModification getMod() { + protected final ModifiedNode getMod() { return mod; } - protected final StoreMetadataNode getNewMeta() { + protected final TreeNode getNewMeta() { return newMeta; } - protected final StoreMetadataNode getOldMeta() { + protected final TreeNode getOldMeta() { return oldMeta; } - private static final StoreMetadataNode childMeta(final StoreMetadataNode parent, final PathArgument id) { - return parent == null ? null : parent.getChild(id).orNull(); + private static final TreeNode childMeta(final TreeNode parent, final PathArgument id) { + if (parent != null) { + return parent.getChild(id).orNull(); + } else { + return null; + } } @Override public Iterable getChildNodes() { - return Iterables.transform(mod.getModifications(), new Function() { + return Iterables.transform(mod.getChildren(), new Function() { @Override - public DataTreeCandidateNode apply(final NodeModification input) { + public DataTreeCandidateNode apply(final ModifiedNode input) { final PathArgument id = input.getIdentifier(); return new ChildNode(input, childMeta(oldMeta, id), childMeta(newMeta, id)); } @@ -53,14 +58,15 @@ final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate { @Override public ModificationType getModificationType() { - return mod.getModificationType(); + return mod.getType(); } - private Optional> optionalData(StoreMetadataNode meta) { - if (meta == null) { + private Optional> optionalData(final TreeNode meta) { + if (meta != null) { + return Optional.>of(meta.getData()); + } else { return Optional.absent(); } - return Optional.>of(meta.getData()); } @Override @@ -75,7 +81,7 @@ final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate { } private static final class ChildNode extends AbstractNode { - public ChildNode(NodeModification mod, StoreMetadataNode oldMeta, StoreMetadataNode newMeta) { + public ChildNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) { super(mod, oldMeta, newMeta); } @@ -86,7 +92,7 @@ final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate { } private static final class RootNode extends AbstractNode { - public RootNode(NodeModification mod, StoreMetadataNode oldMeta, StoreMetadataNode newMeta) { + public RootNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) { super(mod, oldMeta, newMeta); } @@ -98,17 +104,17 @@ final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate { private final RootNode root; - InMemoryDataTreeCandidate(final InstanceIdentifier rootPath, final NodeModification modificationRoot, - final StoreMetadataNode oldRoot, final StoreMetadataNode newRoot) { + InMemoryDataTreeCandidate(final InstanceIdentifier rootPath, final ModifiedNode modificationRoot, + final TreeNode beforeRoot, final TreeNode afterRoot) { super(rootPath); - this.root = new RootNode(modificationRoot, oldRoot, newRoot); + this.root = new RootNode(modificationRoot, beforeRoot, afterRoot); } - StoreMetadataNode getAfterRoot() { + TreeNode getAfterRoot() { return root.getNewMeta(); } - StoreMetadataNode getBeforeRoot() { + TreeNode getBeforeRoot() { return root.getOldMeta(); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java index 7614611ab2..4640be43e7 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java @@ -1,6 +1,8 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeFactory; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; @@ -10,26 +12,26 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; * A factory for creating in-memory data trees. */ public final class InMemoryDataTreeFactory implements DataTreeFactory { - private static final InMemoryDataTreeFactory INSTANCE = new InMemoryDataTreeFactory(); + private static final InMemoryDataTreeFactory INSTANCE = new InMemoryDataTreeFactory(); - private InMemoryDataTreeFactory() { - // Never instantiated externally - } + private InMemoryDataTreeFactory() { + // Never instantiated externally + } - @Override - public InMemoryDataTree create() { - final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME); - final NormalizedNode data = Builders.containerBuilder().withNodeIdentifier(root).build(); + @Override + public InMemoryDataTree create() { + final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME); + final NormalizedNode data = Builders.containerBuilder().withNodeIdentifier(root).build(); - return new InMemoryDataTree(StoreMetadataNode.createEmpty(data), null); - } + return new InMemoryDataTree(TreeNodeFactory.createTreeNode(data, Version.initial()), null); + } - /** - * Get an instance of this factory. This method cannot fail. - * - * @return Data tree factory instance. - */ - public static final InMemoryDataTreeFactory getInstance() { - return INSTANCE; - } + /** + * Get an instance of this factory. This method cannot fail. + * + * @return Data tree factory instance. + */ + public static final InMemoryDataTreeFactory getInstance() { + return INSTANCE; + } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java index 7d0c81e39d..c05ed4b442 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java @@ -7,14 +7,13 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; -import static com.google.common.base.Preconditions.checkState; - import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; + +import javax.annotation.concurrent.GuardedBy; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -28,26 +27,20 @@ import com.google.common.base.Preconditions; final class InMemoryDataTreeModification implements DataTreeModification { private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class); - - /* - * FIXME: the thread safety of concurrent write/delete/read/seal operations - * needs to be evaluated. - */ - private static final AtomicIntegerFieldUpdater SEALED_UPDATER = - AtomicIntegerFieldUpdater.newUpdater(InMemoryDataTreeModification.class, "sealed"); - private volatile int sealed = 0; - private final ModificationApplyOperation strategyTree; private final InMemoryDataTreeSnapshot snapshot; - private final NodeModification rootNode; + private final ModifiedNode rootNode; + + @GuardedBy("this") + private boolean sealed = false; InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final ModificationApplyOperation resolver) { this.snapshot = Preconditions.checkNotNull(snapshot); this.strategyTree = Preconditions.checkNotNull(resolver); - this.rootNode = NodeModification.createUnmodified(snapshot.getRootNode()); + this.rootNode = ModifiedNode.createUnmodified(snapshot.getRootNode()); } - NodeModification getRootModification() { + ModifiedNode getRootModification() { return rootNode; } @@ -56,13 +49,13 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public void write(final InstanceIdentifier path, final NormalizedNode value) { + public synchronized void write(final InstanceIdentifier path, final NormalizedNode value) { checkSealed(); resolveModificationFor(path).write(value); } @Override - public void merge(final InstanceIdentifier path, final NormalizedNode data) { + public synchronized void merge(final InstanceIdentifier path, final NormalizedNode data) { checkSealed(); mergeImpl(resolveModificationFor(path),data); } @@ -81,23 +74,23 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public void delete(final InstanceIdentifier path) { + public synchronized void delete(final InstanceIdentifier path) { checkSealed(); resolveModificationFor(path).delete(); } @Override - public Optional> readNode(final InstanceIdentifier path) { + public synchronized Optional> readNode(final InstanceIdentifier path) { /* * Walk the tree from the top, looking for the first node between root and * the requested path which has been modified. If no such node exists, * we use the node itself. */ - final Entry entry = TreeNodeUtils.findClosestsOrFirstMatch(rootNode, path, NodeModification.IS_TERMINAL_PREDICATE); + final Entry entry = TreeNodeUtils.findClosestsOrFirstMatch(rootNode, path, ModifiedNode.IS_TERMINAL_PREDICATE); final InstanceIdentifier key = entry.getKey(); - final NodeModification mod = entry.getValue(); + final ModifiedNode mod = entry.getValue(); - final Optional result = resolveSnapshot(key, mod); + final Optional result = resolveSnapshot(key, mod); if (result.isPresent()) { NormalizedNode data = result.get().getData(); return NormalizedNodeUtils.findNode(key, data, path); @@ -106,16 +99,16 @@ final class InMemoryDataTreeModification implements DataTreeModification { } } - private Optional resolveSnapshot(final InstanceIdentifier path, - final NodeModification modification) { - final Optional> potentialSnapshot = modification.getSnapshotCache(); + private Optional resolveSnapshot(final InstanceIdentifier path, + final ModifiedNode modification) { + final Optional> potentialSnapshot = modification.getSnapshotCache(); if(potentialSnapshot.isPresent()) { return potentialSnapshot.get(); } try { return resolveModificationStrategy(path).apply(modification, modification.getOriginal(), - StoreUtils.increase(snapshot.getRootNode().getSubtreeVersion())); + snapshot.getRootNode().getSubtreeVersion().next()); } catch (Exception e) { LOG.error("Could not create snapshot for {}:{}", path,modification,e); throw e; @@ -128,7 +121,7 @@ final class InMemoryDataTreeModification implements DataTreeModification { } private OperationWithModification resolveModificationFor(final InstanceIdentifier path) { - NodeModification modification = rootNode; + ModifiedNode modification = rootNode; // We ensure strategy is present. ModificationApplyOperation operation = resolveModificationStrategy(path); for (PathArgument pathArg : path.getPath()) { @@ -138,14 +131,15 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public void seal() { - final boolean success = SEALED_UPDATER.compareAndSet(this, 0, 1); - Preconditions.checkState(success, "Attempted to seal an already-sealed Data Tree."); + public synchronized void seal() { + Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree."); + sealed = true; rootNode.seal(); } + @GuardedBy("this") private void checkSealed() { - checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed."); + Preconditions.checkState(!sealed, "Data Tree is sealed. No further modifications allowed."); } @Override @@ -154,7 +148,9 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public DataTreeModification newModification() { + public synchronized DataTreeModification newModification() { + Preconditions.checkState(sealed, "Attempted to chain on an unsealed modification"); + // FIXME: transaction chaining throw new UnsupportedOperationException("Implement this as part of transaction chaining"); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java index ce2d8c9bd4..ee91e62518 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java @@ -1,6 +1,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeSnapshot; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils; @@ -12,16 +13,16 @@ import com.google.common.base.Preconditions; final class InMemoryDataTreeSnapshot implements DataTreeSnapshot { private final ModificationApplyOperation applyOper; private final SchemaContext schemaContext; - private final StoreMetadataNode rootNode; + private final TreeNode rootNode; - InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final StoreMetadataNode rootNode, + InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final TreeNode rootNode, final ModificationApplyOperation applyOper) { this.schemaContext = Preconditions.checkNotNull(schemaContext); this.rootNode = Preconditions.checkNotNull(rootNode); this.applyOper = Preconditions.checkNotNull(applyOper); } - StoreMetadataNode getRootNode() { + TreeNode getRootNode() { return rootNode; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java index 5b4cd565e5..10f39a8cef 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java @@ -9,15 +9,16 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedLong; /** * - * Operation responsible for applying {@link NodeModification} on tree. + * Operation responsible for applying {@link ModifiedNode} on tree. * * Operation is composite - operation on top level node consists of * suboperations on child nodes. This allows to walk operation hierarchy and @@ -29,7 +30,7 @@ import com.google.common.primitives.UnsignedLong; * Implementations MUST expose all nested suboperations which operates on child * nodes expose via {@link #getChild(PathArgument)} method. *
  • Same suboperations SHOULD be used when invoked via - * {@link #apply(NodeModification, Optional)} if applicable. + * {@link #apply(ModifiedNode, Optional)} if applicable. * * * Hierarchical composite operation which is responsible for applying @@ -54,10 +55,10 @@ interface ModificationApplyOperation extends StoreTreeNode apply(NodeModification modification, Optional storeMeta, UnsignedLong subtreeVersion); + Optional apply(ModifiedNode modification, Optional storeMeta, Version subtreeVersion); /** * @@ -67,7 +68,7 @@ interface ModificationApplyOperation extends StoreTreeNode current) throws DataPreconditionFailedException; + void checkApplicable(InstanceIdentifier path, NodeModification modification, Optional current) throws DataPreconditionFailedException; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModifiedNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModifiedNode.java new file mode 100644 index 0000000000..f83ea1a2de --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModifiedNode.java @@ -0,0 +1,225 @@ +/* + * 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.store.impl.tree.data; + +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.annotation.concurrent.GuardedBy; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; + +/** + * Node Modification Node and Tree + * + * Tree which structurally resembles data tree and captures client modifications + * to the data store tree. + * + * This tree is lazily created and populated via {@link #modifyChild(PathArgument)} + * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}. + */ +final class ModifiedNode implements StoreTreeNode, Identifiable, NodeModification { + + public static final Predicate IS_TERMINAL_PREDICATE = new Predicate() { + @Override + public boolean apply(final ModifiedNode input) { + switch (input.getType()) { + case DELETE: + case MERGE: + case WRITE: + return true; + case SUBTREE_MODIFIED: + case UNMODIFIED: + return false; + } + + throw new IllegalArgumentException(String.format("Unhandled modification type %s", input.getType())); + } + }; + + private final Map children = new LinkedHashMap<>(); + private final Optional original; + private final PathArgument identifier; + private ModificationType modificationType = ModificationType.UNMODIFIED; + private Optional snapshotCache; + private NormalizedNode value; + + private ModifiedNode(final PathArgument identifier, final Optional original) { + this.identifier = identifier; + this.original = original; + } + + /** + * + * + * @return + */ + public NormalizedNode getWrittenValue() { + return value; + } + + @Override + public PathArgument getIdentifier() { + return identifier; + } + + /** + * + * Returns original store metadata + * @return original store metadata + */ + @Override + public Optional getOriginal() { + return original; + } + + /** + * Returns modification type + * + * @return modification type + */ + @Override + public ModificationType getType() { + return modificationType; + } + + /** + * + * Returns child modification if child was modified + * + * @return Child modification if direct child or it's subtree + * was modified. + * + */ + @Override + public Optional getChild(final PathArgument child) { + return Optional. fromNullable(children.get(child)); + } + + /** + * + * Returns child modification if child was modified, creates {@link ModifiedNode} + * for child otherwise. + * + * If this node's {@link ModificationType} is {@link ModificationType#UNMODIFIED} + * changes modification type to {@link ModificationType#SUBTREE_MODIFIED} + * + * @param child + * @return {@link ModifiedNode} for specified child, with {@link #getOriginal()} + * containing child metadata if child was present in original data. + */ + public ModifiedNode modifyChild(final PathArgument child) { + clearSnapshot(); + if (modificationType == ModificationType.UNMODIFIED) { + updateModificationType(ModificationType.SUBTREE_MODIFIED); + } + final ModifiedNode potential = children.get(child); + if (potential != null) { + return potential; + } + + final Optional currentMetadata; + if (original.isPresent()) { + final TreeNode orig = original.get(); + currentMetadata = orig.getChild(child); + } else { + currentMetadata = Optional.absent(); + } + + ModifiedNode newlyCreated = new ModifiedNode(child, currentMetadata); + children.put(child, newlyCreated); + return newlyCreated; + } + + /** + * + * Returns all recorded direct child modification + * + * @return all recorded direct child modifications + */ + @Override + public Iterable getChildren() { + return children.values(); + } + + /** + * + * Records a delete for associated node. + * + */ + public void delete() { + clearSnapshot(); + updateModificationType(ModificationType.DELETE); + children.clear(); + this.value = null; + } + + /** + * + * Records a write for associated node. + * + * @param value + */ + public void write(final NormalizedNode value) { + clearSnapshot(); + updateModificationType(ModificationType.WRITE); + children.clear(); + this.value = value; + } + + public void merge(final NormalizedNode data) { + clearSnapshot(); + updateModificationType(ModificationType.MERGE); + // FIXME: Probably merge with previous value. + this.value = data; + } + + void seal() { + clearSnapshot(); + for (ModifiedNode child : children.values()) { + child.seal(); + } + } + + private void clearSnapshot() { + snapshotCache = null; + } + + public Optional storeSnapshot(final Optional snapshot) { + snapshotCache = snapshot; + return snapshot; + } + + public Optional> getSnapshotCache() { + return Optional.fromNullable(snapshotCache); + } + + @GuardedBy("this") + private void updateModificationType(final ModificationType type) { + modificationType = type; + clearSnapshot(); + } + + @Override + public String toString() { + return "NodeModification [identifier=" + identifier + ", modificationType=" + + modificationType + ", childModification=" + children + "]"; + } + + public static ModifiedNode createUnmodified(final TreeNode metadataTree) { + return new ModifiedNode(metadataTree.getIdentifier(), Optional.of(metadataTree)); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java index f2720b57ae..2639d050ef 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java @@ -7,228 +7,15 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; -import static com.google.common.base.Preconditions.checkState; - -import java.util.LinkedHashMap; -import java.util.Map; - -import javax.annotation.concurrent.GuardedBy; - import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.base.Optional; -import com.google.common.base.Predicate; - -/** - * Node Modification Node and Tree - * - * Tree which structurally resembles data tree and captures client modifications - * to the data store tree. - * - * This tree is lazily created and populated via {@link #modifyChild(PathArgument)} - * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}. - */ -final class NodeModification implements StoreTreeNode, Identifiable { - - public static final Predicate IS_TERMINAL_PREDICATE = new Predicate() { - @Override - public boolean apply(final NodeModification input) { - return input.getModificationType() == ModificationType.WRITE // - || input.getModificationType() == ModificationType.DELETE // - || input.getModificationType() == ModificationType.MERGE; - } - }; - private final PathArgument identifier; - private ModificationType modificationType = ModificationType.UNMODIFIED; - - - private final Optional original; - - private NormalizedNode value; - - private Optional snapshotCache; - - private final Map childModification; - - @GuardedBy("this") - private boolean sealed = false; - - protected NodeModification(final PathArgument identifier, final Optional original) { - this.identifier = identifier; - this.original = original; - childModification = new LinkedHashMap<>(); - } - - /** - * - * - * @return - */ - public NormalizedNode getWrittenValue() { - return value; - } - - @Override - public PathArgument getIdentifier() { - return identifier; - } - - /** - * - * Returns original store metadata - * @return original store metadata - */ - public final Optional getOriginal() { - return original; - } - - /** - * Returns modification type - * - * @return modification type - */ - public final ModificationType getModificationType() { - return modificationType; - } - - /** - * - * Returns child modification if child was modified - * - * @return Child modification if direct child or it's subtree - * was modified. - * - */ - @Override - public Optional getChild(final PathArgument child) { - return Optional. fromNullable(childModification.get(child)); - } - - /** - * - * Returns child modification if child was modified, creates {@link NodeModification} - * for child otherwise. - * - * If this node's {@link ModificationType} is {@link ModificationType#UNMODIFIED} - * changes modification type to {@link ModificationType#SUBTREE_MODIFIED} - * - * @param child - * @return {@link NodeModification} for specified child, with {@link #getOriginal()} - * containing child metadata if child was present in original data. - */ - public synchronized NodeModification modifyChild(final PathArgument child) { - checkSealed(); - clearSnapshot(); - if(modificationType == ModificationType.UNMODIFIED) { - updateModificationType(ModificationType.SUBTREE_MODIFIED); - } - final NodeModification potential = childModification.get(child); - if (potential != null) { - return potential; - } - Optional currentMetadata = Optional.absent(); - if(original.isPresent()) { - currentMetadata = original.get().getChild(child); - } - NodeModification newlyCreated = new NodeModification(child,currentMetadata); - childModification.put(child, newlyCreated); - return newlyCreated; - } - - /** - * - * Returns all recorded direct child modification - * - * @return all recorded direct child modifications - */ - public Iterable getModifications() { - return childModification.values(); - } - - - /** - * - * Records a delete for associated node. - * - */ - public synchronized void delete() { - checkSealed(); - clearSnapshot(); - updateModificationType(ModificationType.DELETE); - childModification.clear(); - this.value = null; - } - - /** - * - * Records a write for associated node. - * - * @param value - */ - public synchronized void write(final NormalizedNode value) { - checkSealed(); - clearSnapshot(); - updateModificationType(ModificationType.WRITE); - childModification.clear(); - this.value = value; - } - - public synchronized void merge(final NormalizedNode data) { - checkSealed(); - clearSnapshot(); - updateModificationType(ModificationType.MERGE); - // FIXME: Probably merge with previous value. - this.value = data; - } - - @GuardedBy("this") - private void checkSealed() { - checkState(!sealed, "Node Modification is sealed. No further changes allowed."); - } - - public synchronized void seal() { - sealed = true; - clearSnapshot(); - for(NodeModification child : childModification.values()) { - child.seal(); - } - } - - private void clearSnapshot() { - snapshotCache = null; - } - - public Optional storeSnapshot(final Optional snapshot) { - snapshotCache = snapshot; - return snapshot; - } - - public Optional> getSnapshotCache() { - return Optional.fromNullable(snapshotCache); - } - - public boolean hasAdditionalModifications() { - return !childModification.isEmpty(); - } - - @GuardedBy("this") - private void updateModificationType(final ModificationType type) { - modificationType = type; - clearSnapshot(); - } - - @Override - public String toString() { - return "NodeModification [identifier=" + identifier + ", modificationType=" - + modificationType + ", childModification=" + childModification + "]"; - } - - public static NodeModification createUnmodified(final StoreMetadataNode metadataTree) { - return new NodeModification(metadataTree.getIdentifier(), Optional.of(metadataTree)); - } +interface NodeModification extends Identifiable { + ModificationType getType(); + Optional getOriginal(); + Iterable getChildren(); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java index 8a46748414..2ef85cbcb7 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java @@ -46,9 +46,9 @@ final class NoopDataTreeCandidate extends AbstractDataTreeCandidate { } }; - protected NoopDataTreeCandidate(final InstanceIdentifier rootPath, final NodeModification modificationRoot) { + protected NoopDataTreeCandidate(final InstanceIdentifier rootPath, final ModifiedNode modificationRoot) { super(rootPath); - Preconditions.checkArgument(modificationRoot.getModificationType() == ModificationType.UNMODIFIED); + Preconditions.checkArgument(modificationRoot.getType() == ModificationType.UNMODIFIED); } @Override diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java index 7ab840e0e0..3a3af5ecab 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java @@ -16,6 +16,10 @@ import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.ListEntryModificationStrategy; import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ValueNodeModificationStrategy.LeafSetEntryModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.MutableTreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; @@ -42,7 +46,7 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; -import com.google.common.primitives.UnsignedLong; +import com.google.common.collect.Iterables; abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareApplyOperation { @@ -53,18 +57,18 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp } @Override - public void verifyStructure(final NodeModification modification) throws IllegalArgumentException { - if (modification.getModificationType() == ModificationType.WRITE) { + public void verifyStructure(final ModifiedNode modification) throws IllegalArgumentException { + if (modification.getType() == ModificationType.WRITE) { } - for (NodeModification childModification : modification.getModifications()) { + for (ModifiedNode childModification : modification.getChildren()) { resolveChildOperation(childModification.getIdentifier()).verifyStructure(childModification); } } @Override protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { + final Optional current) throws DataPreconditionFailedException { // FIXME: Implement proper write check for replacement of node container // prerequisite is to have transaction chain available for clients // otherwise this will break chained writes to same node. @@ -90,94 +94,110 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp } @Override - protected StoreMetadataNode applyWrite(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { - - NormalizedNode newValue = modification.getWrittenValue(); - - final UnsignedLong nodeVersion; + protected TreeNode applyWrite(final ModifiedNode modification, + final Optional currentMeta, final Version subtreeVersion) { + final Version nodeVersion; if (currentMeta.isPresent()) { - nodeVersion = StoreUtils.increase(currentMeta.get().getNodeVersion()); + nodeVersion = currentMeta.get().getVersion().next(); } else { nodeVersion = subtreeVersion; } - final StoreMetadataNode newValueMeta = StoreMetadataNode.createRecursively(newValue, nodeVersion); - if (!modification.hasAdditionalModifications()) { + final NormalizedNode newValue = modification.getWrittenValue(); + final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, nodeVersion); + + if (Iterables.isEmpty(modification.getChildren())) { return newValueMeta; } + /* + * This is where things get interesting. The user has performed a write and + * then she applied some more modifications to it. So we need to make sense + * of that an apply the operations on top of the written value. We could have + * done it during the write, but this operation is potentially expensive, so + * we have left it out of the fast path. + * + * As it turns out, once we materialize the written data, we can share the + * code path with the subtree change. So let's create an unsealed TreeNode + * and run the common parts on it -- which end with the node being sealed. + */ + final MutableTreeNode mutable = newValueMeta.mutable(); + mutable.setSubtreeVersion(subtreeVersion); + @SuppressWarnings("rawtypes") - NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue); - StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.create(nodeVersion, dataBuilder) // - .setSubtreeVersion(subtreeVersion); + final NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue); + + return mutateChildren(mutable, dataBuilder, nodeVersion, modification.getChildren()); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private TreeNode mutateChildren(final MutableTreeNode meta, final NormalizedNodeContainerBuilder data, + final Version nodeVersion, final Iterable modifications) { + + for (ModifiedNode mod : modifications) { + final PathArgument id = mod.getIdentifier(); + final Optional cm = meta.getChild(id); + + Optional result = resolveChildOperation(id).apply(mod, cm, nodeVersion); + if (result.isPresent()) { + final TreeNode tn = result.get(); + meta.addChild(tn); + data.addChild(tn.getData()); + } else { + meta.removeChild(id); + data.removeChild(id); + } + } - return mutateChildren(modification.getModifications(), newValueMeta, builder, nodeVersion); + meta.setData(data.build()); + return meta.seal(); } @Override - protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, - final UnsignedLong subtreeVersion) { + protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, + final Version subtreeVersion) { // For Node Containers - merge is same as subtree change - we only replace children. return applySubtreeChange(modification, currentMeta, subtreeVersion); } @Override - public StoreMetadataNode applySubtreeChange(final NodeModification modification, - final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) { + public TreeNode applySubtreeChange(final ModifiedNode modification, + final TreeNode currentMeta, final Version subtreeVersion) { // Bump subtree version to its new target - final UnsignedLong updatedSubtreeVersion = StoreUtils.increase(currentMeta.getSubtreeVersion()); + final Version updatedSubtreeVersion = currentMeta.getSubtreeVersion().next(); + + final MutableTreeNode newMeta = currentMeta.mutable(); + newMeta.setSubtreeVersion(updatedSubtreeVersion); @SuppressWarnings("rawtypes") NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData()); - StoreNodeCompositeBuilder builder = StoreNodeCompositeBuilder.create(dataBuilder, currentMeta) - .setIdentifier(modification.getIdentifier()) - .setSubtreeVersion(updatedSubtreeVersion); - return mutateChildren(modification.getModifications(), currentMeta, builder, updatedSubtreeVersion); - } - - private StoreMetadataNode mutateChildren(final Iterable modifications, final StoreMetadataNode meta, - final StoreNodeCompositeBuilder builder, final UnsignedLong nodeVersion) { - - for (NodeModification mod : modifications) { - final PathArgument id = mod.getIdentifier(); - final Optional cm = meta.getChild(id); - - Optional result = resolveChildOperation(id).apply(mod, cm, nodeVersion); - if (result.isPresent()) { - builder.add(result.get()); - } else { - builder.remove(id); - } - } - - return builder.build(); + return mutateChildren(newMeta, dataBuilder, updatedSubtreeVersion, modification.getChildren()); } @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { + protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException { checkDataPrecondition(path, current.isPresent(), "Node was deleted by other transaction."); - checkChildPreconditions(path,modification,current); - + checkChildPreconditions(path, modification, current); } - private void checkChildPreconditions(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { - StoreMetadataNode currentMeta = current.get(); - for (NodeModification childMod : modification.getModifications()) { - PathArgument childId = childMod.getIdentifier(); - Optional childMeta = currentMeta.getChild(childId); + private void checkChildPreconditions(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + final TreeNode currentMeta = current.get(); + for (NodeModification childMod : modification.getChildren()) { + final PathArgument childId = childMod.getIdentifier(); + final Optional childMeta = currentMeta.getChild(childId); + InstanceIdentifier childPath = StoreUtils.append(path, childId); - resolveChildOperation(childId).checkApplicable(childPath,childMod, childMeta); + resolveChildOperation(childId).checkApplicable(childPath, childMod, childMeta); } } @Override protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { + final Optional current) throws DataPreconditionFailedException { if(current.isPresent()) { - checkChildPreconditions(path,modification,current); + checkChildPreconditions(path, modification,current); } } @@ -325,4 +345,4 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp return "UnorderedMapModificationStrategy [entry=" + entryStrategy + "]"; } } -} \ No newline at end of file +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java index fda8407a95..ff90d57f49 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java @@ -7,19 +7,20 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedLong; final class OperationWithModification { - private final NodeModification modification; + private final ModifiedNode modification; private final ModificationApplyOperation applyOperation; - private OperationWithModification(final ModificationApplyOperation op, final NodeModification mod) { + private OperationWithModification(final ModificationApplyOperation op, final ModifiedNode mod) { this.modification = mod; this.applyOperation = op; } @@ -35,7 +36,7 @@ final class OperationWithModification { return this; } - public NodeModification getModification() { + public ModifiedNode getModification() { return modification; } @@ -43,12 +44,12 @@ final class OperationWithModification { return applyOperation; } - public Optional apply(final Optional data, final UnsignedLong subtreeVersion) { + public Optional apply(final Optional data, final Version subtreeVersion) { return applyOperation.apply(modification, data, subtreeVersion); } public static OperationWithModification from(final ModificationApplyOperation operation, - final NodeModification modification) { + final ModifiedNode modification) { return new OperationWithModification(operation, modification); } @@ -60,7 +61,7 @@ final class OperationWithModification { } public OperationWithModification forChild(final PathArgument childId) { - NodeModification childMod = modification.modifyChild(childId); + ModifiedNode childMod = modification.modifyChild(childId); Optional childOp = applyOperation.getChild(childId); return from(childOp.get(),childMod); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java index 7afc12caab..bdf5667b67 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java @@ -20,6 +20,9 @@ import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNod import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.OrderedMapModificationStrategy; import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NormalizedNodeContainerModificationStrategy.UnorderedLeafSetModificationStrategy; import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ValueNodeModificationStrategy.LeafModificationStrategy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; @@ -40,7 +43,6 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.primitives.UnsignedLong; abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareApplyOperation.class); @@ -80,6 +82,13 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { return null; } + public static boolean checkDataPrecondition(final InstanceIdentifier path, final boolean condition, final String message) throws DataPreconditionFailedException { + if(!condition) { + throw new DataPreconditionFailedException(path, message); + } + return condition; + } + private static SchemaAwareApplyOperation fromListSchemaNode(final ListSchemaNode schemaNode) { List keyDefinition = schemaNode.getKeyDefinition(); if (keyDefinition == null || keyDefinition.isEmpty()) { @@ -100,9 +109,11 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } } - private static final void checkNotConflicting(final InstanceIdentifier path,final StoreMetadataNode original, final StoreMetadataNode current) throws DataPreconditionFailedException { - checkDataPrecondition(path, original.getNodeVersion().equals(current.getNodeVersion()),"Node was replaced by other transaction."); - checkDataPrecondition(path,original.getSubtreeVersion().equals(current.getSubtreeVersion()), "Node children was modified by other transaction"); + private static final void checkNotConflicting(final InstanceIdentifier path, final TreeNode original, final TreeNode current) throws DataPreconditionFailedException { + checkDataPrecondition(path, original.getVersion().equals(current.getVersion()), + "Node was replaced by other transaction."); + checkDataPrecondition(path, original.getSubtreeVersion().equals(current.getSubtreeVersion()), + "Node children was modified by other transaction"); } protected final ModificationApplyOperation resolveChildOperation(final PathArgument child) { @@ -112,36 +123,36 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } @Override - public void verifyStructure(final NodeModification modification) throws IllegalArgumentException { - if (modification.getModificationType() == ModificationType.WRITE) { + public void verifyStructure(final ModifiedNode modification) throws IllegalArgumentException { + if (modification.getType() == ModificationType.WRITE) { verifyWrittenStructure(modification.getWrittenValue()); } } @Override - public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { - switch (modification.getModificationType()) { + public final void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + switch (modification.getType()) { case DELETE: checkDeleteApplicable(modification, current); case SUBTREE_MODIFIED: - checkSubtreeModificationApplicable(path,modification, current); + checkSubtreeModificationApplicable(path, modification, current); return; case WRITE: - checkWriteApplicable(path,modification, current); + checkWriteApplicable(path, modification, current); return; case MERGE: - checkMergeApplicable(path,modification,current); + checkMergeApplicable(path, modification, current); return; case UNMODIFIED: return; default: - throw new UnsupportedOperationException("Suplied modification type "+modification.getModificationType()+ "is not supported."); + throw new UnsupportedOperationException("Suplied modification type "+ modification.getType()+ "is not supported."); } } - protected void checkMergeApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { - Optional original = modification.getOriginal(); + protected void checkMergeApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + Optional original = modification.getOriginal(); if (original.isPresent() && current.isPresent()) { /* * We need to do conflict detection only and only if the value of leaf changed @@ -150,22 +161,21 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { * leads to same data. */ if(!original.get().getData().equals(current.get().getData())) { - - checkNotConflicting(path,original.get(), current.get()); + checkNotConflicting(path, original.get(), current.get()); } } } - protected void checkWriteApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { - Optional original = modification.getOriginal(); + protected void checkWriteApplicable(final InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException { + Optional original = modification.getOriginal(); if (original.isPresent() && current.isPresent()) { - checkNotConflicting(path,original.get(), current.get()); + checkNotConflicting(path, original.get(), current.get()); } else if(original.isPresent()) { throw new DataPreconditionFailedException(path,"Node was deleted by other transaction."); } } - private void checkDeleteApplicable(final NodeModification modification, final Optional current) { + private void checkDeleteApplicable(final NodeModification modification, final Optional current) { // Delete is always applicable, we do not expose it to subclasses if (current.isPresent()) { LOG.trace("Delete operation turned to no-op on missing node {}", modification); @@ -173,12 +183,12 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } @Override - public final Optional apply(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { + public final Optional apply(final ModifiedNode modification, + final Optional currentMeta, final Version subtreeVersion) { - switch (modification.getModificationType()) { + switch (modification.getType()) { case DELETE: - return modification.storeSnapshot(Optional. absent()); + return modification.storeSnapshot(Optional. absent()); case SUBTREE_MODIFIED: Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification", modification); @@ -197,17 +207,17 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } } - protected abstract StoreMetadataNode applyMerge(NodeModification modification, - StoreMetadataNode currentMeta, UnsignedLong subtreeVersion); + protected abstract TreeNode applyMerge(ModifiedNode modification, + TreeNode currentMeta, Version subtreeVersion); - protected abstract StoreMetadataNode applyWrite(NodeModification modification, - Optional currentMeta, UnsignedLong subtreeVersion); + protected abstract TreeNode applyWrite(ModifiedNode modification, + Optional currentMeta, Version subtreeVersion); - protected abstract StoreMetadataNode applySubtreeChange(NodeModification modification, - StoreMetadataNode currentMeta, UnsignedLong subtreeVersion); + protected abstract TreeNode applySubtreeChange(ModifiedNode modification, + TreeNode currentMeta, Version subtreeVersion); - protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException; + protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException; protected abstract void verifyWrittenStructure(NormalizedNode writtenValue); @@ -220,21 +230,21 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } @Override - protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, - final UnsignedLong subtreeVersion) { + protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, + final Version subtreeVersion) { return applyWrite(modification, Optional.of(currentMeta), subtreeVersion); } @Override - protected StoreMetadataNode applySubtreeChange(final NodeModification modification, - final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) { + protected TreeNode applySubtreeChange(final ModifiedNode modification, + final TreeNode currentMeta, final Version subtreeVersion) { throw new UnsupportedOperationException("UnkeyedList does not support subtree change."); } @Override - protected StoreMetadataNode applyWrite(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { - return StoreMetadataNode.createRecursively(modification.getWrittenValue(), subtreeVersion); + protected TreeNode applyWrite(final ModifiedNode modification, + final Optional currentMeta, final Version subtreeVersion) { + return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion); } @Override @@ -251,17 +261,9 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { + protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException { throw new DataPreconditionFailedException(path, "Subtree modification is not allowed."); } } - - public static boolean checkDataPrecondition(final InstanceIdentifier path, final boolean condition, final String message) throws DataPreconditionFailedException { - if(!condition) { - throw new DataPreconditionFailedException(path, message); - } - return condition; - } - } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java deleted file mode 100644 index 695a1f1dd3..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; - -import static com.google.common.base.Preconditions.checkState; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.opendaylight.yangtools.concepts.Identifiable; -import org.opendaylight.yangtools.concepts.Immutable; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; - -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.primitives.UnsignedLong; - -class StoreMetadataNode implements Immutable, Identifiable { - private final Map children; - private final UnsignedLong nodeVersion; - private final UnsignedLong subtreeVersion; - private final NormalizedNode data; - - /** - * - * @param data - * @param nodeVersion - * @param subtreeVersion - * @param children Map of children, must not be modified externally - */ - private StoreMetadataNode(final NormalizedNode data, final UnsignedLong nodeVersion, - final UnsignedLong subtreeVersion, final Map children) { - this.nodeVersion = Preconditions.checkNotNull(nodeVersion); - this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion); - this.data = Preconditions.checkNotNull(data); - this.children = Preconditions.checkNotNull(children); - } - - public static StoreMetadataNode createEmpty(final NormalizedNode data) { - return new StoreMetadataNode(data, UnsignedLong.ZERO, UnsignedLong.ZERO, - Collections.emptyMap()); - } - - public static Builder builder(final UnsignedLong version) { - return new Builder(version); - } - - public static Builder builder(final StoreMetadataNode node) { - return new Builder(node); - } - - public UnsignedLong getNodeVersion() { - return this.nodeVersion; - } - - @Override - public PathArgument getIdentifier() { - return data.getIdentifier(); - } - - public UnsignedLong getSubtreeVersion() { - return subtreeVersion; - } - - public NormalizedNode getData() { - return this.data; - } - - Optional getChild(final PathArgument key) { - return Optional.fromNullable(children.get(key)); - } - - @Override - public String toString() { - return "StoreMetadataNode [identifier=" + getIdentifier() + ", nodeVersion=" + nodeVersion + "]"; - } - - public static final StoreMetadataNode createRecursively(final NormalizedNode node, - final UnsignedLong version) { - Builder builder = builder(version) // - .setSubtreeVersion(version) // - .setData(node); - if (node instanceof NormalizedNodeContainer) { - - @SuppressWarnings("unchecked") - NormalizedNodeContainer> nodeContainer = (NormalizedNodeContainer>) node; - for (NormalizedNode subNode : nodeContainer.getValue()) { - builder.add(createRecursively(subNode, version)); - } - } - return builder.build(); - } - - public static class Builder { - - private final UnsignedLong nodeVersion; - private UnsignedLong subtreeVersion; - private NormalizedNode data; - private Map children; - private boolean dirty = false; - - private Builder(final UnsignedLong version) { - this.nodeVersion = Preconditions.checkNotNull(version); - children = new HashMap<>(); - } - - private Builder(final StoreMetadataNode node) { - this.nodeVersion = node.getNodeVersion(); - children = new HashMap<>(node.children); - } - - public Builder setSubtreeVersion(final UnsignedLong version) { - this.subtreeVersion = version; - return this; - } - - public Builder setData(final NormalizedNode data) { - this.data = data; - return this; - } - - public Builder add(final StoreMetadataNode node) { - if (dirty) { - children = new HashMap<>(children); - dirty = false; - } - children.put(node.getIdentifier(), node); - return this; - } - - public Builder remove(final PathArgument id) { - if (dirty) { - children = new HashMap<>(children); - dirty = false; - } - children.remove(id); - return this; - } - - public StoreMetadataNode build() { - checkState(data != null, "Data node should not be null."); - checkState(subtreeVersion.compareTo(nodeVersion) >= 0, - "Subtree version must be equals or greater than node version."); - dirty = true; - return new StoreMetadataNode(data, nodeVersion, subtreeVersion, children); - } - } - -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java deleted file mode 100644 index 19debbb990..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; -import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder; - -import com.google.common.base.Preconditions; -import com.google.common.primitives.UnsignedLong; - -/** - * - * Helper builder - * - * - */ -@SuppressWarnings("rawtypes") -class StoreNodeCompositeBuilder { - - private final StoreMetadataNode.Builder metadata; - - private final NormalizedNodeContainerBuilder data; - - private StoreNodeCompositeBuilder(final UnsignedLong version, final NormalizedNodeContainerBuilder nodeBuilder) { - this.metadata = StoreMetadataNode.builder(version); - this.data = Preconditions.checkNotNull(nodeBuilder); - } - - private StoreNodeCompositeBuilder(final NormalizedNodeContainerBuilder nodeBuilder, final StoreMetadataNode currentMeta) { - this.metadata = StoreMetadataNode.builder(currentMeta); - this.data = Preconditions.checkNotNull(nodeBuilder); - } - - @SuppressWarnings("unchecked") - public StoreNodeCompositeBuilder add(final StoreMetadataNode node) { - metadata.add(node); - data.addChild(node.getData()); - return this; - } - - @SuppressWarnings("unchecked") - public StoreNodeCompositeBuilder remove(final PathArgument id) { - metadata.remove(id); - data.removeChild(id); - return this; - } - - public StoreMetadataNode build() { - return metadata.setData(data.build()).build(); - } - - public static StoreNodeCompositeBuilder create(final UnsignedLong version, final NormalizedNodeContainerBuilder nodeBuilder) { - return new StoreNodeCompositeBuilder(version, nodeBuilder); - } - - public static StoreNodeCompositeBuilder create(final NormalizedNodeContainerBuilder nodeBuilder, final StoreMetadataNode currentMeta) { - return new StoreNodeCompositeBuilder(nodeBuilder, currentMeta); - } - - @SuppressWarnings("unchecked") - public StoreNodeCompositeBuilder setIdentifier(final PathArgument identifier) { - data.withNodeIdentifier(identifier); - return this; - } - - public StoreNodeCompositeBuilder setSubtreeVersion(final UnsignedLong updatedSubtreeVersion) { - metadata.setSubtreeVersion(updatedSubtreeVersion); - return this; - } -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java index 2892953935..5f68782a2e 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java @@ -4,82 +4,85 @@ * 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.store.impl.tree.data; + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; - import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkArgument; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; - import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; - import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; - import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; - import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; - import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; - import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; - import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; - import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import com.google.common.base.Optional; - import com.google.common.primitives.UnsignedLong; - abstract class ValueNodeModificationStrategy extends SchemaAwareApplyOperation { +abstract class ValueNodeModificationStrategy extends SchemaAwareApplyOperation { - private final T schema; - private final Class> nodeClass; + private final T schema; + private final Class> nodeClass; - protected ValueNodeModificationStrategy(final T schema, final Class> nodeClass) { - super(); - this.schema = schema; - this.nodeClass = nodeClass; - } + protected ValueNodeModificationStrategy(final T schema, final Class> nodeClass) { + super(); + this.schema = schema; + this.nodeClass = nodeClass; + } - @Override - protected void verifyWrittenStructure(final NormalizedNode writtenValue) { - checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass); - } + @Override + protected void verifyWrittenStructure(final NormalizedNode writtenValue) { + checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass); + } - @Override - public Optional getChild(final PathArgument child) { - throw new UnsupportedOperationException("Node " + schema.getPath() - + "is leaf type node. Child nodes not allowed"); - } + @Override + public Optional getChild(final PathArgument child) { + throw new UnsupportedOperationException("Node " + schema.getPath() + + "is leaf type node. Child nodes not allowed"); + } - @Override - protected StoreMetadataNode applySubtreeChange(final NodeModification modification, - final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) { - throw new UnsupportedOperationException("Node " + schema.getPath() - + "is leaf type node. Subtree change is not allowed."); - } + @Override + protected TreeNode applySubtreeChange(final ModifiedNode modification, + final TreeNode currentMeta, final Version subtreeVersion) { + throw new UnsupportedOperationException("Node " + schema.getPath() + + "is leaf type node. Subtree change is not allowed."); + } - @Override - protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta, - final UnsignedLong subtreeVersion) { - return applyWrite(modification, Optional.of(currentMeta), subtreeVersion); - } + @Override + protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, + final Version subtreeVersion) { + // Just overwrite whatever was there + return applyWrite(modification, null, subtreeVersion); + } - @Override - protected StoreMetadataNode applyWrite(final NodeModification modification, - final Optional currentMeta, final UnsignedLong subtreeVersion) { - return StoreMetadataNode.builder(subtreeVersion).setSubtreeVersion(subtreeVersion) - .setData(modification.getWrittenValue()).build(); - } + @Override + protected TreeNode applyWrite(final ModifiedNode modification, + final Optional currentMeta, final Version subtreeVersion) { + return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion); + } - @Override - protected void checkSubtreeModificationApplicable(final InstanceIdentifier path,final NodeModification modification, - final Optional current) throws DataPreconditionFailedException { - throw new DataPreconditionFailedException(path, "Subtree modification is not allowed."); - } + @Override + protected void checkSubtreeModificationApplicable(final InstanceIdentifier path, final NodeModification modification, + final Optional current) throws DataPreconditionFailedException { + throw new DataPreconditionFailedException(path, "Subtree modification is not allowed."); + } - public static class LeafSetEntryModificationStrategy extends ValueNodeModificationStrategy { - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected LeafSetEntryModificationStrategy(final LeafListSchemaNode schema) { - super(schema, (Class) LeafSetEntryNode.class); - } - } + public static class LeafSetEntryModificationStrategy extends ValueNodeModificationStrategy { + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected LeafSetEntryModificationStrategy(final LeafListSchemaNode schema) { + super(schema, (Class) LeafSetEntryNode.class); + } + } - public static class LeafModificationStrategy extends ValueNodeModificationStrategy { - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected LeafModificationStrategy(final LeafSchemaNode schema) { - super(schema, (Class) LeafNode.class); - } - } - } \ No newline at end of file + public static class LeafModificationStrategy extends ValueNodeModificationStrategy { + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected LeafModificationStrategy(final LeafSchemaNode schema) { + super(schema, (Class) LeafNode.class); + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java new file mode 100644 index 0000000000..1444f0c6a8 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java @@ -0,0 +1,41 @@ +/* + * 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.store.impl.tree.spi; + +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +import com.google.common.base.Preconditions; + +/* + * A very basic data tree node. + */ +abstract class AbstractTreeNode implements TreeNode { + private final NormalizedNode data; + private final Version version; + + protected AbstractTreeNode(final NormalizedNode data, final Version version) { + this.data = Preconditions.checkNotNull(data); + this.version = Preconditions.checkNotNull(version); + } + + @Override + public PathArgument getIdentifier() { + return data.getIdentifier(); + } + + @Override + public final Version getVersion() { + return version; + } + + @Override + public final NormalizedNode getData() { + return data; + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java new file mode 100644 index 0000000000..8f74f60498 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java @@ -0,0 +1,122 @@ +/* + * 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.store.impl.tree.spi; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; +import org.opendaylight.yangtools.yang.data.api.schema.OrderedNodeContainer; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; + +/** + * A TreeNode capable of holding child nodes. The fact that any of the children + * changed is tracked by the subtree version. + */ +final class ContainerNode extends AbstractTreeNode { + private final Map children; + private final Version subtreeVersion; + + protected ContainerNode(final NormalizedNode data, final Version version, + final Map children, final Version subtreeVersion) { + super(data, version); + this.children = Preconditions.checkNotNull(children); + this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion); + } + + @Override + public Version getSubtreeVersion() { + return subtreeVersion; + } + + @Override + public Optional getChild(final PathArgument key) { + return Optional.fromNullable(children.get(key)); + } + + @Override + public MutableTreeNode mutable() { + return new Mutable(this); + } + + private static final class Mutable implements MutableTreeNode { + private final Map children; + private final Version version; + private NormalizedNode data; + private Version subtreeVersion; + + private Mutable(final ContainerNode parent) { + this.data = parent.getData(); + this.children = new HashMap<>(parent.children); + this.subtreeVersion = parent.getSubtreeVersion(); + this.version = parent.getVersion(); + } + + @Override + public Optional getChild(final PathArgument child) { + return Optional.fromNullable(children.get(child)); + } + + @Override + public void setSubtreeVersion(final Version subtreeVersion) { + this.subtreeVersion = Preconditions.checkNotNull(subtreeVersion); + } + + @Override + public void addChild(final TreeNode child) { + children.put(child.getIdentifier(), child); + } + + @Override + public void removeChild(final PathArgument id) { + children.remove(id); + } + + @Override + public TreeNode seal() { + final Map realChildren; + + if (children.isEmpty()) { + realChildren = Collections.emptyMap(); + } else { + realChildren = children; + } + + return new ContainerNode(data, version, realChildren, subtreeVersion); + } + + @Override + public void setData(final NormalizedNode data) { + this.data = Preconditions.checkNotNull(data); + } + } + + private static ContainerNode create(final Version version, final NormalizedNode data, + final Iterable> children) { + final Map map = new HashMap<>(); + + for (NormalizedNode child : children) { + map.put(child.getIdentifier(), TreeNodeFactory.createTreeNode(child, version)); + } + + return new ContainerNode(data, version, map, version); + } + + public static ContainerNode create(final Version version, final NormalizedNodeContainer> container) { + return create(version, container, container.getValue()); + } + + public static ContainerNode create(final Version version, final OrderedNodeContainer> container) { + return create(version, container, container.getValue()); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java new file mode 100644 index 0000000000..dd3672cf11 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.spi; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +public interface MutableTreeNode extends StoreTreeNode { + void setData(NormalizedNode data); + void setSubtreeVersion(Version subtreeVersion); + void addChild(TreeNode child); + void removeChild(PathArgument id); + TreeNode seal(); +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java new file mode 100644 index 0000000000..b0beb8168b --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java @@ -0,0 +1,48 @@ +/* + * 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.store.impl.tree.spi; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; +import org.opendaylight.yangtools.concepts.Identifiable; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +/* + * A very basic data tree node. It has a version (when it was last modified), + * a subtree version (when any of its children were modified) and some read-only + * data. + */ +public interface TreeNode extends Identifiable, StoreTreeNode { + /** + * Get the data node version. + * + * @return Current data node version. + */ + Version getVersion(); + + /** + * Get the subtree version. + * + * @return Current subtree version. + */ + Version getSubtreeVersion(); + + /** + * Get a read-only view of the underlying data. + * + * @return Unmodifiable view of the underlying data. + */ + NormalizedNode getData(); + + /** + * Get a mutable, isolated copy of the node. + * + * @return Mutable copy + */ + MutableTreeNode mutable(); +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java new file mode 100644 index 0000000000..c5d174caad --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java @@ -0,0 +1,42 @@ +/* + * 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.store.impl.tree.spi; + +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; +import org.opendaylight.yangtools.yang.data.api.schema.OrderedNodeContainer; + +public final class TreeNodeFactory { + private TreeNodeFactory() { + throw new UnsupportedOperationException("Utility class should not be instantiated"); + } + + /** + * Create a new AbstractTreeNode from a data node, descending recursively as needed. + * This method should only ever be used for new data. + * + * @param data data node + * @param version data node version + * @return new AbstractTreeNode instance, covering the data tree provided + */ + public static final TreeNode createTreeNode(final NormalizedNode data, final Version version) { + if (data instanceof NormalizedNodeContainer) { + @SuppressWarnings("unchecked") + NormalizedNodeContainer> container = (NormalizedNodeContainer>) data; + return ContainerNode.create(version, container); + + } + if (data instanceof OrderedNodeContainer) { + @SuppressWarnings("unchecked") + OrderedNodeContainer> container = (OrderedNodeContainer>) data; + return ContainerNode.create(version, container); + } + + return new ValueNode(data, version); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java new file mode 100644 index 0000000000..7194faadf6 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java @@ -0,0 +1,43 @@ +/* + * 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.store.impl.tree.spi; + +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Optional; + +final class ValueNode extends AbstractTreeNode { + private static final Logger LOG = LoggerFactory.getLogger(ValueNode.class); + + protected ValueNode(final NormalizedNode data, final Version version) { + super(data, version); + } + + @Override + public Optional getChild(final PathArgument childId) { + LOG.warn("Attempted to access child {} of value-node {}", childId, this); + return Optional.absent(); + } + + @Override + public Version getSubtreeVersion() { + return getVersion(); + } + + @Override + public MutableTreeNode mutable() { + /** + * Value nodes can only we read/written/delete, which does a straight + * replace. That means they don't haver need to be made mutable. + */ + throw new UnsupportedOperationException(String.format("Attempted to mutate value-node %s", this)); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/Version.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/Version.java new file mode 100644 index 0000000000..09a35d3b1a --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/Version.java @@ -0,0 +1,37 @@ +/* + * 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.store.impl.tree.spi; + +/** + * The concept of a version, either node version, or a subtree version. The + * only interface contract this class has is that no two versions are the + * same. + */ +public final class Version { + private Version() { + + } + + /** + * Create a new version, distinct from any other version. + * + * @return a new version. + */ + public Version next() { + return new Version(); + } + + /** + * Create an initial version. + * + * @return a new version. + */ + public static final Version initial() { + return new Version(); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/GlobalBundleScanningSchemaServiceImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/GlobalBundleScanningSchemaServiceImpl.java index dab8fd5cd1..430963a884 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/GlobalBundleScanningSchemaServiceImpl.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/GlobalBundleScanningSchemaServiceImpl.java @@ -10,7 +10,10 @@ package org.opendaylight.controller.sal.dom.broker; import static com.google.common.base.Preconditions.checkState; import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; +import java.util.List; import org.opendaylight.controller.sal.core.api.model.SchemaService; import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider; @@ -33,54 +36,34 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Optional; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSet.Builder; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; -public class GlobalBundleScanningSchemaServiceImpl implements // - SchemaContextProvider, // - SchemaService, // - ServiceTrackerCustomizer, // - AutoCloseable { - private static final Logger logger = LoggerFactory.getLogger(GlobalBundleScanningSchemaServiceImpl.class); - - private ListenerRegistry listeners; - - private BundleContext context; - private final BundleScanner scanner = new BundleScanner(); - - private BundleTracker>> bundleTracker; +public class GlobalBundleScanningSchemaServiceImpl implements SchemaContextProvider, SchemaService, ServiceTrackerCustomizer, AutoCloseable { + private static final Logger LOG = LoggerFactory.getLogger(GlobalBundleScanningSchemaServiceImpl.class); + private final ListenerRegistry listeners = new ListenerRegistry<>(); private final URLSchemaContextResolver contextResolver = new URLSchemaContextResolver(); + private final BundleScanner scanner = new BundleScanner(); + private final BundleContext context; private ServiceTracker listenerTracker; - + private BundleTracker>> bundleTracker; private boolean starting = true; - public ListenerRegistry getListeners() { - return listeners; - } - - public void setListeners(final ListenerRegistry listeners) { - this.listeners = listeners; + public GlobalBundleScanningSchemaServiceImpl(final BundleContext context) { + this.context = Preconditions.checkNotNull(context); } public BundleContext getContext() { return context; } - public void setContext(final BundleContext context) { - this.context = context; - } - public void start() { checkState(context != null); - if (listeners == null) { - listeners = new ListenerRegistry<>(); - } listenerTracker = new ServiceTracker<>(context, SchemaServiceListener.class, GlobalBundleScanningSchemaServiceImpl.this); - bundleTracker = new BundleTracker>>(context, BundleEvent.RESOLVED - | BundleEvent.UNRESOLVED, scanner); + bundleTracker = new BundleTracker<>(context, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, scanner); bundleTracker.open(); listenerTracker.open(); starting = false; @@ -139,7 +122,7 @@ public class GlobalBundleScanningSchemaServiceImpl implements // try { listener.getInstance().onGlobalContextUpdated(snapshot); } catch (Exception e) { - logger.error("Exception occured during invoking listener", e); + LOG.error("Exception occured during invoking listener", e); } } if (services != null) { @@ -148,37 +131,47 @@ public class GlobalBundleScanningSchemaServiceImpl implements // try { listener.onGlobalContextUpdated(snapshot); } catch (Exception e) { - logger.error("Exception occured during invoking listener", e); + LOG.error("Exception occured during invoking listener {}", listener, e); } } } } - private class BundleScanner implements BundleTrackerCustomizer>> { + private class BundleScanner implements BundleTrackerCustomizer>> { @Override - public ImmutableSet> addingBundle(final Bundle bundle, final BundleEvent event) { + public Iterable> addingBundle(final Bundle bundle, final BundleEvent event) { if (bundle.getBundleId() == 0) { - return ImmutableSet.of(); + return Collections.emptyList(); } - Enumeration enumeration = bundle.findEntries("META-INF/yang", "*.yang", false); - Builder> builder = ImmutableSet.> builder(); - while (enumeration != null && enumeration.hasMoreElements()) { - Registration reg = contextResolver.registerSource(enumeration.nextElement()); - builder.add(reg); + final Enumeration enumeration = bundle.findEntries("META-INF/yang", "*.yang", false); + if (enumeration == null) { + return Collections.emptyList(); } - ImmutableSet> urls = builder.build(); - if(urls.isEmpty()) { - return urls; + + final List> urls = new ArrayList<>(); + while (enumeration.hasMoreElements()) { + final URL u = enumeration.nextElement(); + try { + urls.add(contextResolver.registerSource(u)); + LOG.debug("Registered {}", u); + } catch (Exception e) { + LOG.warn("Failed to register {}, ignoring it", e); + } } - tryToUpdateSchemaContext(); - return urls; + + if (!urls.isEmpty()) { + LOG.debug("Loaded {} new URLs, rebuilding schema context", urls.size()); + tryToUpdateSchemaContext(); + } + + return ImmutableList.copyOf(urls); } @Override - public void modifiedBundle(final Bundle bundle, final BundleEvent event, final ImmutableSet> object) { - logger.debug("Modified bundle {} {} {}", bundle, event, object); + public void modifiedBundle(final Bundle bundle, final BundleEvent event, final Iterable> object) { + LOG.debug("Modified bundle {} {} {}", bundle, event, object); } /** @@ -188,12 +181,12 @@ public class GlobalBundleScanningSchemaServiceImpl implements // */ @Override - public synchronized void removedBundle(final Bundle bundle, final BundleEvent event, final ImmutableSet> urls) { + public synchronized void removedBundle(final Bundle bundle, final BundleEvent event, final Iterable> urls) { for (Registration url : urls) { try { url.close(); } catch (Exception e) { - e.printStackTrace(); + LOG.warn("Failed do unregister URL {}, proceeding", url, e); } } tryToUpdateSchemaContext(); @@ -212,7 +205,7 @@ public class GlobalBundleScanningSchemaServiceImpl implements // } public synchronized void tryToUpdateSchemaContext() { - if(starting ) { + if (starting) { return; } Optional schema = contextResolver.tryToUpdateSchemaContext(); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java index d8315568be..1a572d157d 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaAwareDataStoreAdapter.java @@ -45,9 +45,9 @@ import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableSet; public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator implements // - DataStore, // - SchemaContextListener, // - AutoCloseable { +DataStore, // +SchemaContextListener, // +AutoCloseable { private final static Logger LOG = LoggerFactory.getLogger(SchemaAwareDataStoreAdapter.class); @@ -56,7 +56,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator reader = new MergeFirstLevelReader(); @Override - public boolean containsConfigurationPath(InstanceIdentifier path) { + public boolean containsConfigurationPath(final InstanceIdentifier path) { try { getDelegateReadLock().lock(); return getDelegate().containsConfigurationPath(path); @@ -67,7 +67,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator requestCommit( - DataModification modification) { + final DataModification modification) { validateAgainstSchema(modification); NormalizedDataModification cleanedUp = prepareMergedTransaction(modification); cleanedUp.status = TransactionStatus.SUBMITED; @@ -122,11 +122,11 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator modification) { + private void validateAgainstSchema(final DataModification modification) { if (!validationEnabled) { return; } @@ -138,12 +138,12 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator original) { + final DataModification original) { NormalizedDataModification normalized = new NormalizedDataModification(original); LOG.trace("Transaction: {} Removed Configuration {}, Removed Operational {}", original.getIdentifier(), original.getRemovedConfigurationData(), original.getRemovedConfigurationData()); @@ -194,7 +194,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator getConfigurationSubpaths(InstanceIdentifier entry) { + private Iterable getConfigurationSubpaths(final InstanceIdentifier entry) { // FIXME: This should be replaced by index Iterable paths = getStoredConfigurationPaths(); @@ -202,15 +202,15 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator getOperationalSubpaths(InstanceIdentifier entry) { + public Iterable getOperationalSubpaths(final InstanceIdentifier entry) { // FIXME: This should be indexed Iterable paths = getStoredOperationalPaths(); return getChildrenPaths(entry, paths); } - private static final Iterable getChildrenPaths(InstanceIdentifier entry, - Iterable paths) { + private static final Iterable getChildrenPaths(final InstanceIdentifier entry, + final Iterable paths) { ImmutableSet.Builder children = ImmutableSet.builder(); for (InstanceIdentifier potential : paths) { if (entry.contains(potential)) { @@ -222,7 +222,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator> preparationComparator = new Comparator>() { @Override - public int compare(Entry o1, Entry o2) { + public int compare(final Entry o1, final Entry o2) { InstanceIdentifier o1Key = o1.getKey(); InstanceIdentifier o2Key = o2.getKey(); return Integer.compare(o1Key.getPath().size(), o2Key.getPath().size()); @@ -242,7 +242,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator> childNodes = new ArrayList>(); if (original != null) { - childNodes.addAll(original.getChildren()); + childNodes.addAll(original.getValue()); qname = original.getNodeType(); } else { qname = path.getPath().get(path.getPath().size() - 1).getNodeType(); @@ -251,7 +251,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator directChildren = FluentIterable.from(getStoredConfigurationPaths()) .filter(new Predicate() { @Override - public boolean apply(InstanceIdentifier input) { + public boolean apply(final InstanceIdentifier input) { if (path.contains(input)) { int nesting = input.getPath().size() - path.getPath().size(); if (nesting == 1) { @@ -285,7 +285,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator> childNodes = new ArrayList>(); if (original != null) { - childNodes.addAll(original.getChildren()); + childNodes.addAll(original.getValue()); qname = original.getNodeType(); } else { qname = path.getPath().get(path.getPath().size() - 1).getNodeType(); @@ -294,7 +294,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator directChildren = FluentIterable.from(getStoredOperationalPaths()) .filter(new Predicate() { @Override - public boolean apply(InstanceIdentifier input) { + public boolean apply(final InstanceIdentifier input) { if (path.contains(input)) { int nesting = input.getPath().size() - path.getPath().size(); if (nesting == 1) { @@ -326,7 +326,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator original) { + public NormalizedDataModification(final DataModification original) { super(getDelegate()); identifier = original; status = TransactionStatus.NEW; @@ -339,7 +339,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator paths = getOperationalSubpaths(entry); removeOperationalData(entry); for (InstanceIdentifier potential : paths) { @@ -347,7 +347,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator paths = getConfigurationSubpaths(entry); removeConfigurationData(entry); for (InstanceIdentifier potential : paths) { @@ -355,11 +355,11 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator child : entryData.getChildren()) { + for (Node child : entryData.getValue()) { InstanceIdentifier subEntryId = InstanceIdentifier.builder(entryKey).node(child.getNodeType()) .toInstance(); if (child instanceof CompositeNode) { @@ -438,7 +438,7 @@ public class SchemaAwareDataStoreAdapter extends AbstractLockableDelegator getValuesFromListSchema(ListSchemaNode listSchema, CompositeNode entryData) { + private Map getValuesFromListSchema(final ListSchemaNode listSchema, final CompositeNode entryData) { List keyDef = listSchema.getKeyDefinition(); if (keyDef != null && !keyDef.isEmpty()) { Map map = new HashMap(); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/SchemaServiceActivator.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/SchemaServiceActivator.java index 344b3f3276..f893f96d18 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/SchemaServiceActivator.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/SchemaServiceActivator.java @@ -17,20 +17,19 @@ import org.osgi.framework.ServiceRegistration; public class SchemaServiceActivator implements BundleActivator { - + private ServiceRegistration schemaServiceReg; private GlobalBundleScanningSchemaServiceImpl schemaService; @Override - public void start(BundleContext context) throws Exception { - schemaService = new GlobalBundleScanningSchemaServiceImpl(); - schemaService.setContext(context); + public void start(final BundleContext context) { + schemaService = new GlobalBundleScanningSchemaServiceImpl(context); schemaService.start(); schemaServiceReg = context.registerService(SchemaService.class, schemaService, new Hashtable()); } - + @Override - public void stop(BundleContext context) throws Exception { + public void stop(final BundleContext context) throws Exception { schemaServiceReg.unregister(); schemaService.close(); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java index 8940e55d32..4fb190fc82 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java +++ b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java @@ -29,6 +29,8 @@ import org.junit.Test; import org.opendaylight.controller.md.sal.dom.store.impl.TestModel; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; @@ -40,7 +42,6 @@ import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableCo import org.opendaylight.yangtools.yang.model.api.SchemaContext; import com.google.common.base.Optional; -import com.google.common.primitives.UnsignedLong; /** * @@ -149,7 +150,7 @@ public class ModificationMetadataTreeTest { @Test public void basicReadWrites() { DataTreeModification modificationTree = new InMemoryDataTreeModification(new InMemoryDataTreeSnapshot(schemaContext, - StoreMetadataNode.createRecursively(createDocumentOne(), UnsignedLong.valueOf(5)), applyOper), + TreeNodeFactory.createTreeNode(createDocumentOne(), Version.initial()), applyOper), new SchemaAwareApplyOperationRoot(schemaContext)); Optional> originalBarNode = modificationTree.readNode(OUTER_LIST_2_PATH); assertTrue(originalBarNode.isPresent()); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java index 8a74b17ac4..34cd9aa47b 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceTwoPhaseCommitTransaction.java @@ -35,7 +35,6 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifie import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.Node; import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; -import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl; import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,9 +51,9 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction modification, - boolean candidateSupported, boolean rollbackOnErrorSupported) { + public NetconfDeviceTwoPhaseCommitTransaction(final NetconfDevice device, + final DataModification modification, + final boolean candidateSupported, final boolean rollbackOnErrorSupported) { this.device = Preconditions.checkNotNull(device); this.modification = Preconditions.checkNotNull(modification); this.candidateSupported = candidateSupported; @@ -70,15 +69,15 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransactionabsent(), Optional.of(value))); } - private void sendDelete(InstanceIdentifier toDelete) throws InterruptedException, ExecutionException { + private void sendDelete(final InstanceIdentifier toDelete) throws InterruptedException, ExecutionException { sendEditRpc(createEditStructure(toDelete, Optional.of("delete"), Optional. absent())); } - private void sendEditRpc(CompositeNode editStructure) throws InterruptedException, ExecutionException { + private void sendEditRpc(final CompositeNode editStructure) throws InterruptedException, ExecutionException { CompositeNodeBuilder builder = configurationRpcBuilder(); builder.setQName(NETCONF_EDIT_CONFIG_QNAME); builder.add(editStructure); @@ -108,8 +107,8 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction operation, - Optional lastChildOverride) { + private CompositeNode createEditStructure(final InstanceIdentifier dataPath, final Optional operation, + final Optional lastChildOverride) { List path = dataPath.getPath(); List reversed = Lists.reverse(path); CompositeNode previous = null; @@ -130,7 +129,7 @@ class NetconfDeviceTwoPhaseCommitTransaction implements DataCommitTransaction> children = lastChildOverride.get().getChildren(); + List> children = lastChildOverride.get().getValue(); for(Node child : children) { if(!predicates.containsKey(child.getKey())) { builder.add(child); diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java index f76ec28624..2b3a992fc1 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.java @@ -7,12 +7,6 @@ */ package org.opendaylight.controller.sal.connect.netconf; -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; import java.net.URI; import java.util.ArrayList; import java.util.Collections; @@ -20,8 +14,10 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; + import javax.activation.UnsupportedDataTypeException; import javax.annotation.Nullable; + import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfMessage; import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil; @@ -41,11 +37,16 @@ import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl; import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils; import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder; import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; -import org.opendaylight.yangtools.yang.model.api.RpcDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.w3c.dom.Document; import org.w3c.dom.Element; +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + public class NetconfMapping { public static URI NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0"); @@ -91,7 +92,7 @@ public class NetconfMapping { static AtomicInteger messageId = new AtomicInteger(0); - static Node toFilterStructure(InstanceIdentifier identifier) { + static Node toFilterStructure(final InstanceIdentifier identifier) { Node previous = null; if (identifier.getPath().isEmpty()) { return null; @@ -108,7 +109,7 @@ public class NetconfMapping { return filter("subtree", previous); } - static Node toNode(NodeIdentifierWithPredicates argument, Node node) { + static Node toNode(final NodeIdentifierWithPredicates argument, final Node node) { List> list = new ArrayList<>(); for (Map.Entry arg : argument.getKeyValues().entrySet()) { list.add(new SimpleNodeTOImpl(arg.getKey(), null, arg.getValue())); @@ -119,7 +120,7 @@ public class NetconfMapping { return new CompositeNodeTOImpl(argument.getNodeType(), null, list); } - static Node toNode(PathArgument argument, Node node) { + static Node toNode(final PathArgument argument, final Node node) { if (node != null) { return new CompositeNodeTOImpl(argument.getNodeType(), null, Collections.> singletonList(node)); } else { @@ -127,14 +128,14 @@ public class NetconfMapping { } } - static CompositeNode toCompositeNode(NetconfMessage message, Optional ctx) { + static CompositeNode toCompositeNode(final NetconfMessage message, final Optional ctx) { // TODO: implement general normalization to normalize incoming Netconf // Message // for Schema Context counterpart return null; } - static CompositeNode toNotificationNode(NetconfMessage message, Optional ctx) { + static CompositeNode toNotificationNode(final NetconfMessage message, final Optional ctx) { if (ctx.isPresent()) { SchemaContext schemaContext = ctx.get(); Set notifications = schemaContext.getNotifications(); @@ -144,7 +145,7 @@ public class NetconfMapping { return null; } - static NetconfMessage toRpcMessage(QName rpc, CompositeNode node, Optional ctx) { + static NetconfMessage toRpcMessage(final QName rpc, final CompositeNode node, final Optional ctx) { CompositeNodeTOImpl rpcPayload = wrap(NETCONF_RPC_QNAME, flattenInput(node)); Document w3cPayload = null; try { @@ -164,8 +165,8 @@ public class NetconfMapping { if (input instanceof CompositeNode) { List> nodes = ImmutableList.> builder() // - .addAll(input.getChildren()) // - .addAll(Collections2.filter(node.getChildren(), new Predicate>() { + .addAll(input.getValue()) // + .addAll(Collections2.filter(node.getValue(), new Predicate>() { @Override public boolean apply(@Nullable final Node input) { return input.getNodeType() != inputQName; @@ -179,7 +180,7 @@ public class NetconfMapping { return input; } - static RpcResult toRpcResult(NetconfMessage message, final QName rpc, Optional context) { + static RpcResult toRpcResult(final NetconfMessage message, final QName rpc, final Optional context) { CompositeNode rawRpc; if (context.isPresent()) if (isDataRetrieQNameReply(rpc)) { @@ -196,7 +197,7 @@ public class NetconfMapping { rawRpc = it.toInstance(); // sys(xmlData) } else { - rawRpc = (CompositeNode) toCompositeNode(message, context); + rawRpc = toCompositeNode(message, context); } else { rawRpc = (CompositeNode) toCompositeNode(message.getDocument()); @@ -205,17 +206,17 @@ public class NetconfMapping { return Rpcs.getRpcResult(true, rawRpc, Collections. emptySet()); } - static Element getDataSubtree(Document doc) { + static Element getDataSubtree(final Document doc) { return (Element) doc.getElementsByTagNameNS(NETCONF_URI.toString(), "data").item(0); } - static boolean isDataRetrieQNameReply(QName it) { + static boolean isDataRetrieQNameReply(final QName it) { return NETCONF_URI == it.getNamespace() && (it.getLocalName() == NETCONF_GET_CONFIG_QNAME.getLocalName() || it.getLocalName() == NETCONF_GET_QNAME - .getLocalName()); + .getLocalName()); } - static CompositeNodeTOImpl wrap(QName name, Node node) { + static CompositeNodeTOImpl wrap(final QName name, final Node node) { if (node != null) { return new CompositeNodeTOImpl(name, null, Collections.> singletonList(node)); } else { @@ -223,7 +224,7 @@ public class NetconfMapping { } } - static CompositeNodeTOImpl wrap(QName name, Node additional, Node node) { + static CompositeNodeTOImpl wrap(final QName name, final Node additional, final Node node) { if (node != null) { return new CompositeNodeTOImpl(name, null, ImmutableList.of(additional, node)); } else { @@ -231,7 +232,7 @@ public class NetconfMapping { } } - static ImmutableCompositeNode filter(String type, Node node) { + static ImmutableCompositeNode filter(final String type, final Node node) { CompositeNodeBuilder it = ImmutableCompositeNode.builder(); // it.setQName(NETCONF_FILTER_QNAME); it.setAttribute(NETCONF_TYPE_QNAME, type); @@ -242,11 +243,11 @@ public class NetconfMapping { } } - public static Node toCompositeNode(Document document) { + public static Node toCompositeNode(final Document document) { return XmlDocumentUtils.toDomNode(document); } - public static void checkValidReply(NetconfMessage input, NetconfMessage output) { + public static void checkValidReply(final NetconfMessage input, final NetconfMessage output) { String inputMsgId = input.getDocument().getDocumentElement().getAttribute("message-id"); String outputMsgId = output.getDocument().getDocumentElement().getAttribute("message-id"); @@ -257,7 +258,7 @@ public class NetconfMapping { } } - public static void checkSuccessReply(NetconfMessage output) throws NetconfDocumentedException { + public static void checkSuccessReply(final NetconfMessage output) throws NetconfDocumentedException { if(NetconfMessageUtil.isErrorMessage(output)) { throw new IllegalStateException(String.format("Response contains error: %s", XmlUtil.toString(output.getDocument()))); } diff --git a/opendaylight/md-sal/sal-rest-connector/pom.xml b/opendaylight/md-sal/sal-rest-connector/pom.xml index c17a4b70cc..e4c7c0c647 100644 --- a/opendaylight/md-sal/sal-rest-connector/pom.xml +++ b/opendaylight/md-sal/sal-rest-connector/pom.xml @@ -47,6 +47,14 @@ org.opendaylight.yangtools yang-parser-impl + + org.opendaylight.yangtools.model + ietf-restconf + + + org.opendaylight.yangtools.model + ietf-yang-types-20130715 + org.slf4j slf4j-api diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java index d1441d7b9d..ea0f149d29 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/JsonMapper.java @@ -57,7 +57,7 @@ class JsonMapper { private MountInstance mountPoint; private final Logger logger = LoggerFactory.getLogger(JsonMapper.class); - public void write(JsonWriter writer, CompositeNode data, DataNodeContainer schema, MountInstance mountPoint) + public void write(final JsonWriter writer, final CompositeNode data, final DataNodeContainer schema, final MountInstance mountPoint) throws IOException { Preconditions.checkNotNull(writer); Preconditions.checkNotNull(data); @@ -81,12 +81,12 @@ class JsonMapper { foundLists.clear(); } - private void writeChildrenOfParent(JsonWriter writer, CompositeNode parent, DataNodeContainer parentSchema) + private void writeChildrenOfParent(final JsonWriter writer, final CompositeNode parent, final DataNodeContainer parentSchema) throws IOException { checkNotNull(parent); checkNotNull(parentSchema); - for (Node child : parent.getChildren()) { + for (Node child : parent.getValue()) { DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes()); if (childSchema == null) { @@ -122,17 +122,17 @@ class JsonMapper { } } - for (Node child : parent.getChildren()) { + for (Node child : parent.getValue()) { DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchema.getChildNodes()); if (childSchema instanceof LeafListSchemaNode) { - foundLeafLists.remove((LeafListSchemaNode) childSchema); + foundLeafLists.remove(childSchema); } else if (childSchema instanceof ListSchemaNode) { - foundLists.remove((ListSchemaNode) childSchema); + foundLists.remove(childSchema); } } } - private DataSchemaNode findFirstSchemaForNode(Node node, Set dataSchemaNode) { + private DataSchemaNode findFirstSchemaForNode(final Node node, final Set dataSchemaNode) { for (DataSchemaNode dsn : dataSchemaNode) { if (node.getNodeType().equals(dsn.getQName())) { return dsn; @@ -148,14 +148,14 @@ class JsonMapper { return null; } - private void writeContainer(JsonWriter writer, CompositeNode node, ContainerSchemaNode schema) throws IOException { + private void writeContainer(final JsonWriter writer, final CompositeNode node, final ContainerSchemaNode schema) throws IOException { writeName(node, schema, writer); writer.beginObject(); writeChildrenOfParent(writer, node, schema); writer.endObject(); } - private void writeList(JsonWriter writer, CompositeNode nodeParent, CompositeNode node, ListSchemaNode schema) + private void writeList(final JsonWriter writer, final CompositeNode nodeParent, final CompositeNode node, final ListSchemaNode schema) throws IOException { writeName(node, schema, writer); writer.beginArray(); @@ -176,8 +176,8 @@ class JsonMapper { writer.endArray(); } - private void writeLeafList(JsonWriter writer, CompositeNode nodeParent, SimpleNode node, - LeafListSchemaNode schema) throws IOException { + private void writeLeafList(final JsonWriter writer, final CompositeNode nodeParent, final SimpleNode node, + final LeafListSchemaNode schema) throws IOException { writeName(node, schema, writer); writer.beginArray(); @@ -188,13 +188,13 @@ class JsonMapper { writer.endArray(); } - private void writeLeaf(JsonWriter writer, SimpleNode node, LeafSchemaNode schema) throws IOException { + private void writeLeaf(final JsonWriter writer, final SimpleNode node, final LeafSchemaNode schema) throws IOException { writeName(node, schema, writer); writeValueOfNodeByType(writer, node, schema.getType(), schema); } - private void writeValueOfNodeByType(JsonWriter writer, SimpleNode node, TypeDefinition type, - DataSchemaNode schema) throws IOException { + private void writeValueOfNodeByType(final JsonWriter writer, final SimpleNode node, final TypeDefinition type, + final DataSchemaNode schema) throws IOException { TypeDefinition baseType = RestUtil.resolveBaseTypeFrom(type); @@ -245,7 +245,7 @@ class JsonMapper { } } - private void writeIdentityValuesDTOToJson(JsonWriter writer, IdentityValuesDTO valueDTO) throws IOException { + private void writeIdentityValuesDTOToJson(final JsonWriter writer, final IdentityValuesDTO valueDTO) throws IOException { StringBuilder result = new StringBuilder(); for (IdentityValue identityValue : valueDTO.getValuesWithNamespaces()) { result.append("/"); @@ -271,7 +271,7 @@ class JsonMapper { writer.value(result.toString()); } - private void writeModuleNameAndIdentifier(StringBuilder result, IdentityValue identityValue) { + private void writeModuleNameAndIdentifier(final StringBuilder result, final IdentityValue identityValue) { String moduleName = ControllerContext.getInstance().findModuleNameByNamespace( URI.create(identityValue.getNamespace())); if (moduleName != null && !moduleName.isEmpty()) { @@ -281,8 +281,8 @@ class JsonMapper { result.append(identityValue.getValue()); } - private void writeStringRepresentation(JsonWriter writer, SimpleNode node, TypeDefinition baseType, - Class requiredType) throws IOException { + private void writeStringRepresentation(final JsonWriter writer, final SimpleNode node, final TypeDefinition baseType, + final Class requiredType) throws IOException { Object value = node.getValue(); logger.debug("Value of " + baseType.getQName().getNamespace() + ":" + baseType.getQName().getLocalName() + " is not instance of " + requiredType.getClass() + " but is " + node.getValue().getClass()); @@ -293,13 +293,13 @@ class JsonMapper { } } - private void writeEmptyDataTypeToJson(JsonWriter writer) throws IOException { + private void writeEmptyDataTypeToJson(final JsonWriter writer) throws IOException { writer.beginArray(); writer.nullValue(); writer.endArray(); } - private void writeName(Node node, DataSchemaNode schema, JsonWriter writer) throws IOException { + private void writeName(final Node node, final DataSchemaNode schema, final JsonWriter writer) throws IOException { String nameForOutput = node.getNodeType().getLocalName(); if (schema.isAugmenting()) { ControllerContext contContext = ControllerContext.getInstance(); @@ -323,7 +323,7 @@ class JsonMapper { private static final long serialVersionUID = -3147729419814417666L; private final String value; - public NumberForJsonWriter(String value) { + public NumberForJsonWriter(final String value) { this.value = value; } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java index 1870bdf0bf..2abd4b6a3a 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/impl/RestconfProvider.java @@ -34,7 +34,6 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack private ListenerRegistration listenerRegistration; private ServiceTracker brokerServiceTrancker; private BundleContext bundleContext; - private ProviderSession session; private Thread webSocketServerThread; @Override @@ -70,7 +69,6 @@ public class RestconfProvider implements BundleActivator, Provider, ServiceTrack } } webSocketServerThread.interrupt(); - session.close(); brokerServiceTrancker.close(); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java index e0ae788703..96ad528a0d 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java +++ b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/CompositeNodeWrapper.java @@ -34,21 +34,21 @@ public final class CompositeNodeWrapper implements NodeWrapper, C private QName name; private List> values = new ArrayList<>(); - public CompositeNodeWrapper(String localName) { + public CompositeNodeWrapper(final String localName) { this.localName = Preconditions.checkNotNull(localName); } - public CompositeNodeWrapper(URI namespace, String localName) { + public CompositeNodeWrapper(final URI namespace, final String localName) { this(localName); this.namespace = namespace; } - + @Override - public void setQname(QName name) { + public void setQname(final QName name) { Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies."); this.name = name; } - + @Override public QName getQname() { return name; @@ -71,26 +71,26 @@ public final class CompositeNodeWrapper implements NodeWrapper, C } @Override - public void setNamespace(URI namespace) { + public void setNamespace(final URI namespace) { Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies."); this.namespace = namespace; } - public void addValue(NodeWrapper value) { + public void addValue(final NodeWrapper value) { Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies."); values.add(value); } - public void removeValue(NodeWrapper value) { + public void removeValue(final NodeWrapper value) { Preconditions.checkState(compositeNode == null, "Cannot change the object, due to data inconsistencies."); values.remove(value); } - + public List> getValues() { Preconditions.checkState(compositeNode == null, "Data can be inconsistent."); return Collections.unmodifiableList(values); } - + @Override public boolean isChangeAllowed() { return compositeNode == null ? true : false; @@ -103,13 +103,13 @@ public final class CompositeNodeWrapper implements NodeWrapper, C Preconditions.checkNotNull(namespace); name = new QName(namespace, localName); } - + List> nodeValues = new ArrayList<>(); for (NodeWrapper nodeWrapper : values) { nodeValues.add(nodeWrapper.unwrap()); } compositeNode = NodeFactory.createMutableCompositeNode(name, null, nodeValues, null, null); - + values = null; namespace = null; localName = null; @@ -123,6 +123,7 @@ public final class CompositeNodeWrapper implements NodeWrapper, C return unwrap().getNodeType(); } + @Deprecated @Override public CompositeNode getParent() { return unwrap().getParent(); @@ -138,38 +139,42 @@ public final class CompositeNodeWrapper implements NodeWrapper, C return unwrap().getModificationAction(); } + /** + * @deprecated Use {@link #getValue()} instead. + */ + @Deprecated @Override public List> getChildren() { - return unwrap().getChildren(); + return unwrap().getValue(); } @Override - public List getCompositesByName(QName children) { + public List getCompositesByName(final QName children) { return unwrap().getCompositesByName(children); } @Override - public List getCompositesByName(String children) { + public List getCompositesByName(final String children) { return unwrap().getCompositesByName(children); } @Override - public List> getSimpleNodesByName(QName children) { + public List> getSimpleNodesByName(final QName children) { return unwrap().getSimpleNodesByName(children); } @Override - public List> getSimpleNodesByName(String children) { + public List> getSimpleNodesByName(final String children) { return unwrap().getSimpleNodesByName(children); } @Override - public CompositeNode getFirstCompositeByName(QName container) { + public CompositeNode getFirstCompositeByName(final QName container) { return unwrap().getFirstCompositeByName(container); } @Override - public SimpleNode getFirstSimpleByName(QName leaf) { + public SimpleNode getFirstSimpleByName(final QName leaf) { return unwrap().getFirstSimpleByName(leaf); } @@ -184,7 +189,7 @@ public final class CompositeNodeWrapper implements NodeWrapper, C } @Override - public List> setValue(List> value) { + public List> setValue(final List> value) { return unwrap().setValue(value); } @@ -199,32 +204,32 @@ public final class CompositeNodeWrapper implements NodeWrapper, C } @Override - public boolean containsKey(Object key) { + public boolean containsKey(final Object key) { return unwrap().containsKey(key); } @Override - public boolean containsValue(Object value) { + public boolean containsValue(final Object value) { return unwrap().containsValue(value); } @Override - public List> get(Object key) { + public List> get(final Object key) { return unwrap().get(key); } @Override - public List> put(QName key, List> value) { + public List> put(final QName key, final List> value) { return unwrap().put(key, value); } @Override - public List> remove(Object key) { + public List> remove(final Object key) { return unwrap().remove(key); } @Override - public void putAll(Map>> m) { + public void putAll(final Map>> m) { unwrap().putAll(m); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java index 874e8b0d1f..d978a2f0de 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnJsonBasicYangTypesTest.java @@ -85,7 +85,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { verifyJsonOutput(jsonOutput); } - private void verifyJsonOutputForEmptyData(String jsonOutput) { + private void verifyJsonOutputForEmptyData(final String jsonOutput) { assertNotNull(jsonOutput); StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); @@ -104,7 +104,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { assertNull("Error during reading Json output: " + exception, exception); } - private void verifyJsonOutput(String jsonOutput) { + private void verifyJsonOutput(final String jsonOutput) { assertNotNull(jsonOutput); StringReader strReader = new StringReader(jsonOutput); JsonReader jReader = new JsonReader(strReader); @@ -123,7 +123,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { assertNull("Error during reading Json output: " + exception, exception); } - private Cont jsonReadCont1(JsonReader jReader) throws IOException { + private Cont jsonReadCont1(final JsonReader jReader) throws IOException { jReader.beginObject(); assertNotNull("cont1 is missing.", jReader.hasNext()); @@ -136,7 +136,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private Cont jsonReadCont1Elements(JsonReader jReader, Cont redData) throws IOException { + private Cont jsonReadCont1Elements(final JsonReader jReader, final Cont redData) throws IOException { jReader.beginObject(); while (jReader.hasNext()) { String keyName = jReader.nextName(); @@ -163,7 +163,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private Lst jsonReadLst11(JsonReader jReader, Lst lst) throws IOException { + private Lst jsonReadLst11(final JsonReader jReader, final Lst lst) throws IOException { jReader.beginArray(); while (jReader.hasNext()) { @@ -174,7 +174,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lst; } - private LstItem jsonReadLst11Elements(JsonReader jReader) throws IOException { + private LstItem jsonReadLst11Elements(final JsonReader jReader) throws IOException { LstItem lstItem = new LstItem(); jReader.beginObject(); while (jReader.hasNext()) { @@ -203,7 +203,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lstItem; } - private Lst jsonReadLst112(JsonReader jReader, Lst lst) throws IOException { + private Lst jsonReadLst112(final JsonReader jReader, final Lst lst) throws IOException { jReader.beginArray(); while (jReader.hasNext()) { LstItem lstItem = jsonReadLst112Elements(jReader); @@ -213,7 +213,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lst; } - private LstItem jsonReadLst112Elements(JsonReader jReader) throws IOException { + private LstItem jsonReadLst112Elements(final JsonReader jReader) throws IOException { LstItem lstItem = new LstItem(); jReader.beginObject(); if (jReader.hasNext()) { @@ -227,7 +227,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private Lst jsonReadLst111(JsonReader jReader, Lst lst) throws IOException { + private Lst jsonReadLst111(final JsonReader jReader, final Lst lst) throws IOException { jReader.beginArray(); while (jReader.hasNext()) { LstItem lstItem = jsonReadLst111Elements(jReader); @@ -237,7 +237,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lst; } - private LstItem jsonReadLst111Elements(JsonReader jReader) throws IOException { + private LstItem jsonReadLst111Elements(final JsonReader jReader) throws IOException { LstItem lstItem = new LstItem(); jReader.beginObject(); if (jReader.hasNext()) { @@ -250,7 +250,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lstItem; } - private Object nextValue(JsonReader jReader) throws IOException { + private Object nextValue(final JsonReader jReader) throws IOException { if (jReader.peek().equals(JsonToken.NULL)) { jReader.nextNull(); return null; @@ -261,14 +261,14 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } } - private Cont jsonReadCont111(JsonReader jReader, Cont cont) throws IOException { + private Cont jsonReadCont111(final JsonReader jReader, Cont cont) throws IOException { jReader.beginObject(); cont = jsonReadCont111Elements(jReader, cont); jReader.endObject(); return cont; } - private Cont jsonReadCont111Elements(JsonReader jReader, Cont cont) throws IOException { + private Cont jsonReadCont111Elements(final JsonReader jReader, final Cont cont) throws IOException { while (jReader.hasNext()) { String keyName = jReader.nextName(); if (keyName.equals("lf1111")) { @@ -289,7 +289,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private Lst jsonReadLst1111(JsonReader jReader, Lst lst) throws IOException { + private Lst jsonReadLst1111(final JsonReader jReader, final Lst lst) throws IOException { jReader.beginArray(); while (jReader.hasNext()) { LstItem lstItem = jsonReadLst1111Elements(jReader); @@ -299,7 +299,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lst; } - private LstItem jsonReadLst1111Elements(JsonReader jReader) throws IOException { + private LstItem jsonReadLst1111Elements(final JsonReader jReader) throws IOException { jReader.beginObject(); LstItem lstItem = new LstItem(); while (jReader.hasNext()) { @@ -312,7 +312,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lstItem; } - private LfLst jsonReadLflstValues(JsonReader jReader, LfLst lfLst) throws IOException { + private LfLst jsonReadLflstValues(final JsonReader jReader, final LfLst lfLst) throws IOException { jReader.beginArray(); while (jReader.hasNext()) { lfLst.addLf(new Lf(nextValue(jReader))); @@ -321,7 +321,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { return lfLst; } - private void checkDataFromJsonEmpty(Cont dataFromJson) { + private void checkDataFromJsonEmpty(final Cont dataFromJson) { assertTrue(dataFromJson.getLfs().isEmpty()); assertTrue(dataFromJson.getLfLsts().isEmpty()); assertTrue(dataFromJson.getConts().isEmpty()); @@ -357,9 +357,9 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { assertEquals(1, lst11_1.getLsts().size()); assertEquals( lst11_1.getLsts().get("lst111"), - new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", (int) 35)) - .addLstItem(new LstItem().addLf("lf1111", (int) 34)).addLstItem(new LstItem()) - .addLstItem(new LstItem())); + new Lst("lst111").addLstItem(new LstItem().addLf("lf1111", 35)) + .addLstItem(new LstItem().addLf("lf1111", 34)).addLstItem(new LstItem()) + .addLstItem(new LstItem())); assertEquals(lst11_1.getConts().get("cont111"), new Cont("cont111")); // : lst11_1 @@ -378,10 +378,10 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { assertEquals(1, lst11_2_cont111.getLsts().size()); assertTrue(lst11_2_cont111.getConts().isEmpty()); - assertEquals(new LfLst("lflst1111").addLf((int) 1024).addLf((int) 4096), + assertEquals(new LfLst("lflst1111").addLf(1024).addLf(4096), lst11_2_cont111.getLfLsts().get("lflst1111")); assertEquals( - new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", (int) 4)).addLstItem( + new Lst("lst1111").addLstItem(new LstItem().addLf("lf1111B", 4)).addLstItem( new LstItem().addLf("lf1111A", "lf1111A str12")), lst11_2_cont111.getLsts().get("lst1111")); // :-cont111 assertEquals(lst11_2.getLsts().get("lst112"), new Lst("lst112").addLstItem(new LstItem())); @@ -407,7 +407,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private void checkDataFromJson(Cont dataFromJson) { + private void checkDataFromJson(final Cont dataFromJson) { assertNotNull(dataFromJson.getLfs().get("lf11")); assertEquals(dataFromJson.getLfs().get("lf11"), new Lf("lf11", "lf")); @@ -450,7 +450,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { checkLst11_2(lst11_2); } - private void checkLst11_2(LstItem lst11_2) { + private void checkLst11_2(final LstItem lst11_2) { assertNotNull(lst11_2); assertEquals(2, lst11_2.getLfs().size()); assertEquals(1, lst11_2.getConts().size()); @@ -479,7 +479,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { new LstItem().addLf(new Lf("lf1121", "lf1121 str21"))); } - private void checkLst11_1(LstItem lst11_1) { + private void checkLst11_1(final LstItem lst11_1) { assertNotNull(lst11_1); assertEquals(2, lst11_1.getLfs().size()); @@ -507,7 +507,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { checkLst11x(lst11_1.getLsts().get("lst112"), new LstItem().addLf(new Lf("lf1121", "lf1121 str11"))); } - private void checkLst11x(Lst lst, LstItem... lstItems) { + private void checkLst11x(final Lst lst, final LstItem... lstItems) { assertNotNull(lst); Lst requiredLst = new Lst(lst.getName()); @@ -519,7 +519,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { } - private void checkLst1111(Set lstItems, Lf lf11, Lf lf12, Lf lf21, Lf lf22) { + private void checkLst1111(final Set lstItems, final Lf lf11, final Lf lf12, final Lf lf21, final Lf lf22) { LstItem lst11_1_cont_lst1111_1 = null; LstItem lst11_1_cont_lst1111_2 = null; for (LstItem lstItem : lstItems) { @@ -541,49 +541,49 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { // lst11_1 MutableCompositeNode lst11_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1, null, ModifyAction.CREATE, null); - cont1.getChildren().add(lst11_1); + cont1.getValue().add(lst11_1); MutableSimpleNode lf111_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_1, (short) 1, ModifyAction.CREATE, null); - lst11_1.getChildren().add(lf111_1); + lst11_1.getValue().add(lf111_1); // lst111_1_1 MutableCompositeNode lst111_1_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); - lst11_1.getChildren().add(lst111_1_1); + lst11_1.getValue().add(lst111_1_1); MutableSimpleNode lf1111_1_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111","simple:yang:types","2013-11-5"), - lst111_1_1, (int) 34, ModifyAction.CREATE, null); - lst111_1_1.getChildren().add(lf1111_1_1); + lst111_1_1, 34, ModifyAction.CREATE, null); + lst111_1_1.getValue().add(lf1111_1_1); lst111_1_1.init(); // :lst111_1_1 // lst111_1_2 MutableCompositeNode lst111_1_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); - lst11_1.getChildren().add(lst111_1_2); + lst11_1.getValue().add(lst111_1_2); MutableSimpleNode lf1111_1_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111","simple:yang:types","2013-11-5"), - lst111_1_2, (int) 35, ModifyAction.CREATE, null); - lst111_1_2.getChildren().add(lf1111_1_2); + lst111_1_2, 35, ModifyAction.CREATE, null); + lst111_1_2.getValue().add(lf1111_1_2); lst111_1_2.init(); // :lst111_1_2 // lst111_1_3 MutableCompositeNode lst111_1_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); - lst11_1.getChildren().add(lst111_1_3); + lst11_1.getValue().add(lst111_1_3); lst111_1_2.init(); // :lst111_1_3 // lst111_1_4 MutableCompositeNode lst111_1_4 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); - lst11_1.getChildren().add(lst111_1_4); + lst11_1.getValue().add(lst111_1_4); lst111_1_2.init(); // :lst111_1_4 MutableCompositeNode cont111_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"), lst11_1, null, ModifyAction.CREATE, null); - lst11_1.getChildren().add(cont111_1); + lst11_1.getValue().add(cont111_1); lst11_1.init(); // :lst11_1 @@ -591,39 +591,39 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { // lst11_2 MutableCompositeNode lst11_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1, null, ModifyAction.CREATE, null); - cont1.getChildren().add(lst11_2); + cont1.getValue().add(lst11_2); MutableSimpleNode lf111_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_2, (short) 2, ModifyAction.CREATE, null); - lst11_2.getChildren().add(lf111_2); + lst11_2.getValue().add(lf111_2); // cont111_2 MutableCompositeNode cont111_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"), lst11_2, null, ModifyAction.CREATE, null); - lst11_2.getChildren().add(cont111_2); + lst11_2.getValue().add(cont111_2); MutableSimpleNode lflst1111_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111","simple:yang:types","2013-11-5"), - cont111_2, (int) 1024, ModifyAction.CREATE, null); - cont111_2.getChildren().add(lflst1111_2_2); + cont111_2, 1024, ModifyAction.CREATE, null); + cont111_2.getValue().add(lflst1111_2_2); MutableSimpleNode lflst1111_2_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lflst1111","simple:yang:types","2013-11-5"), - cont111_2, (int) 4096, ModifyAction.CREATE, null); - cont111_2.getChildren().add(lflst1111_2_3); + cont111_2, 4096, ModifyAction.CREATE, null); + cont111_2.getValue().add(lflst1111_2_3); // lst1111_2 MutableCompositeNode lst1111_2_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_2, null, ModifyAction.CREATE, null); - cont111_2.getChildren().add(lst1111_2_1); + cont111_2.getValue().add(lst1111_2_1); MutableSimpleNode lf1111B_2_1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111B","simple:yang:types","2013-11-5"), lst1111_2_1, (short) 4, ModifyAction.CREATE, null); - lst1111_2_1.getChildren().add(lf1111B_2_1); + lst1111_2_1.getValue().add(lf1111B_2_1); lst1111_2_1.init(); MutableCompositeNode lst1111_2_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_2, null, ModifyAction.CREATE, null); - cont111_2.getChildren().add(lst1111_2_2); + cont111_2.getValue().add(lst1111_2_2); MutableSimpleNode lf1111A_2_2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1111A","simple:yang:types","2013-11-5"), lst1111_2_2, "lf1111A str12", ModifyAction.CREATE, null); - lst1111_2_2.getChildren().add(lf1111A_2_2); + lst1111_2_2.getValue().add(lf1111A_2_2); lst1111_2_2.init(); // :lst1111_2 @@ -632,7 +632,7 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { MutableCompositeNode lst112_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst112","simple:yang:types","2013-11-5"), lst11_2, null, ModifyAction.CREATE, null); - lst11_2.getChildren().add(lst112_2); + lst11_2.getValue().add(lst112_2); lst112_2.init(); lst11_2.init(); @@ -641,25 +641,25 @@ public class CnSnJsonBasicYangTypesTest extends YangAndXmlAndDataSchemaLoader { // lst11_3 MutableCompositeNode lst11_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst11","simple:yang:types","2013-11-5"), cont1, null, ModifyAction.CREATE, null); - cont1.getChildren().add(lst11_3); + cont1.getValue().add(lst11_3); MutableSimpleNode lf111_3 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111","simple:yang:types","2013-11-5"), lst11_3, (short) 3, ModifyAction.CREATE, null); - lst11_3.getChildren().add(lf111_3); + lst11_3.getValue().add(lf111_3); // cont111_3 MutableCompositeNode cont111_3 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont111","simple:yang:types","2013-11-5"), lst11_3, null, ModifyAction.CREATE, null); - lst11_3.getChildren().add(cont111_3); + lst11_3.getValue().add(cont111_3); MutableCompositeNode lst1111_3_1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_3, null, ModifyAction.CREATE, null); - cont111_3.getChildren().add(lst1111_3_1); + cont111_3.getValue().add(lst1111_3_1); lst1111_3_1.init(); MutableCompositeNode lst1111_3_2 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("lst1111","simple:yang:types","2013-11-5"), cont111_3, null, ModifyAction.CREATE, null); - cont111_3.getChildren().add(lst1111_3_2); + cont111_3.getValue().add(lst1111_3_2); lst1111_3_2.init(); cont111_3.init(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java index 745f11c210..fdd3aa6684 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonIdentityrefTest.java @@ -73,17 +73,17 @@ public class CnSnToJsonIdentityrefTest extends YangAndXmlAndDataSchemaLoader { assertTrue(mtch.matches()); } - private CompositeNode prepareCompositeNode(Object value) { + private CompositeNode prepareCompositeNode(final Object value) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont","identityref:module","2013-12-2"), null, null, ModifyAction.CREATE, null); MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont1","identityref:module","2013-12-2"), cont, null, ModifyAction.CREATE, null); - cont.getChildren().add(cont1); + cont.getValue().add(cont1); MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1","identityref:module","2013-12-2"), cont1, value, ModifyAction.CREATE, null); - cont1.getChildren().add(lf1); + cont1.getValue().add(lf1); cont1.init(); cont.init(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java index dd1502ba79..42e1e3f739 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonNotExistingLeafTypeTest.java @@ -27,6 +27,7 @@ import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; import org.slf4j.Logger; @@ -46,7 +47,7 @@ public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLo String jsonOutput = null; jsonOutput = TestUtils .writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), - Collections.EMPTY_SET, prepareDataSchemaNode(), + Collections.emptySet(), prepareDataSchemaNode(), StructuredDataToJsonProvider.INSTANCE); assertNotNull(jsonOutput); assertTrue(jsonOutput.contains("\"lf1\": \"\"")); @@ -57,7 +58,7 @@ public class CnSnToJsonNotExistingLeafTypeTest extends YangAndXmlAndDataSchemaLo TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null); MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode( TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null); - cont.getChildren().add(lf1); + cont.getValue().add(lf1); cont.init(); return cont; } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java index 348edbd294..052bb1a2be 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/json/test/CnSnToJsonWithDataFromSeveralModulesTest.java @@ -99,32 +99,32 @@ public class CnSnToJsonWithDataFromSeveralModulesTest extends YangAndXmlAndDataS MutableCompositeNode cont_m1 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont_m1", uri1, rev1), data, null, null, null); - data.getChildren().add(cont_m1); + data.getValue().add(cont_m1); MutableSimpleNode lf1_m1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1_m1", uri1, rev1), cont_m1, "lf1 m1 value", null, null); - cont_m1.getChildren().add(lf1_m1); + cont_m1.getValue().add(lf1_m1); cont_m1.init(); MutableCompositeNode contB_m1 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("contB_m1", uri1, rev1), data, null, null, null); - data.getChildren().add(contB_m1); + data.getValue().add(contB_m1); contB_m1.init(); String uri2 = "module:two"; String rev2 = "2014-01-17"; MutableCompositeNode cont_m2 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont_m2", uri2, rev2), data, null, null, null); - data.getChildren().add(cont_m2); + data.getValue().add(cont_m2); MutableSimpleNode lf1_m2 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf1_m2", uri2, rev2), cont_m1, "lf1 m2 value", null, null); - cont_m2.getChildren().add(lf1_m2); + cont_m2.getValue().add(lf1_m2); cont_m2.init(); MutableCompositeNode contB_m2 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("contB_m2", uri2, rev2), data, null, null, null); - data.getChildren().add(contB_m2); + data.getValue().add(contB_m2); contB_m2.init(); data.init(); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java index f81c1d63f5..2ada6e13e9 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlNotExistingLeafTypeTest.java @@ -25,6 +25,7 @@ import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; import org.slf4j.Logger; @@ -41,7 +42,7 @@ public class CnSnToXmlNotExistingLeafTypeTest { boolean nullPointerExceptionRaised = false; try { TestUtils.writeCompNodeWithSchemaContextToOutput(prepareCompositeNode(), - Collections.EMPTY_SET, prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE); + Collections.emptySet(), prepareDataSchemaNode(), StructuredDataToXmlProvider.INSTANCE); } catch (WebApplicationException | IOException e) { LOG.error("WebApplicationException or IOException was raised"); } catch (NullPointerException e) { @@ -56,7 +57,7 @@ public class CnSnToXmlNotExistingLeafTypeTest { TestUtils.buildQName("cont", "simple:uri", "2012-12-17"), null, null, ModifyAction.CREATE, null); MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode( TestUtils.buildQName("lf1", "simple:uri", "2012-12-17"), cont, "any value", ModifyAction.CREATE, null); - cont.getChildren().add(lf1); + cont.getValue().add(lf1); cont.init(); return cont; } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java index 6b4b153252..fc54795fcc 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlTest.java @@ -28,11 +28,11 @@ import org.opendaylight.yangtools.yang.data.impl.NodeFactory; import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec; /** - * + * * CnSn = Composite node and Simple node data structure Class contains test of * serializing simple nodes data values according data types from YANG schema to * XML file - * + * */ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass @@ -139,9 +139,9 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { serializeToXml( prepareCnStructForYangData( TypeDefinitionAwareCodec.BINARY_DEFAULT_CODEC - .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"), + .deserialize("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"), elName), "<" + elName + ">ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567"); + + elName + ">"); } @Test @@ -198,7 +198,7 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { + elName + ">str"); } - private void serializeToXml(CompositeNode compositeNode, String... xmlRepresentation) + private void serializeToXml(final CompositeNode compositeNode, final String... xmlRepresentation) throws TransformerFactoryConfigurationError { String xmlString = ""; try { @@ -220,12 +220,12 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { } - private CompositeNode prepareIdentityrefData(String prefix, boolean valueAsQName) { + private CompositeNode prepareIdentityrefData(final String prefix, final boolean valueAsQName) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont", "basic:module", "2013-12-2"), null, null, ModifyAction.CREATE, null); MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont1", "basic:module", "2013-12-2"), cont, null, ModifyAction.CREATE, null); - cont.getChildren().add(cont1); + cont.getValue().add(cont1); Object value = null; if (valueAsQName) { @@ -235,20 +235,20 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { } MutableSimpleNode lf11 = NodeFactory.createMutableSimpleNode( TestUtils.buildQName("lf11", "basic:module", "2013-12-2"), cont1, value, ModifyAction.CREATE, null); - cont1.getChildren().add(lf11); + cont1.getValue().add(lf11); cont1.init(); cont.init(); return cont; } - private CompositeNode prepareCnStructForYangData(Object data, String leafName) { + private CompositeNode prepareCnStructForYangData(final Object data, final String leafName) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, ModifyAction.CREATE, null); MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(leafName), cont, data, ModifyAction.CREATE, null); - cont.getChildren().add(lf1); + cont.getValue().add(lf1); cont.init(); return cont; @@ -262,8 +262,8 @@ public class CnSnToXmlTest extends YangAndXmlAndDataSchemaLoader { cont, Boolean.TRUE, ModifyAction.CREATE, null); MutableSimpleNode lfLfref = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lfLfref"), cont, "true", ModifyAction.CREATE, null); - cont.getChildren().add(lfBoolean); - cont.getChildren().add(lfLfref); + cont.getValue().add(lfBoolean); + cont.getValue().add(lfLfref); cont.init(); return cont; diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java index a3e33ce30b..ac7fe20818 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/cnsn/to/xml/test/CnSnToXmlWithChoiceTest.java @@ -18,15 +18,18 @@ import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.StructuredDataToXmlProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.ModifyAction; +import org.opendaylight.yangtools.yang.data.api.MutableCompositeNode; +import org.opendaylight.yangtools.yang.data.api.MutableSimpleNode; import org.opendaylight.yangtools.yang.data.impl.NodeFactory; /** - * + * * CnSn = Composite node and Simple node data structure Class contains test of * serializing simple nodes data values according data types from YANG schema to * XML file - * + * */ public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader { @BeforeClass @@ -56,13 +59,13 @@ public class CnSnToXmlWithChoiceTest extends YangAndXmlAndDataSchemaLoader { } - private CompositeNode prepareCnStructForYangData(String lfName, Object data) { + private CompositeNode prepareCnStructForYangData(final String lfName, final Object data) { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode(TestUtils.buildQName("cont"), null, null, ModifyAction.CREATE, null); MutableSimpleNode lf1 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName(lfName), cont, data, ModifyAction.CREATE, null); - cont.getChildren().add(lf1); + cont.getValue().add(lf1); cont.init(); return cont; diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java index 9e726baf55..0c9e95173f 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonIdentityrefToCnSnTest.java @@ -7,7 +7,9 @@ */ package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.util.List; @@ -17,7 +19,9 @@ import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { @@ -36,13 +40,13 @@ public class JsonIdentityrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { assertEquals("cont", compositeNode.getNodeType().getLocalName()); - List> childs = compositeNode.getChildren(); + List> childs = compositeNode.getValue(); assertEquals(1, childs.size()); Node nd = childs.iterator().next(); assertTrue(nd instanceof CompositeNode); assertEquals("cont1", nd.getNodeType().getLocalName()); - childs = ((CompositeNode) nd).getChildren(); + childs = ((CompositeNode) nd).getValue(); assertEquals(4, childs.size()); SimpleNode lf11 = null; SimpleNode lf12 = null; diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java index 2030d9125a..79dd026fd0 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonLeafrefToCnSnTest.java @@ -7,14 +7,18 @@ */ package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { @@ -37,7 +41,7 @@ public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { assertEquals("cont", compositeNode.getNodeType().getLocalName()); SimpleNode lf2 = null; - for (Node childNode : compositeNode.getChildren()) { + for (Node childNode : compositeNode.getValue()) { if (childNode instanceof SimpleNode) { if (childNode.getNodeType().getLocalName().equals("lf2")) { lf2 = (SimpleNode) childNode; @@ -48,7 +52,7 @@ public class JsonLeafrefToCnSnTest extends YangAndXmlAndDataSchemaLoader { assertNotNull(lf2); assertTrue(lf2.getValue() instanceof String); - assertEquals("121", (String) lf2.getValue()); + assertEquals("121", lf2.getValue()); } diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java index 8b1dc3475f..415d58e53d 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/json/to/cnsn/test/JsonToCnSnTest.java @@ -58,13 +58,13 @@ public class JsonToCnSnTest { CompositeNode compositeNode = TestUtils.readInputToCnSn("/json-to-cnsn/multiple-leaflist-items.json", true, JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); - assertEquals(3, compositeNode.getChildren().size()); + assertEquals(3, compositeNode.getValue().size()); boolean lflst1_1 = false; boolean lflst1_2 = false; boolean lflst1_3 = false; - for (Node node : compositeNode.getChildren()) { + for (Node node : compositeNode.getValue()) { assertEquals("lflst1", node.getNodeType().getLocalName()); assertTrue(node instanceof SimpleNode); SimpleNode simpleNode = (SimpleNode) node; @@ -105,9 +105,9 @@ public class JsonToCnSnTest { assertNotNull(compositeNode); assertEquals("cont", compositeNode.getNodeType().getLocalName()); - assertNotNull(compositeNode.getChildren()); - assertEquals(1, compositeNode.getChildren().size()); - Node lfNode = compositeNode.getChildren().iterator().next(); + assertNotNull(compositeNode.getValue()); + assertEquals(1, compositeNode.getValue().size()); + Node lfNode = compositeNode.getValue().iterator().next(); assertTrue(lfNode instanceof SimpleNode); assertEquals(null, ((SimpleNode) lfNode).getValue()); @@ -119,7 +119,7 @@ public class JsonToCnSnTest { Throwable cause1 = null; try { TestUtils - .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE); + .readInputToCnSn("/json-to-cnsn/wrong-top-level1.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause1 = e; } @@ -134,7 +134,7 @@ public class JsonToCnSnTest { Throwable cause2 = null; try { TestUtils - .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE); + .readInputToCnSn("/json-to-cnsn/wrong-top-level2.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause2 = e; } @@ -144,7 +144,7 @@ public class JsonToCnSnTest { Throwable cause3 = null; try { TestUtils - .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE); + .readInputToCnSn("/json-to-cnsn/wrong-top-level3.json", true, JsonToCompositeNodeProvider.INSTANCE); } catch (WebApplicationException e) { cause3 = e; } @@ -170,7 +170,7 @@ public class JsonToCnSnTest { assertEquals("cont", compositeNode.getNodeType().getLocalName()); assertTrue(compositeNode instanceof CompositeNode); - List> children = ((CompositeNode) compositeNode).getChildren(); + List> children = compositeNode.getValue(); assertEquals(1, children.size()); assertEquals("lflst2", children.get(0).getNodeType().getLocalName()); assertEquals("45", children.get(0).getValue()); @@ -190,7 +190,7 @@ public class JsonToCnSnTest { * Tests whether namespace stay unchanged if concrete values are * present in composite or simple node and if the method for update is * called. - * + * */ @Test public void notSupplyNamespaceIfAlreadySupplied() { @@ -233,13 +233,13 @@ public class JsonToCnSnTest { assertEquals("cont", compositeNode.getNodeType().getLocalName()); - List> childs = compositeNode.getChildren(); + List> childs = compositeNode.getValue(); assertEquals(1, childs.size()); Node nd = childs.iterator().next(); assertTrue(nd instanceof CompositeNode); assertEquals("cont1", nd.getNodeType().getLocalName()); - childs = ((CompositeNode) nd).getChildren(); + childs = ((CompositeNode) nd).getValue(); assertEquals(4, childs.size()); SimpleNode lf11 = null; SimpleNode lf12 = null; @@ -274,7 +274,7 @@ public class JsonToCnSnTest { assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName()); assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString()); } - + @Ignore @Test public void loadDataAugmentedSchemaMoreEqualNamesTest() { @@ -285,17 +285,17 @@ public class JsonToCnSnTest { } catch (ResponseException e) { exceptionCaught = true; } - + assertFalse(exceptionCaught); } - private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace, - String moduleName) { + private void simpleTest(final String jsonPath, final String yangPath, final String topLevelElementName, final String namespace, + final String moduleName) { CompositeNode compNode = loadAndNormalizeData(jsonPath, yangPath, topLevelElementName, moduleName); verifyCompositeNode(compNode, namespace); } - private CompositeNode loadAndNormalizeData(String jsonPath, String yangPath, String topLevelElementName, String moduleName) { + private CompositeNode loadAndNormalizeData(final String jsonPath, final String yangPath, final String topLevelElementName, final String moduleName) { CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); @@ -312,8 +312,8 @@ public class JsonToCnSnTest { return compNode; } - private void verityMultipleItemsInList(CompositeNode compositeNode) { - List> childrenNodes = compositeNode.getChildren(); + private void verityMultipleItemsInList(final CompositeNode compositeNode) { + List> childrenNodes = compositeNode.getValue(); assertEquals(4, childrenNodes.size()); boolean lf11Found = false; boolean cont11Found = false; @@ -322,7 +322,7 @@ public class JsonToCnSnTest { assertEquals("lst1", lst1Item.getNodeType().getLocalName()); assertTrue(lst1Item instanceof CompositeNode); - List> childrenLst1 = ((CompositeNode) lst1Item).getChildren(); + List> childrenLst1 = ((CompositeNode) lst1Item).getValue(); assertEquals(1, childrenLst1.size()); String localName = childrenLst1.get(0).getNodeType().getLocalName(); if (localName.equals("lf11")) { @@ -338,7 +338,7 @@ public class JsonToCnSnTest { } else if (localName.equals("lst11")) { lst11Found = true; assertTrue(childrenLst1.get(0) instanceof CompositeNode); - assertEquals(0, ((CompositeNode) childrenLst1.get(0)).getChildren().size()); + assertEquals(0, ((CompositeNode) childrenLst1.get(0)).getValue().size()); } } @@ -347,7 +347,7 @@ public class JsonToCnSnTest { assertTrue(lst11Found); } - private void verifyCompositeNode(CompositeNode compositeNode, String namespace) { + private void verifyCompositeNode(final CompositeNode compositeNode, final String namespace) { boolean cont1Found = false; boolean lst1Found = false; boolean lflst1_1Found = false; @@ -357,16 +357,16 @@ public class JsonToCnSnTest { // assertEquals(namespace, // compositeNode.getNodeType().getNamespace().toString()); - for (Node node : compositeNode.getChildren()) { + for (Node node : compositeNode.getValue()) { if (node.getNodeType().getLocalName().equals("cont1")) { if (node instanceof CompositeNode) { cont1Found = true; - assertEquals(0, ((CompositeNode) node).getChildren().size()); + assertEquals(0, ((CompositeNode) node).getValue().size()); } } else if (node.getNodeType().getLocalName().equals("lst1")) { if (node instanceof CompositeNode) { lst1Found = true; - assertEquals(0, ((CompositeNode) node).getChildren().size()); + assertEquals(0, ((CompositeNode) node).getValue().size()); } } else if (node.getNodeType().getLocalName().equals("lflst1")) { if (node instanceof SimpleNode) { diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java index 0492b3efd4..07d781028b 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java @@ -64,7 +64,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch @Ignore @Test public void saveCnSnWithLeafListInstIdentifierToXmlTest() throws WebApplicationException, IOException, - URISyntaxException, XMLStreamException { + URISyntaxException, XMLStreamException { CompositeNode cnSn = prepareCnSn(createInstanceIdentifierWithLeafList()); String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode, StructuredDataToXmlProvider.INSTANCE); @@ -94,7 +94,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch @Test public void saveCnSnWithLeafListInstIdentifierToJsonTest() throws WebApplicationException, IOException, - URISyntaxException { + URISyntaxException { CompositeNode cnSn = prepareCnSn(createInstanceIdentifierWithLeafList()); String output = TestUtils.writeCompNodeWithSchemaContextToOutput(cnSn, modules, dataSchemaNode, StructuredDataToJsonProvider.INSTANCE); @@ -111,7 +111,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch assertTrue(strInOutput); } - private void validateXmlOutput(String xml) throws XMLStreamException { + private void validateXmlOutput(final String xml) throws XMLStreamException { XMLInputFactory xmlInFactory = XMLInputFactory.newInstance(); XMLEventReader eventReader; @@ -152,7 +152,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch } - private void validateXmlOutputWithLeafList(String xml) throws XMLStreamException { + private void validateXmlOutputWithLeafList(final String xml) throws XMLStreamException { XMLInputFactory xmlInFactory = XMLInputFactory.newInstance(); XMLEventReader eventReader; @@ -188,7 +188,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch } - private CompositeNode prepareCnSn(InstanceIdentifier instanceIdentifier) throws URISyntaxException { + private CompositeNode prepareCnSn(final InstanceIdentifier instanceIdentifier) throws URISyntaxException { MutableCompositeNode cont = NodeFactory.createMutableCompositeNode( TestUtils.buildQName("cont", "instance:identifier:module", "2014-01-17"), null, null,null,null); MutableCompositeNode cont1 = NodeFactory.createMutableCompositeNode( @@ -200,13 +200,13 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch lst11, instanceIdentifier,null,null); - lst11.getChildren().add(lf111); + lst11.getValue().add(lf111); lst11.init(); - cont1.getChildren().add(lst11); + cont1.getValue().add(lst11); cont1.init(); - cont.getChildren().add(cont1); + cont.getValue().add(cont1); cont.init(); return cont; diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java index b42178a9c6..018a235718 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/InvokeRpcMethodTest.java @@ -63,7 +63,7 @@ public class InvokeRpcMethodTest { private class AnswerImpl implements Answer> { @Override - public RpcResult answer(InvocationOnMock invocation) throws Throwable { + public RpcResult answer(final InvocationOnMock invocation) throws Throwable { CompositeNode compNode = (CompositeNode) invocation.getArguments()[1]; return new DummyRpcResult.Builder().result(compNode).isSuccessful(true).build(); } @@ -123,7 +123,7 @@ public class InvokeRpcMethodTest { TestUtils.buildQName("cont", "nmspc", "2013-12-04"), null, null, ModifyAction.CREATE, null); MutableSimpleNode lf = NodeFactory.createMutableSimpleNode( TestUtils.buildQName("lf", "nmspc", "2013-12-04"), cont, "any value", ModifyAction.CREATE, null); - cont.getChildren().add(lf); + cont.getValue().add(lf); cont.init(); return cont; @@ -150,7 +150,7 @@ public class InvokeRpcMethodTest { } catch (ResponseException e) { assertEquals(e.getMessage(), Status.INTERNAL_SERVER_ERROR.getStatusCode(), e - .getResponse().getStatus()); + .getResponse().getStatus()); } } @@ -216,7 +216,7 @@ public class InvokeRpcMethodTest { } catch (ResponseException e) { assertEquals(e.getMessage(), Status.UNSUPPORTED_MEDIA_TYPE.getStatusCode(), e - .getResponse().getStatus()); + .getResponse().getStatus()); } } @@ -273,8 +273,8 @@ public class InvokeRpcMethodTest { BrokerFacade brokerFacade = mock(BrokerFacade.class); when( brokerFacade.invokeRpc( - eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)testOutput")), - any( CompositeNode.class ))).thenReturn(rpcResult); + eq(QName.create("(http://netconfcentral.org/ns/toaster?revision=2009-11-20)testOutput")), + any( CompositeNode.class ))).thenReturn(rpcResult); restconfImpl.setBroker(brokerFacade); @@ -301,7 +301,7 @@ public class InvokeRpcMethodTest { MountInstance mockMountPoint = mock( MountInstance.class ); when( mockMountPoint.rpc( eq( cancelToastQName ), any( CompositeNode.class ) ) ) - .thenReturn( mockListener ); + .thenReturn( mockListener ); InstanceIdWithSchemaNode mockedInstanceId = mock( InstanceIdWithSchemaNode.class ); when( mockedInstanceId.getMountPoint() ).thenReturn( mockMountPoint ); @@ -315,8 +315,8 @@ public class InvokeRpcMethodTest { restconfImpl.setControllerContext( mockedContext ); StructuredData output = restconfImpl.invokeRpc( - "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/toaster:cancel-toast", - ""); + "opendaylight-inventory:nodes/node/REMOTE_HOST/yang-ext:mount/toaster:cancel-toast", + ""); assertEquals(null, output); //additional validation in the fact that the restconfImpl does not throw an exception. diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java index 7a949b8f2d..e5b0bf507d 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlLeafrefToCnSnTest.java @@ -50,13 +50,13 @@ public class XmlLeafrefToCnSnTest { verifyCommonPartAOfXml(compNode, "", nameSpace); } - private void verifyNullAndEmptyStringSingleNode(CompositeNode compNode, String nameSpace) { + private void verifyNullAndEmptyStringSingleNode(final CompositeNode compNode, final String nameSpace) { assertEquals("cont", compNode.getNodeType().getLocalName()); SimpleNode lf2 = null; SimpleNode lf3 = null; int found = 0; - for (Node child : compNode.getChildren()) { + for (Node child : compNode.getValue()) { if (found == 0x3) break; if (child instanceof SimpleNode) { @@ -91,11 +91,11 @@ public class XmlLeafrefToCnSnTest { String nameSpaceCont = "data:container:yang"; assertEquals(nameSpaceCont, compNode.getNodeType().getNamespace().toString()); assertEquals("cont", compNode.getNodeType().getLocalName()); - assertEquals(3, compNode.getChildren().size()); + assertEquals(3, compNode.getValue().size()); CompositeNode lst1_1 = null; CompositeNode lst1_2 = null; int loopCount = 0; - for (Node node : compNode.getChildren()) { + for (Node node : compNode.getValue()) { if (node.getNodeType().getLocalName().equals("lf1")) { assertEquals(nameSpaceList, node.getNodeType().getNamespace().toString()); assertTrue(node instanceof SimpleNode); @@ -120,7 +120,7 @@ public class XmlLeafrefToCnSnTest { // lst1_2 SimpleNode lflst11 = null; CompositeNode cont11 = null; - for (Node node : lst1_2.getChildren()) { + for (Node node : lst1_2.getValue()) { String nodeName = node.getNodeType().getLocalName(); if (nodeName.equals("lflst11")) { assertTrue(node instanceof SimpleNode); @@ -134,9 +134,9 @@ public class XmlLeafrefToCnSnTest { } assertEquals("221", lflst11.getValue()); - assertEquals(1, cont11.getChildren().size()); - assertTrue(cont11.getChildren().get(0) instanceof SimpleNode); - SimpleNode cont11_lf111 = (SimpleNode) cont11.getChildren().get(0); + assertEquals(1, cont11.getValue().size()); + assertTrue(cont11.getValue().get(0) instanceof SimpleNode); + SimpleNode cont11_lf111 = (SimpleNode) cont11.getValue().get(0); assertEquals(nameSpaceCont, cont11_lf111.getNodeType().getNamespace().toString()); assertEquals("lf111", cont11_lf111.getNodeType().getLocalName()); assertEquals((short) 100, cont11_lf111.getValue()); @@ -154,7 +154,7 @@ public class XmlLeafrefToCnSnTest { SimpleNode lflst1_2 = null; CompositeNode lst1 = null; int lflst1Count = 0; - for (Node node : compNode.getChildren()) { + for (Node node : compNode.getValue()) { if (node.getNodeType().getLocalName().equals("lf1")) { assertTrue(node instanceof SimpleNode); lf1 = (SimpleNode) node; @@ -183,11 +183,11 @@ public class XmlLeafrefToCnSnTest { assertEquals("", lf1.getValue()); assertEquals("", lflst1_1.getValue()); assertEquals("", lflst1_2.getValue()); - assertEquals(1, lst1.getChildren().size()); - assertEquals("lf11", lst1.getChildren().get(0).getNodeType().getLocalName()); + assertEquals(1, lst1.getValue().size()); + assertEquals("lf11", lst1.getValue().get(0).getNodeType().getLocalName()); - assertTrue(lst1.getChildren().get(0) instanceof SimpleNode); - assertEquals("", lst1.getChildren().get(0).getValue()); + assertTrue(lst1.getValue().get(0) instanceof SimpleNode); + assertEquals("", lst1.getValue().get(0).getValue()); } @@ -201,7 +201,7 @@ public class XmlLeafrefToCnSnTest { } /** - * + * * Test case like identity */ @@ -213,7 +213,7 @@ public class XmlLeafrefToCnSnTest { } /** - * + * * Test case like identity */ @@ -224,7 +224,7 @@ public class XmlLeafrefToCnSnTest { } /** - * + * * Test case like * x:identity */ @@ -236,7 +236,7 @@ public class XmlLeafrefToCnSnTest { } /** - * + * * Test case like (without namespace in xml) x:identity * */ @@ -247,7 +247,7 @@ public class XmlLeafrefToCnSnTest { } /** - * + * * Test case like (without namespace in xml) identity * */ @@ -257,7 +257,7 @@ public class XmlLeafrefToCnSnTest { "/xml-to-cnsn/identityref", "identityref-module", "cont", 2, "iden", "identityref:module"); } - private void verifyCommonPartAOfXml(CompositeNode compNode, String suf, String nameSpace) { + private void verifyCommonPartAOfXml(final CompositeNode compNode, final String suf, final String nameSpace) { SimpleNode lf1suf = null; SimpleNode lflst1suf_1 = null; SimpleNode lflst1suf_2 = null; @@ -267,7 +267,7 @@ public class XmlLeafrefToCnSnTest { int lflstCount = 0; - for (Node node : compNode.getChildren()) { + for (Node node : compNode.getValue()) { String localName = node.getNodeType().getLocalName(); if (localName.equals("lf1" + suf)) { assertTrue(node instanceof SimpleNode); @@ -307,23 +307,23 @@ public class XmlLeafrefToCnSnTest { assertEquals("131", lflst1suf_2.getValue()); assertEquals("str1", lflst1suf_3.getValue()); - assertEquals(1, lst1suf.getChildren().size()); + assertEquals(1, lst1suf.getValue().size()); - assertTrue(lst1suf.getChildren().get(0) instanceof SimpleNode); - SimpleNode lst11_lf11 = (SimpleNode) lst1suf.getChildren().get(0); + assertTrue(lst1suf.getValue().get(0) instanceof SimpleNode); + SimpleNode lst11_lf11 = (SimpleNode) lst1suf.getValue().get(0); assertEquals(nameSpace, lst11_lf11.getNodeType().getNamespace().toString()); assertEquals("lf11" + suf, lst11_lf11.getNodeType().getLocalName()); assertEquals("str2", lst11_lf11.getValue()); - assertTrue(cont1suf.getChildren().get(0) instanceof SimpleNode); - SimpleNode cont1_lf11 = (SimpleNode) cont1suf.getChildren().get(0); + assertTrue(cont1suf.getValue().get(0) instanceof SimpleNode); + SimpleNode cont1_lf11 = (SimpleNode) cont1suf.getValue().get(0); assertEquals(nameSpace, cont1_lf11.getNodeType().getNamespace().toString()); assertEquals("lf11" + suf, cont1_lf11.getNodeType().getLocalName()); assertEquals((short) 100, cont1_lf11.getValue()); } - private void testIdentityrefToCnSn(String xmlPath, String yangPath, String moduleName, String schemaName, - int moduleCount, String resultLocalName, String resultNamespace) { + private void testIdentityrefToCnSn(final String xmlPath, final String yangPath, final String moduleName, final String schemaName, + final int moduleCount, final String resultLocalName, final String resultNamespace) { CompositeNode compositeNode = TestUtils.readInputToCnSn(xmlPath, false, XmlToCompositeNodeProvider.INSTANCE); assertNotNull(compositeNode); @@ -339,16 +339,16 @@ public class XmlLeafrefToCnSnTest { assertEquals(resultNamespace, qName.getNamespace().toString()); } - private SimpleNode getLf11(CompositeNode compositeNode) { + private SimpleNode getLf11(final CompositeNode compositeNode) { assertEquals("cont", compositeNode.getNodeType().getLocalName()); - List> childs = compositeNode.getChildren(); + List> childs = compositeNode.getValue(); assertEquals(1, childs.size()); Node nd = childs.iterator().next(); assertTrue(nd instanceof CompositeNode); assertEquals("cont1", nd.getNodeType().getLocalName()); - childs = ((CompositeNode) nd).getChildren(); + childs = ((CompositeNode) nd).getValue(); SimpleNode lf11 = null; for (Node child : childs) { assertTrue(child instanceof SimpleNode); diff --git a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java index f1a18d56a8..5008d28bbf 100644 --- a/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java +++ b/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/xml/to/cnsn/test/XmlToCnSnTest.java @@ -7,14 +7,18 @@ */ package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider; import org.opendaylight.controller.sal.restconf.impl.test.TestUtils; import org.opendaylight.controller.sal.restconf.impl.test.YangAndXmlAndDataSchemaLoader; -import org.opendaylight.yangtools.yang.data.api.*; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader { @@ -34,7 +38,7 @@ public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader { assertEquals("cont", compositeNode.getNodeType().getLocalName()); SimpleNode lf2 = null; - for (Node childNode : compositeNode.getChildren()) { + for (Node childNode : compositeNode.getValue()) { if (childNode instanceof SimpleNode) { if (childNode.getNodeType().getLocalName().equals("lf2")) { lf2 = (SimpleNode) childNode; @@ -45,7 +49,7 @@ public class XmlToCnSnTest extends YangAndXmlAndDataSchemaLoader { assertNotNull(lf2); assertTrue(lf2.getValue() instanceof String); - assertEquals("121", (String) lf2.getValue()); + assertEquals("121", lf2.getValue()); } } diff --git a/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/util/InstanceIdentifierUtils.java b/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/util/InstanceIdentifierUtils.java index ea08f94ebc..c2be488d93 100644 --- a/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/util/InstanceIdentifierUtils.java +++ b/opendaylight/md-sal/samples/l2switch/implementation/src/main/java/org/opendaylight/controller/sample/l2switch/md/util/InstanceIdentifierUtils.java @@ -28,130 +28,129 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; /* InstanceIdentifierUtils provides utility functions related to InstanceIdentifiers. */ -public class InstanceIdentifierUtils { - - /** - * Creates an Instance Identifier (path) for node with specified id - * - * @param nodeId - * @return - */ - public static final InstanceIdentifier createNodePath(NodeId nodeId) { - return InstanceIdentifier.builder(Nodes.class) // - .child(Node.class, new NodeKey(nodeId)) // - .build(); - } - - /** - * Shorten's node child path to node path. - * - * @param nodeChild child of node, from which we want node path. - * @return - */ - public static final InstanceIdentifier getNodePath(InstanceIdentifier nodeChild) { - return nodeChild.firstIdentifierOf(Node.class); - } - - - /** - * Creates a table path by appending table specific location to node path - * - * @param nodePath - * @param tableKey - * @return - */ - public static final InstanceIdentifier createTablePath(InstanceIdentifier nodePath, TableKey tableKey) { - return InstanceIdentifier.builder(nodePath) - .augmentation(FlowCapableNode.class) - .child(Table.class, tableKey) - .build(); - } - - /** - * Creates a path for particular flow, by appending flow-specific information - * to table path. - * - * @param table - * @param flowKey - * @return - */ - public static InstanceIdentifier createFlowPath(InstanceIdentifier
    table, FlowKey flowKey) { - return InstanceIdentifier.builder(table) - .child(Flow.class, flowKey) - .build(); - } - - /** - * Extract table id from table path. - * - * @param tablePath - * @return - */ - public static Short getTableId(InstanceIdentifier
    tablePath) { - return tablePath.firstKeyOf(Table.class, TableKey.class).getId(); - } - - /** - * Extracts NodeConnectorKey from node connector path. - */ - public static NodeConnectorKey getNodeConnectorKey(InstanceIdentifier nodeConnectorPath) { - return nodeConnectorPath.firstKeyOf(NodeConnector.class, NodeConnectorKey.class); - } - - /** - * Extracts NodeKey from node path. - */ - public static NodeKey getNodeKey(InstanceIdentifier nodePath) { - return nodePath.firstKeyOf(Node.class, NodeKey.class); - } - - - // - public static final InstanceIdentifier createNodeConnectorIdentifier(String nodeIdValue, - String nodeConnectorIdValue) { - return InstanceIdentifier.builder(createNodePath(new NodeId(nodeIdValue))) // - .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(nodeConnectorIdValue))) // - .build(); - } - - /** - * @param nodeConnectorRef - * @return - */ - public static InstanceIdentifier generateNodeInstanceIdentifier(NodeConnectorRef nodeConnectorRef) { - return nodeConnectorRef.getValue().firstIdentifierOf(Node.class); - } - - /** - * @param nodeConnectorRef - * @param flowTableKey - * @return - */ - public static InstanceIdentifier
    generateFlowTableInstanceIdentifier(NodeConnectorRef nodeConnectorRef, TableKey flowTableKey) { - return InstanceIdentifier.builder(generateNodeInstanceIdentifier(nodeConnectorRef)) - .augmentation(FlowCapableNode.class) - .child(Table.class, flowTableKey) - .build(); - } - - /** - * @param nodeConnectorRef - * @param flowTableKey - * @param flowKey - * @return - */ - public static InstanceIdentifier generateFlowInstanceIdentifier(NodeConnectorRef nodeConnectorRef, - TableKey flowTableKey, - FlowKey flowKey) { - return InstanceIdentifier.builder(generateFlowTableInstanceIdentifier(nodeConnectorRef, flowTableKey)) - .child(Flow.class, flowKey) - .build(); - } - - public static InstanceIdentifier generateTopologyInstanceIdentifier(String topologyId) { - return InstanceIdentifier.builder(NetworkTopology.class) - .child(Topology.class, new TopologyKey(new TopologyId(topologyId))) - .build(); - } +public final class InstanceIdentifierUtils { + + private InstanceIdentifierUtils() { + throw new UnsupportedOperationException("Utility class should never be instantiated"); + } + + /** + * Creates an Instance Identifier (path) for node with specified id + * + * @param nodeId + * @return + */ + public static final InstanceIdentifier createNodePath(final NodeId nodeId) { + return InstanceIdentifier.builder(Nodes.class) // + .child(Node.class, new NodeKey(nodeId)) // + .build(); + } + + /** + * Shorten's node child path to node path. + * + * @param nodeChild child of node, from which we want node path. + * @return + */ + public static final InstanceIdentifier getNodePath(final InstanceIdentifier nodeChild) { + return nodeChild.firstIdentifierOf(Node.class); + } + + + /** + * Creates a table path by appending table specific location to node path + * + * @param nodePath + * @param tableKey + * @return + */ + public static final InstanceIdentifier
    createTablePath(final InstanceIdentifier nodePath, final TableKey tableKey) { + return nodePath.builder() + .augmentation(FlowCapableNode.class) + .child(Table.class, tableKey) + .build(); + } + + /** + * Creates a path for particular flow, by appending flow-specific information + * to table path. + * + * @param table + * @param flowKey + * @return + */ + public static InstanceIdentifier createFlowPath(final InstanceIdentifier
    table, final FlowKey flowKey) { + return table.child(Flow.class, flowKey); + } + + /** + * Extract table id from table path. + * + * @param tablePath + * @return + */ + public static Short getTableId(final InstanceIdentifier
    tablePath) { + return tablePath.firstKeyOf(Table.class, TableKey.class).getId(); + } + + /** + * Extracts NodeConnectorKey from node connector path. + */ + public static NodeConnectorKey getNodeConnectorKey(final InstanceIdentifier nodeConnectorPath) { + return nodeConnectorPath.firstKeyOf(NodeConnector.class, NodeConnectorKey.class); + } + + /** + * Extracts NodeKey from node path. + */ + public static NodeKey getNodeKey(final InstanceIdentifier nodePath) { + return nodePath.firstKeyOf(Node.class, NodeKey.class); + } + + + // + public static final InstanceIdentifier createNodeConnectorIdentifier(final String nodeIdValue, + final String nodeConnectorIdValue) { + return createNodePath(new NodeId(nodeIdValue)) + .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(nodeConnectorIdValue))); + } + + /** + * @param nodeConnectorRef + * @return + */ + public static InstanceIdentifier generateNodeInstanceIdentifier(final NodeConnectorRef nodeConnectorRef) { + return nodeConnectorRef.getValue().firstIdentifierOf(Node.class); + } + + /** + * @param nodeConnectorRef + * @param flowTableKey + * @return + */ + public static InstanceIdentifier
    generateFlowTableInstanceIdentifier(final NodeConnectorRef nodeConnectorRef, final TableKey flowTableKey) { + return generateNodeInstanceIdentifier(nodeConnectorRef).builder() + .augmentation(FlowCapableNode.class) + .child(Table.class, flowTableKey) + .build(); + } + + /** + * @param nodeConnectorRef + * @param flowTableKey + * @param flowKey + * @return + */ + public static InstanceIdentifier generateFlowInstanceIdentifier(final NodeConnectorRef nodeConnectorRef, + final TableKey flowTableKey, + final FlowKey flowKey) { + return generateFlowTableInstanceIdentifier(nodeConnectorRef, flowTableKey).child(Flow.class, flowKey); + } + + public static InstanceIdentifier generateTopologyInstanceIdentifier(final String topologyId) { + return InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(new TopologyId(topologyId))) + .build(); + } } diff --git a/opendaylight/md-sal/samples/l2switch/implementation/src/test/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImplTest.java b/opendaylight/md-sal/samples/l2switch/implementation/src/test/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImplTest.java index 3520d812d7..50f74cc33f 100644 --- a/opendaylight/md-sal/samples/l2switch/implementation/src/test/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImplTest.java +++ b/opendaylight/md-sal/samples/l2switch/implementation/src/test/java/org/opendaylight/controller/sample/l2switch/md/flow/FlowWriterServiceImplTest.java @@ -7,11 +7,19 @@ */ package org.opendaylight.controller.sample.l2switch.md.flow; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import org.junit.Before; import org.junit.Test; -import org.opendaylight.controller.sample.l2switch.md.topology.NetworkGraphService; import org.opendaylight.controller.sal.binding.api.data.DataBrokerService; import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sample.l2switch.md.topology.NetworkGraphService; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef; @@ -23,128 +31,110 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - /** */ public class FlowWriterServiceImplTest { - private DataBrokerService dataBrokerService; - private NodeConnectorRef srcNodeConnectorRef; - private NodeConnectorRef destNodeConnectorRef; - private MacAddress destMacAddress; - private MacAddress srcMacAddress; - private DataModificationTransaction dataModificationTransaction; - private NetworkGraphService networkGraphService; + private DataBrokerService dataBrokerService; + private NodeConnectorRef srcNodeConnectorRef; + private NodeConnectorRef destNodeConnectorRef; + private MacAddress destMacAddress; + private MacAddress srcMacAddress; + private DataModificationTransaction dataModificationTransaction; + private NetworkGraphService networkGraphService; - @Before - public void init() { - dataBrokerService = mock(DataBrokerService.class); - networkGraphService = mock(NetworkGraphService.class); - //build source node connector ref - InstanceIdentifier srcNodesInstanceIdentifier - = InstanceIdentifier.builder(Nodes.class) - .build(); - InstanceIdentifier srcNodeInstanceIdentifier - = InstanceIdentifier.builder(srcNodesInstanceIdentifier) - .child(Node.class, new NodeKey(new NodeId("openflow:1"))) - .build(); - InstanceIdentifier srcNodeConnectorInstanceIdentifier - = InstanceIdentifier.builder(srcNodeInstanceIdentifier) - .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:1:2"))) - .build(); - srcNodeConnectorRef = new NodeConnectorRef(srcNodeConnectorInstanceIdentifier); + @Before + public void init() { + dataBrokerService = mock(DataBrokerService.class); + networkGraphService = mock(NetworkGraphService.class); + //build source node connector ref + InstanceIdentifier srcNodesInstanceIdentifier = InstanceIdentifier.create(Nodes.class); + InstanceIdentifier srcNodeInstanceIdentifier = srcNodesInstanceIdentifier + .child(Node.class, new NodeKey(new NodeId("openflow:1"))); + InstanceIdentifier srcNodeConnectorInstanceIdentifier = srcNodeInstanceIdentifier + .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:1:2"))); + srcNodeConnectorRef = new NodeConnectorRef(srcNodeConnectorInstanceIdentifier); - //build dest node connector ref - InstanceIdentifier nodesInstanceIdentifier + //build dest node connector ref + InstanceIdentifier nodesInstanceIdentifier = InstanceIdentifier.builder(Nodes.class) .build(); - InstanceIdentifier nodeInstanceIdentifier - = InstanceIdentifier.builder(nodesInstanceIdentifier) - .child(Node.class, new NodeKey(new NodeId("openflow:2"))) - .build(); - InstanceIdentifier nodeConnectorInstanceIdentifier - = InstanceIdentifier.builder(nodeInstanceIdentifier) - .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:2:2"))) - .build(); - destNodeConnectorRef = new NodeConnectorRef(nodeConnectorInstanceIdentifier); - destMacAddress = new MacAddress("00:0a:95:9d:68:16"); - srcMacAddress = new MacAddress("00:0a:95:8c:97:24"); - dataModificationTransaction = mock(DataModificationTransaction.class); - when(dataBrokerService.beginTransaction()).thenReturn(dataModificationTransaction); - } + InstanceIdentifier nodeInstanceIdentifier = + nodesInstanceIdentifier.child(Node.class, new NodeKey(new NodeId("openflow:2"))); + InstanceIdentifier nodeConnectorInstanceIdentifier = + nodeInstanceIdentifier.child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:2:2"))); + destNodeConnectorRef = new NodeConnectorRef(nodeConnectorInstanceIdentifier); + destMacAddress = new MacAddress("00:0a:95:9d:68:16"); + srcMacAddress = new MacAddress("00:0a:95:8c:97:24"); + dataModificationTransaction = mock(DataModificationTransaction.class); + when(dataBrokerService.beginTransaction()).thenReturn(dataModificationTransaction); + } - @Test - public void testFlowWriterServiceImpl_NPEWhenDataBrokerServiceIsNull() throws Exception { - try { - new FlowWriterServiceImpl(null, networkGraphService); - fail("Expected null pointer exception."); - } catch(NullPointerException npe) { - assertEquals("dataBrokerService should not be null.", npe.getMessage()); + @Test + public void testFlowWriterServiceImpl_NPEWhenDataBrokerServiceIsNull() throws Exception { + try { + new FlowWriterServiceImpl(null, networkGraphService); + fail("Expected null pointer exception."); + } catch(NullPointerException npe) { + assertEquals("dataBrokerService should not be null.", npe.getMessage()); + } } - } - @Test - public void testAddMacToMacFlow_NPEWhenNullSourceMacDestMacAndNodeConnectorRef() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - try { - flowWriterService.addMacToMacFlow(null, null, null); - fail("Expected null pointer exception."); - } catch(NullPointerException npe) { - assertEquals("Destination mac address should not be null.", npe.getMessage()); + @Test + public void testAddMacToMacFlow_NPEWhenNullSourceMacDestMacAndNodeConnectorRef() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + try { + flowWriterService.addMacToMacFlow(null, null, null); + fail("Expected null pointer exception."); + } catch(NullPointerException npe) { + assertEquals("Destination mac address should not be null.", npe.getMessage()); + } } - } - @Test - public void testAddMacToMacFlow_NPEWhenSourceMacNullMac() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - try { - flowWriterService.addMacToMacFlow(null, null, destNodeConnectorRef); - fail("Expected null pointer exception."); - } catch(NullPointerException npe) { - assertEquals("Destination mac address should not be null.", npe.getMessage()); + @Test + public void testAddMacToMacFlow_NPEWhenSourceMacNullMac() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + try { + flowWriterService.addMacToMacFlow(null, null, destNodeConnectorRef); + fail("Expected null pointer exception."); + } catch(NullPointerException npe) { + assertEquals("Destination mac address should not be null.", npe.getMessage()); + } } - } - @Test - public void testAddMacToMacFlow_NPEWhenNullSourceMacNodeConnectorRef() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - try { - flowWriterService.addMacToMacFlow(null, destMacAddress, null); - fail("Expected null pointer exception."); - } catch(NullPointerException npe) { - assertEquals("Destination port should not be null.", npe.getMessage()); + @Test + public void testAddMacToMacFlow_NPEWhenNullSourceMacNodeConnectorRef() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + try { + flowWriterService.addMacToMacFlow(null, destMacAddress, null); + fail("Expected null pointer exception."); + } catch(NullPointerException npe) { + assertEquals("Destination port should not be null.", npe.getMessage()); + } } - } - @Test - public void testAddMacToMacFlow_WhenNullSourceMac() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - flowWriterService.addMacToMacFlow(null, destMacAddress, destNodeConnectorRef); - verify(dataBrokerService, times(1)).beginTransaction(); - verify(dataModificationTransaction, times(1)).commit(); - } + @Test + public void testAddMacToMacFlow_WhenNullSourceMac() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + flowWriterService.addMacToMacFlow(null, destMacAddress, destNodeConnectorRef); + verify(dataBrokerService, times(1)).beginTransaction(); + verify(dataModificationTransaction, times(1)).commit(); + } - @Test - public void testAddMacToMacFlow_WhenSrcAndDestMacAreSame() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - flowWriterService.addMacToMacFlow(new MacAddress(destMacAddress.getValue()), destMacAddress, destNodeConnectorRef); - verify(dataBrokerService, never()).beginTransaction(); - verify(dataModificationTransaction, never()).commit(); + @Test + public void testAddMacToMacFlow_WhenSrcAndDestMacAreSame() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + flowWriterService.addMacToMacFlow(new MacAddress(destMacAddress.getValue()), destMacAddress, destNodeConnectorRef); + verify(dataBrokerService, never()).beginTransaction(); + verify(dataModificationTransaction, never()).commit(); - } + } - @Test - public void testAddMacToMacFlow_SunnyDay() throws Exception { - FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); - flowWriterService.addMacToMacFlow(srcMacAddress, destMacAddress, destNodeConnectorRef); - verify(dataBrokerService, times(1)).beginTransaction(); - verify(dataModificationTransaction, times(1)).commit(); - } + @Test + public void testAddMacToMacFlow_SunnyDay() throws Exception { + FlowWriterService flowWriterService = new FlowWriterServiceImpl(dataBrokerService, networkGraphService); + flowWriterService.addMacToMacFlow(srcMacAddress, destMacAddress, destNodeConnectorRef); + verify(dataBrokerService, times(1)).beginTransaction(); + verify(dataModificationTransaction, times(1)).commit(); + } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java index 442c504cce..1b74d49c4f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ArrayAttributeReadingStrategy.java @@ -30,8 +30,8 @@ public class ArrayAttributeReadingStrategy extends AbstractAttributeReadingStrat @Override AttributeConfigElement readElementHook(List configNodes) throws NetconfDocumentedException { List innerList = Lists.newArrayList(); - for (int i = 0; i < configNodes.size(); i++) { - innerList.add(innerStrategy.readElement(Lists.newArrayList(configNodes.get(i))).getValue()); + for (XmlElement configNode : configNodes) { + innerList.add(innerStrategy.readElement(Lists.newArrayList(configNode)).getValue()); } return AttributeConfigElement.create(getNullableDefault(), innerList); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java index bf9eee7f26..08f3c73ac2 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/ObjectNameAttributeReadingStrategy.java @@ -8,20 +8,16 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml; import com.google.common.base.Preconditions; +import java.util.List; +import java.util.Map; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.Map; public class ObjectNameAttributeReadingStrategy extends AbstractAttributeReadingStrategy { private static final Object PREFIX_SEPARATOR = ":"; - private static final Logger logger = LoggerFactory.getLogger(ObjectNameAttributeReadingStrategy.class); public ObjectNameAttributeReadingStrategy(String nullableDefault) { super(nullableDefault); @@ -39,8 +35,7 @@ public class ObjectNameAttributeReadingStrategy extends AbstractAttributeReading } private ObjectNameAttributeMappingStrategy.MappedDependency resolve(XmlElement firstChild) throws NetconfDocumentedException{ - XmlElement typeElement = null; - typeElement = firstChild.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); + XmlElement typeElement = firstChild.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); Map.Entry prefixNamespace = typeElement.findNamespaceOfTextContent(); String serviceName = checkPrefixAndExtractServiceName(typeElement, prefixNamespace); @@ -54,7 +49,7 @@ public class ObjectNameAttributeReadingStrategy extends AbstractAttributeReading public static String checkPrefixAndExtractServiceName(XmlElement typeElement, Map.Entry prefixNamespace) throws NetconfDocumentedException { String serviceName = typeElement.getTextContent(); - + // FIXME: comparing Entry with String: Preconditions.checkState(!prefixNamespace.equals(""), "Service %s value not prefixed with namespace", XmlNetconfConstants.TYPE_KEY); String prefix = prefixNamespace.getKey() + PREFIX_SEPARATOR; 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 01844f27d4..4d984acee0 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 @@ -10,28 +10,21 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Preconditions; import com.google.common.collect.Maps; +import java.util.Map; +import java.util.Map.Entry; +import javax.management.openmbean.ArrayType; +import javax.management.openmbean.CompositeType; +import javax.management.openmbean.OpenType; +import javax.management.openmbean.SimpleType; 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.ServiceRegistryWrapper; - -import javax.management.openmbean.ArrayType; -import javax.management.openmbean.CompositeType; -import javax.management.openmbean.OpenType; -import javax.management.openmbean.SimpleType; -import java.util.Map; -import java.util.Map.Entry; public class ObjectMapper extends AttributeIfcSwitchStatement>> { - private final ServiceRegistryWrapper dependencyTracker; - - public ObjectMapper(ServiceRegistryWrapper depTracker) { - this.dependencyTracker = depTracker; - } public Map>> prepareMapping( Map configDefinition) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java index 26709dbe6b..962d459f86 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/SimpleAttributeResolvingStrategy.java @@ -133,7 +133,7 @@ final class SimpleAttributeResolvingStrategy extends AbstractAttributeResolvingS @Override protected Object parseObject(Class type, String value) { - return new Character(value.charAt(0)); + return value.charAt(0); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java deleted file mode 100644 index 61465f93e8..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/AbstractAttributeWritingStrategy.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml; - -public abstract class AbstractAttributeWritingStrategy { - protected Object preprocess(Object value) { - return value; - } -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java index a74afd0812..644df0a7f9 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/RuntimeBeanEntryWritingStrategy.java @@ -46,7 +46,7 @@ public class RuntimeBeanEntryWritingStrategy extends CompositeAttributeWritingSt Util.checkType(runtimeBeanInstanceMappingEntry.getValue(), Map.class); Map innerMap = (Map) runtimeBeanInstanceMappingEntry.getValue(); Element runtimeInstanceNode = XmlUtil.createElement(getDocument(), "_" - + (String) runtimeBeanInstanceMappingEntry.getKey(), Optional.absent()); + + runtimeBeanInstanceMappingEntry.getKey(), Optional.absent()); innerNode.appendChild(runtimeInstanceNode); for (Entry innerObjectEntry : innerMap.entrySet()) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java index 854f99c5c0..1492066289 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java @@ -8,6 +8,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; +import static com.google.common.base.Preconditions.checkState; + import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.HashMultimap; @@ -31,7 +33,6 @@ import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; -import static com.google.common.base.Preconditions.checkState; public class Config { @@ -97,13 +98,12 @@ public class Config { Map>> moduleToInstances = getMappedInstances(instancesToMap, moduleConfigs); - Element root = dataElement; if (maybeNamespace.isPresent()) { - root.setAttributeNS(maybeNamespace.get(), dataElement.getNodeName(), "xmlns"); + dataElement.setAttributeNS(maybeNamespace.get(), dataElement.getNodeName(), "xmlns"); } Element modulesElement = XmlUtil.createElement(document, XmlNetconfConstants.MODULES_KEY, Optional.of(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG)); - root.appendChild(modulesElement); + dataElement.appendChild(modulesElement); for (String moduleNamespace : moduleToInstances.keySet()) { for (Entry> moduleMappingEntry : moduleToInstances.get(moduleNamespace) .entrySet()) { @@ -115,15 +115,15 @@ public class Config { } for (ObjectName objectName : moduleMappingEntry.getValue()) { - modulesElement.appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace)); + modulesElement.appendChild(mapping.toXml(objectName, document, moduleNamespace)); } } } - root.appendChild(Services.toXml(serviceTracker, document)); + dataElement.appendChild(Services.toXml(serviceTracker, document)); - return root; + return dataElement; } // TODO refactor, replace string representing namespace with namespace class diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java index 0fe5fad29c..ff1d719c57 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java @@ -11,7 +11,12 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.confi import com.google.common.base.Optional; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import javax.management.ObjectName; +import javax.management.openmbean.OpenType; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; @@ -29,35 +34,33 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import javax.management.ObjectName; -import javax.management.openmbean.OpenType; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - public final class InstanceConfig { private static final Logger logger = LoggerFactory.getLogger(InstanceConfig.class); private final Map yangToAttrConfig; + private final String nullableDummyContainerName; private final Map jmxToAttrConfig; private final ConfigRegistryClient configRegistryClient; - public InstanceConfig(ConfigRegistryClient configRegistryClient, Map yangNamesToAttributes) { + public InstanceConfig(ConfigRegistryClient configRegistryClient, Map yangNamesToAttributes, + String nullableDummyContainerName) { + this.yangToAttrConfig = yangNamesToAttributes; + this.nullableDummyContainerName = nullableDummyContainerName; this.jmxToAttrConfig = reverseMap(yangNamesToAttributes); this.configRegistryClient = configRegistryClient; } - private Map getMappedConfiguration(ObjectName on, ServiceRegistryWrapper depTracker) { + private Map getMappedConfiguration(ObjectName on) { // TODO make field, mappingStrategies can be instantiated only once - Map>> mappingStrategies = new ObjectMapper(depTracker) + Map>> mappingStrategies = new ObjectMapper() .prepareMapping(jmxToAttrConfig); Map toXml = Maps.newHashMap(); @@ -84,24 +87,26 @@ public final class InstanceConfig { return toXml; } - public Element toXml(ObjectName on, ServiceRegistryWrapper depTracker, String namespace, Document document, Element rootElement) { - - Element cfgElement = rootElement; - + public Element toXml(ObjectName on, String namespace, Document document, Element rootElement) { Map strats = new ObjectXmlWriter().prepareWriting(yangToAttrConfig, document); - - Map mappedConfig = getMappedConfiguration(on, depTracker); - + Map mappedConfig = getMappedConfiguration(on); + Element parentElement; + if (nullableDummyContainerName != null) { + Element dummyElement = XmlUtil.createElement(document, nullableDummyContainerName, Optional.of(namespace)); + rootElement.appendChild(dummyElement); + parentElement = dummyElement; + } else { + parentElement = rootElement; + } for (Entry mappingEntry : mappedConfig.entrySet()) { try { - strats.get(mappingEntry.getKey()).writeElement(cfgElement, namespace, mappingEntry.getValue()); + strats.get(mappingEntry.getKey()).writeElement(parentElement, namespace, mappingEntry.getValue()); } catch (Exception e) { throw new IllegalStateException("Unable to write value " + mappingEntry.getValue() + " for attribute " + mappingEntry.getValue(), e); } } - - return cfgElement; + return rootElement; } private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker) { @@ -129,34 +134,59 @@ public final class InstanceConfig { } public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace, - EditStrategyType defaultStrategy, Multimap providedServices, Map> identityMap) throws NetconfDocumentedException { + EditStrategyType defaultStrategy, + Map> identityMap) throws NetconfDocumentedException { Map retVal = Maps.newHashMap(); Map strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, identityMap); List recognisedChildren = Lists.newArrayList(); - XmlElement type = null; - XmlElement name = null; - type = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); - name = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY); - List typeAndName = Lists.newArrayList(type, name); + XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); + XmlElement nameElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.NAME_KEY); + List typeAndNameElements = Lists.newArrayList(typeElement, nameElement); + + // if dummy container was defined in yang, set moduleElement to its content + if (nullableDummyContainerName != null) { + int size = moduleElement.getChildElements().size(); + int expectedChildNodes = 1 + typeAndNameElements.size(); + if (size > expectedChildNodes) { + throw new NetconfDocumentedException("Error reading module " + typeElement.getTextContent() + " : " + + nameElement.getTextContent() + " - Expected " + expectedChildNodes +" child nodes, " + + "one of them with name " + nullableDummyContainerName + + ", got " + size + " elements."); + } + if (size == expectedChildNodes) { + try { + moduleElement = moduleElement.getOnlyChildElement(nullableDummyContainerName, moduleNamespace); + } catch (NetconfDocumentedException e) { + throw new NetconfDocumentedException("Error reading module " + typeElement.getTextContent() + " : " + + nameElement.getTextContent() + " - Expected child node with name " + nullableDummyContainerName + + "." + e.getMessage()); + } + } // else 2 elements, no need to descend + } for (Entry readStratEntry : strats.entrySet()) { List configNodes = getConfigNodes(moduleElement, moduleNamespace, readStratEntry.getKey(), - recognisedChildren, typeAndName); + recognisedChildren, typeAndNameElements); AttributeConfigElement readElement = readStratEntry.getValue().readElement(configNodes); retVal.put(readStratEntry.getKey(), readElement); } - recognisedChildren.addAll(typeAndName); - moduleElement.checkUnrecognisedElements(recognisedChildren); - + recognisedChildren.addAll(typeAndNameElements); + try { + moduleElement.checkUnrecognisedElements(recognisedChildren); + } catch (NetconfDocumentedException e) { + throw new NetconfDocumentedException("Error reading module " + typeElement.getTextContent() + " : " + + nameElement.getTextContent() + " - " + + e.getMessage(), e.getErrorType(), e.getErrorTag(),e.getErrorSeverity(),e.getErrorInfo()); + } // TODO: add check for conflicts between global and local edit strategy String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); InstanceConfigElementResolved instanceConfigElementResolved = perInstanceEditStrategy.equals("") ? new InstanceConfigElementResolved( - retVal, defaultStrategy, providedServices) : new InstanceConfigElementResolved(perInstanceEditStrategy, retVal, defaultStrategy, providedServices); + retVal, defaultStrategy) : new InstanceConfigElementResolved(perInstanceEditStrategy, retVal, defaultStrategy); resolveConfiguration(instanceConfigElementResolved, services); return instanceConfigElementResolved; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java index c9605af586..ef5ba753d3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java @@ -8,7 +8,6 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import com.google.common.collect.Multimap; import java.util.Map; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException; @@ -24,20 +23,17 @@ public class InstanceConfigElementResolved { private final EditStrategyType editStrategy; private final Map configuration; - private final Multimap providedServices; - public InstanceConfigElementResolved(String currentStrategy, Map configuration, EditStrategyType defaultStrategy, Multimap providedServices) throws NetconfDocumentedException { - EditStrategyType valueOf = null; - valueOf = parseStrategy(currentStrategy, defaultStrategy); - this.editStrategy = valueOf; + public InstanceConfigElementResolved(String currentStrategy, Map configuration, + EditStrategyType defaultStrategy) + throws NetconfDocumentedException { + this.editStrategy = parseStrategy(currentStrategy, defaultStrategy); this.configuration = configuration; - this.providedServices = providedServices; } - public InstanceConfigElementResolved(Map configuration, EditStrategyType defaultStrategy, Multimap providedServices) { + public InstanceConfigElementResolved(Map configuration, EditStrategyType defaultStrategy) { editStrategy = defaultStrategy; this.configuration = configuration; - this.providedServices = providedServices; } @@ -49,7 +45,7 @@ public class InstanceConfigElementResolved { public EditConfigStrategy getEditStrategy() { - return editStrategy.getFittingStrategy(providedServices); + return editStrategy.getFittingStrategy(); } public Map getConfiguration() { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java index 6a17e97350..0c2b0e228e 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java @@ -9,8 +9,9 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; import com.google.common.base.Optional; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; +import java.util.Date; +import java.util.Map; +import javax.management.ObjectName; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; @@ -18,47 +19,20 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; -import org.opendaylight.yangtools.yang.common.QName; import org.w3c.dom.Document; import org.w3c.dom.Element; -import javax.management.ObjectName; -import java.util.Collection; -import java.util.Date; -import java.util.Map; - public class ModuleConfig { private final String moduleName; private final InstanceConfig instanceConfig; - private final Multimap providedServices; - public ModuleConfig(String moduleName, InstanceConfig mbeanMapping, Collection providedServices) { + public ModuleConfig(String moduleName, InstanceConfig mbeanMapping) { this.moduleName = moduleName; this.instanceConfig = mbeanMapping; - this.providedServices = mapServices(providedServices); - } - - private Multimap mapServices(Collection providedServices) { - Multimap mapped = HashMultimap.create(); - - for (QName providedService : providedServices) { - String key = providedService.getNamespace().toString(); - mapped.put(key, providedService.getLocalName()); - } - - return mapped; - } - - public InstanceConfig getMbeanMapping() { - return instanceConfig; - } - - public Multimap getProvidedServices() { - return providedServices; } - public Element toXml(ObjectName instanceON, ServiceRegistryWrapper depTracker, Document document, String namespace) { + public Element toXml(ObjectName instanceON, Document document, String namespace) { Element root = XmlUtil.createElement(document, XmlNetconfConstants.MODULE_KEY, Optional.absent()); // type belongs to config.yang namespace, but needs to be prefix:moduleName @@ -73,7 +47,7 @@ public class ModuleConfig { root.appendChild(nameElement); - root = instanceConfig.toXml(instanceON, depTracker, namespace, document, root); + root = instanceConfig.toXml(instanceON, namespace, document, root); return root; } @@ -81,7 +55,7 @@ public class ModuleConfig { public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy, Map> identityMap) throws NetconfDocumentedException { - InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices, identityMap); + InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, identityMap); return new ModuleElementResolved(instanceName, ice); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java index b772eee0d7..92b7a487e0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java @@ -49,10 +49,6 @@ public class ModuleElementDefinition { return instanceName; } - public EditStrategyType getEditStrategyType() { - return editStrategy; - } - public EditConfigStrategy getEditStrategy() { switch (editStrategy) { case delete : diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java index 1f63555e83..f86d641112 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java @@ -7,47 +7,30 @@ */ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; -import org.opendaylight.yangtools.yang.common.QName; - +import java.util.Map; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; +import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; +import org.opendaylight.yangtools.yang.common.QName; public class ServiceRegistryWrapper { private ServiceReferenceReadableRegistry configServiceRefRegistry; - private long suffix = 1; - public ServiceRegistryWrapper(ServiceReferenceReadableRegistry configServiceRefRegistry) { this.configServiceRefRegistry = configServiceRefRegistry; } - public boolean hasRefName(String namespace, String serviceName, ObjectName on) { - String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName); - Map forQName = configServiceRefRegistry.getServiceMapping().get(qname); - if(forQName==null){ - return false; - } - return forQName.values().contains(on); - } - public ObjectName getByServiceAndRefName(String namespace, String serviceName, String refName) { Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); - Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace); + Preconditions.checkNotNull(serviceNameToRefNameToInstance, "No serviceInstances mapped to " + namespace); Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , " + Preconditions.checkNotNull(refNameToInstance, "No serviceInstances mapped to " + serviceName + " , " + serviceNameToRefNameToInstance.keySet()); String instanceId = refNameToInstance.get(refName); @@ -102,50 +85,4 @@ public class ServiceRegistryWrapper { return retVal; } - - @VisibleForTesting - public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) { - String refName; - refName = "ref_" + instanceName; - - Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); - - Map refNameToInstance; - if(serviceNameToRefNameToInstance == null || !serviceNameToRefNameToInstance.containsKey(serviceName)) { - refNameToInstance = Collections.emptyMap(); - } else { - refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - } - - final Set refNamesAsSet = toSet(refNameToInstance.keySet()); - if (refNamesAsSet.contains(refName)) { - refName = findAvailableRefName(refName, refNamesAsSet); - } - - return refName; - } - - - private Set toSet(Collection values) { - Set refNamesAsSet = Sets.newHashSet(); - - for (String refName : values) { - boolean resultAdd = refNamesAsSet.add(refName); - Preconditions.checkState(resultAdd, - "Error occurred building services element, reference name {} was present twice", refName); - } - - return refNamesAsSet; - } - - private String findAvailableRefName(String refName, Set refNamesAsSet) { - String availableRefName = ""; - - while (true) { - availableRefName = refName + "_" + suffix++; - if (!refNamesAsSet.contains(availableRefName)){ - return availableRefName; - } - } - } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java index 28b1417893..67c178e219 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/rpc/ModuleRpcs.java @@ -56,11 +56,4 @@ public final class ModuleRpcs { return rpc; } - public Map getYangToJavaNames() { - return yangToJavaNames; - } - - public Map> getRpcMapping() { - return rpcMapping; - } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java index 6a49275f26..44227bb4d8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/InstanceRuntime.java @@ -80,10 +80,7 @@ public class InstanceRuntime { if (on.getKeyPropertyList().size() != keyListSize + 1){ return false; } - if (!on.getKeyPropertyList().containsKey(string)){ - return false; - } - return true; + return on.getKeyPropertyList().containsKey(string); } })); } @@ -94,7 +91,7 @@ public class InstanceRuntime { public Element toXml(ObjectName rootOn, Set childRbeOns, Document document, String instanceIndex, Element parentElement, String namespace) { - Element xml = instanceMapping.toXml(rootOn, null, namespace, document, parentElement); + Element xml = instanceMapping.toXml(rootOn, namespace, document, parentElement); if (instanceIndex != null) { xml.setAttribute(KEY_ATTRIBUTE_KEY, instanceIndex); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java index 59767fec6e..4d67c75893 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java @@ -9,27 +9,21 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime; import com.google.common.collect.Sets; +import java.util.Collection; +import java.util.Set; +import javax.management.ObjectName; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.w3c.dom.Document; import org.w3c.dom.Element; -import javax.management.ObjectName; -import java.util.Collection; -import java.util.Set; - public class ModuleRuntime { private final InstanceRuntime instanceRuntime; - public ModuleRuntime(String moduleName, InstanceRuntime instanceRuntime) { + public ModuleRuntime(InstanceRuntime instanceRuntime) { this.instanceRuntime = instanceRuntime; } - public InstanceRuntime getMbeanMapping() { - return instanceRuntime; - } - private ObjectName findRoot(Collection runtimeBeanOns) { for (ObjectName objectName : runtimeBeanOns) { if (objectName.getKeyPropertyList().size() == 3){ @@ -40,15 +34,16 @@ public class ModuleRuntime { } public Element toXml(String namespace, Collection runtimeBeanOns, - Document document, ModuleConfig moduleConfig, ObjectName configBeanON, ServiceRegistryWrapper serviceTracker) { + Document document, ModuleConfig moduleConfig, ObjectName configBeanON) { - Element moduleElement = moduleConfig.toXml(configBeanON, serviceTracker, document, namespace); + Element moduleElement = moduleConfig.toXml(configBeanON, document, namespace); ObjectName rootName = findRoot(runtimeBeanOns); Set childrenRuntimeBeans = Sets.newHashSet(runtimeBeanOns); childrenRuntimeBeans.remove(rootName); + // FIXME: why is this called and not used? instanceRuntime.toXml(rootName, childrenRuntimeBeans, document, moduleElement, namespace); return moduleElement; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java index 439dea2a80..b9518dc4d8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java @@ -8,26 +8,22 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime; +import com.google.common.base.Optional; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; import java.util.Collection; import java.util.Map; import java.util.Set; - import javax.management.ObjectName; - import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; -import com.google.common.base.Optional; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; - public class Runtime { private final Map> moduleRuntimes; @@ -63,7 +59,7 @@ public class Runtime { return retVal; } - public Element toXml(Set instancesToMap, Set configBeans, Document document, ServiceRegistryWrapper serviceRegistry) { + public Element toXml(Set instancesToMap, Set configBeans, Document document) { Element root = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.absent()); Element modulesElement = XmlUtil.createElement(document, XmlNetconfConstants.MODULES_KEY, Optional.of(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG)); @@ -86,11 +82,11 @@ public class Runtime { Element runtimeXml; ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName); if(instanceToRbe==null || !instanceToRbe.containsKey(instanceName)) { - runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace); + runtimeXml = moduleConfig.toXml(instanceON, document, localNamespace); } else { ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName); runtimeXml = moduleRuntime.toXml(localNamespace, instanceToRbe.get(instanceName), document, - moduleConfig, instanceON, serviceRegistry); + moduleConfig, instanceON); } modulesElement.appendChild(runtimeXml); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java index 3ea26055f3..319f539c25 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java @@ -13,6 +13,12 @@ import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; import org.opendaylight.controller.config.api.ValidationException; import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.config.util.ConfigTransactionClient; @@ -21,7 +27,6 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag; import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; -import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved; @@ -43,13 +48,6 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - public class EditConfig extends AbstractConfigNetconfOperation { private static final Logger logger = LoggerFactory.getLogger(EditConfig.class); @@ -69,7 +67,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { @VisibleForTesting Element getResponseInternal(final Document document, - final EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException, NetconfConfigHandlingException { + final EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException { if (editConfigExecution.shouldTest()) { executeTests(getConfigRegistryClient(), editConfigExecution); @@ -232,11 +230,6 @@ public class EditConfig extends AbstractConfigNetconfOperation { return identityNameToSchemaNode.containsKey(idName); } - // FIXME method never used - public IdentitySchemaNode getIdentitySchemaNode(String idName) { - Preconditions.checkState(identityNameToSchemaNode.containsKey(idName), "No identity under name %s", idName); - return identityNameToSchemaNode.get(idName); - } } private static Map> transformIdentities(Set modules) { @@ -280,9 +273,8 @@ public class EditConfig extends AbstractConfigNetconfOperation { String moduleName = moduleNameToMbe.getKey(); ModuleMXBeanEntry moduleMXBeanEntry = moduleNameToMbe.getValue(); - ModuleConfig moduleConfig = new ModuleConfig(moduleName, new InstanceConfig(configRegistryClient, - moduleMXBeanEntry.getAttributes()), moduleMXBeanEntry - .getProvidedServices().values()); + ModuleConfig moduleConfig = new ModuleConfig(moduleName, + new InstanceConfig(configRegistryClient,moduleMXBeanEntry.getAttributes(), moduleMXBeanEntry.getNullableDummyContainerName())); Map moduleNameToModuleConfig = namespaceToModuleNameToModuleConfig.get(namespace); if(moduleNameToModuleConfig == null) { @@ -307,7 +299,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { EditConfigXmlParser.EditConfigExecution editConfigExecution; Config cfg = getConfigMapping(getConfigRegistryClient(), yangStoreSnapshot); - editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, getConfigRegistryClient()); + editConfigExecution = editConfigXmlParser.fromXml(xml, cfg); Element responseInternal; responseInternal = getResponseInternal(document, editConfigExecution); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java index 547ffcda3d..47220f1857 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java @@ -11,8 +11,9 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.collect.Multimap; +import java.util.Arrays; +import java.util.Map; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; -import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition; @@ -20,7 +21,6 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; -import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -28,9 +28,6 @@ import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Arrays; -import java.util.Map; - public class EditConfigXmlParser { private static final Logger logger = LoggerFactory.getLogger(EditConfigXmlParser.class); @@ -45,8 +42,7 @@ public class EditConfigXmlParser { public EditConfigXmlParser() { } - EditConfigXmlParser.EditConfigExecution fromXml(final XmlElement xml, final Config cfgMapping, - TransactionProvider transactionProvider, ConfigRegistryClient configRegistryClient) + EditConfigXmlParser.EditConfigExecution fromXml(final XmlElement xml, final Config cfgMapping) throws NetconfDocumentedException { //TODO remove transactionProvider and CfgRegistry from parameters, accept only service ref store diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java index 6b81603dcd..25d772f4ac 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java @@ -8,12 +8,10 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; -import com.google.common.collect.Multimap; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException; -import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException; - import java.util.EnumSet; import java.util.Set; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.netconf.confignetconfconnector.exception.OperationNotPermittedException; public enum EditStrategyType { // can be default @@ -58,12 +56,12 @@ public enum EditStrategyType { } } - public EditConfigStrategy getFittingStrategy(Multimap providedServices) { + public EditConfigStrategy getFittingStrategy() { switch (this) { case merge: - return new MergeEditConfigStrategy(providedServices); + return new MergeEditConfigStrategy(); case replace: - return new ReplaceEditConfigStrategy(providedServices); + return new ReplaceEditConfigStrategy(); case delete: return new DeleteEditConfigStrategy(); case remove: diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java index 3e5707cf6d..6ebeeaa07b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java @@ -8,9 +8,10 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import java.util.Map; +import java.util.Map.Entry; +import javax.management.Attribute; +import javax.management.ObjectName; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; @@ -19,23 +20,12 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.Attribute; -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; -import java.util.Map; -import java.util.Map.Entry; - public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { private static final Logger logger = LoggerFactory.getLogger(MergeEditConfigStrategy.class); - private final Multimap providedServices; public MergeEditConfigStrategy() { - this.providedServices = HashMultimap.create(); - } - public MergeEditConfigStrategy(Multimap providedServices) { - this.providedServices = providedServices; } @Override @@ -49,32 +39,8 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorSeverity.error); } - - private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { - for (Entry namespaceToService : providedServices.entries()) { - - if(services.hasRefName(namespaceToService.getKey(), - namespaceToService.getValue(), on)){ - continue; - } - - String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), - ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); - ta.saveServiceReference( - ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on); - } - } - @Override void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { - try { - addRefNames(services, providedServices, ta, on); - } catch (InstanceNotFoundException e) { - throw new NetconfConfigHandlingException(String.format("Unable to save default ref name for instance %s. Instance was not found.",e), - NetconfDocumentedException.ErrorType.application, - NetconfDocumentedException.ErrorTag.operation_failed, - NetconfDocumentedException.ErrorSeverity.error); - } for (Entry configAttributeEntry : configuration.entrySet()) { try { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java index c431766c4c..c8adb2eae0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java @@ -27,9 +27,8 @@ public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { - ObjectName on = null; try { - on = ta.createModule(module, instance); + ObjectName on = ta.createModule(module, instance); logger.trace("New instance for {} {} created under name {}", module, instance, on); } catch (InstanceAlreadyExistsException e1) { throw new NetconfConfigHandlingException(String.format("Unable to create instance for %s : %s.", module, instance), @@ -42,6 +41,5 @@ public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy @Override void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName objectName, ServiceRegistryWrapper services) { - return; } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java index bc3082ff50..ab993c5ffd 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java @@ -8,9 +8,10 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import java.util.Map; +import java.util.Map.Entry; +import javax.management.Attribute; +import javax.management.ObjectName; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.exception.NetconfConfigHandlingException; @@ -19,26 +20,10 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.Attribute; -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; -import java.util.Map; -import java.util.Map.Entry; - public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { private static final Logger logger = LoggerFactory.getLogger(ReplaceEditConfigStrategy.class); - private final Multimap providedServices; - - public ReplaceEditConfigStrategy() { - this.providedServices = HashMultimap.create(); - } - - public ReplaceEditConfigStrategy(Multimap providedServices) { - this.providedServices = providedServices; - } - @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, String module, String instance, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { @@ -51,32 +36,8 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { NetconfDocumentedException.ErrorSeverity.error); } - private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { - for (Entry namespaceToService : providedServices.entries()) { - - if(services.hasRefName(namespaceToService.getKey(), - namespaceToService.getValue(), on)){ - continue; - } - - String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), - ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); - ta.saveServiceReference( - ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on); - } - } - @Override void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) throws NetconfConfigHandlingException { - try { - addRefNames(services, providedServices, ta, on); - } catch (InstanceNotFoundException e) { - throw new NetconfConfigHandlingException(String.format("Unable to save default ref name for instance %s. Instance not found. ",on), - NetconfDocumentedException.ErrorType.application, - NetconfDocumentedException.ErrorTag.operation_failed, - NetconfDocumentedException.ErrorSeverity.error); - } - for (Entry configAttributeEntry : configuration.entrySet()) { try { AttributeConfigElement ace = configAttributeEntry.getValue(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java index 4665c2cc89..48b4bbc2a8 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java @@ -9,14 +9,16 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.get; import com.google.common.collect.Maps; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.management.ObjectName; import org.opendaylight.controller.config.util.ConfigRegistryClient; -import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.InstanceRuntime; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.ModuleRuntime; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.Runtime; @@ -24,7 +26,6 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.Abs import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot; -import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException; import org.opendaylight.controller.netconf.util.exception.UnexpectedNamespaceException; @@ -35,22 +36,15 @@ import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import javax.management.ObjectName; -import java.util.List; -import java.util.Map; -import java.util.Set; - public class Get extends AbstractConfigNetconfOperation { private final YangStoreSnapshot yangStoreSnapshot; private static final Logger logger = LoggerFactory.getLogger(Get.class); - private final TransactionProvider transactionProvider; public Get(YangStoreSnapshot yangStoreSnapshot, ConfigRegistryClient configRegistryClient, - String netconfSessionIdForReporting, TransactionProvider transactionProvider) { + String netconfSessionIdForReporting) { super(configRegistryClient, netconfSessionIdForReporting); this.yangStoreSnapshot = yangStoreSnapshot; - this.transactionProvider = transactionProvider; } private Map> createModuleRuntimes(ConfigRegistryClient configRegistryClient, @@ -68,7 +62,7 @@ public class Get extends AbstractConfigNetconfOperation { Map cache = Maps.newHashMap(); RuntimeBeanEntry root = null; for (RuntimeBeanEntry rbe : mbe.getRuntimeBeans()) { - cache.put(rbe, new InstanceConfig(configRegistryClient, rbe.getYangPropertiesToTypesMap())); + cache.put(rbe, new InstanceConfig(configRegistryClient, rbe.getYangPropertiesToTypesMap(), mbe.getNullableDummyContainerName())); if (rbe.isRoot()){ root = rbe; } @@ -79,7 +73,7 @@ public class Get extends AbstractConfigNetconfOperation { } InstanceRuntime rootInstanceRuntime = createInstanceRuntime(root, cache); - ModuleRuntime moduleRuntime = new ModuleRuntime(module, rootInstanceRuntime); + ModuleRuntime moduleRuntime = new ModuleRuntime(rootInstanceRuntime); innerMap.put(module, moduleRuntime); } @@ -137,9 +131,7 @@ public class Get extends AbstractConfigNetconfOperation { final Runtime runtime = new Runtime(moduleRuntimes, moduleConfigs); - ObjectName txOn = transactionProvider.getOrCreateTransaction(); - ConfigTransactionClient ta = getConfigRegistryClient().getConfigTransactionClient(txOn); - final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta)); + final Element element = runtime.toXml(runtimeBeans, configBeans, document); logger.trace("{} operation successful", XmlNetconfConstants.GET); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java index 82e07c1e7b..03e0176e32 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java @@ -76,7 +76,7 @@ public class GetConfig extends AbstractConfigNetconfOperation { } private Element getResponseInternal(final Document document, final ConfigRegistryClient configRegistryClient, - final Datastore source) throws NetconfDocumentedException { + final Datastore source) { Element dataElement = XmlUtil.createElement(document, XmlNetconfConstants.DATA_KEY, Optional.absent()); final Set instances = Datastore.getInstanceQueryStrategy(source, this.transactionProvider) .queryInstances(configRegistryClient); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java index 7790e09cee..98eb176999 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java @@ -56,7 +56,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { } private Element toXml(Document doc, Object result, AttributeIfc returnType, String namespace, String elementName) throws NetconfDocumentedException { - AttributeMappingStrategy> mappingStrategy = new ObjectMapper(null).prepareStrategy(returnType); + AttributeMappingStrategy> mappingStrategy = new ObjectMapper().prepareStrategy(returnType); Optional mappedAttributeOpt = mappingStrategy.mapAttribute(result); Preconditions.checkState(mappedAttributeOpt.isPresent(), "Unable to map return value %s as %s", result, returnType.getOpenType()); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java index 7f4f8fccb5..30873d9534 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java @@ -49,7 +49,7 @@ final class NetconfOperationProvider { ops.add(new EditConfig(yangStoreSnapshot, transactionProvider, configRegistryClient, netconfSessionIdForReporting)); ops.add(new Commit(transactionProvider, configRegistryClient, netconfSessionIdForReporting)); - ops.add(new Get(yangStoreSnapshot, configRegistryClient, netconfSessionIdForReporting, transactionProvider)); + ops.add(new Get(yangStoreSnapshot, configRegistryClient, netconfSessionIdForReporting)); ops.add(new DiscardChanges(transactionProvider, configRegistryClient, netconfSessionIdForReporting)); ops.add(new Validate(transactionProvider, configRegistryClient, netconfSessionIdForReporting)); ops.add(new RuntimeRpc(yangStoreSnapshot, configRegistryClient, netconfSessionIdForReporting)); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java index 250af688ea..beab62e997 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/transactions/TransactionProvider.java @@ -156,17 +156,16 @@ public class TransactionProvider implements AutoCloseable { } public void wipeTestTransaction(ObjectName taON) { - wipeInternal(taON, true, null); + wipeInternal(taON, true); } /** * Wiping means removing all module instances keeping the transaction open + service references. */ - synchronized void wipeInternal(ObjectName taON, boolean isTest, String moduleName) { + synchronized void wipeInternal(ObjectName taON, boolean isTest) { ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON); - Set lookupConfigBeans = moduleName == null ? transactionClient.lookupConfigBeans() - : transactionClient.lookupConfigBeans(moduleName); + Set lookupConfigBeans = transactionClient.lookupConfigBeans(); int i = lookupConfigBeans.size(); for (ObjectName instance : lookupConfigBeans) { try { @@ -190,7 +189,7 @@ public class TransactionProvider implements AutoCloseable { public void wipeTransaction() { Optional taON = getTransaction(); Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); - wipeInternal(taON.get(), false, null); + wipeInternal(taON.get(), false); } } 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 f8d21e401c..41301543a3 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 @@ -24,6 +24,7 @@ import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElem import com.google.common.base.Optional; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -39,6 +40,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; @@ -75,6 +77,7 @@ import org.opendaylight.controller.config.yang.test.impl.IdentityTestModuleFacto import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory; import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean; import org.opendaylight.controller.config.yang.test.impl.Peers; +import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory; import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit; @@ -93,7 +96,6 @@ import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; import org.opendaylight.controller.netconf.mapping.api.NetconfOperation; import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution; import org.opendaylight.controller.netconf.util.test.XmlFileLoader; -import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.test.types.rev131127.TestIdentity1; @@ -124,6 +126,7 @@ public class NetconfMappingTest extends AbstractConfigTest { private NetconfTestImplModuleFactory factory; private DepTestImplModuleFactory factory2; private IdentityTestModuleFactory factory3; + private TestImplModuleFactory factory4; @Mock YangStoreSnapshot yangStoreSnapshot; @@ -144,8 +147,9 @@ public class NetconfMappingTest extends AbstractConfigTest { this.factory = new NetconfTestImplModuleFactory(); this.factory2 = new DepTestImplModuleFactory(); this.factory3 = new IdentityTestModuleFactory(); + factory4 = new TestImplModuleFactory(); super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, this.factory, this.factory2, - this.factory3)); + this.factory3, factory4)); transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID); } @@ -194,33 +198,33 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig.xml"); Document config = getConfigCandidate(); - assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1")); edit("netconfMessages/editConfig_addServiceName.xml"); config = getConfigCandidate(); - assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1", "ref_dep_user_another")); edit("netconfMessages/editConfig_addServiceNameOnTest.xml"); config = getConfigCandidate(); - assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1", "ref_dep_user_another")); commit(); config = getConfigRunning(); assertCorrectRefNamesForDependencies(config); - assertCorrectServiceNames(config, Sets.newHashSet("ref_test2", "user_to_instance_from_code", "ref_dep_user", + assertCorrectServiceNames(config, Sets.newHashSet("user_to_instance_from_code", "ref_dep_user", "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1", "ref_from_code_to_instance-from-code_1", "ref_dep_user_another")); edit("netconfMessages/editConfig_replace_default.xml"); config = getConfigCandidate(); - assertCorrectServiceNames(config, Sets.newHashSet("ref_dep", "ref_dep2")); + assertCorrectServiceNames(config, Collections.emptySet()); edit("netconfMessages/editConfig_remove.xml"); config = getConfigCandidate(); @@ -259,8 +263,8 @@ public class NetconfMappingTest extends AbstractConfigTest { nt.performTest(tester, Node.TEXT_NODE); } - private void assertCorrectServiceNames(Document configCandidate, final Set refNames) throws NodeTestException { - + private void assertCorrectServiceNames(Document configCandidate, Set refNames) throws NodeTestException { + final Set refNames2 = new HashSet<>(refNames); NodeList servicesNodes = configCandidate.getElementsByTagName("services"); assertEquals(1, servicesNodes.getLength()); @@ -272,9 +276,8 @@ public class NetconfMappingTest extends AbstractConfigTest { if(element.getNodeName() != null) { if(element.getNodeName().equals("name")) { String elmText = element.getTextContent(); - if(refNames.contains(elmText)) { - refNames.remove(elmText); - return; + if(refNames2.contains(elmText)) { + refNames2.remove(elmText); } else { throw new NodeTestException("Unexpected services defined: " + elmText); } @@ -284,7 +287,8 @@ public class NetconfMappingTest extends AbstractConfigTest { @Override public void noMoreNodes(NodeTest forTest) throws NodeTestException { - assertTrue(refNames.isEmpty()); + assertEquals(Collections.emptySet(), refNames2); + assertTrue(refNames2.toString(), refNames2.isEmpty()); } }; nt.performTest(tester, Node.ELEMENT_NODE); @@ -423,42 +427,42 @@ public class NetconfMappingTest extends AbstractConfigTest { assertEquals(2, afterReplace); } - @Test(expected = NetconfDocumentedException.class) + @Test public void testSameAttrDifferentNamespaces() throws Exception { try { edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml"); + fail(); } catch (NetconfDocumentedException e) { String message = e.getMessage(); - assertContainsString(message, "Element simple-long-2 present multiple times with different namespaces"); + assertContainsString(message, "Element simpleInt present multiple times with different namespaces"); assertContainsString(message, TEST_NAMESPACE); assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); - throw e; } } - @Test(expected = NetconfDocumentedException.class) + @Test public void testDifferentNamespaceInTO() throws Exception { try { edit("netconfMessages/namespaces/editConfig_differentNamespaceTO.xml"); + fail(); } catch (NetconfDocumentedException e) { String message = e.getMessage(); assertContainsString(message, "Unrecognised elements"); assertContainsString(message, "simple-int2"); assertContainsString(message, "dto_d"); - throw e; } } - @Test(expected = NetconfDocumentedException.class) + @Test public void testSameAttrDifferentNamespacesList() throws Exception { try { edit("netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml"); + fail(); } catch (NetconfDocumentedException e) { String message = e.getMessage(); - assertContainsString(message, "Element binaryLeaf present multiple times with different namespaces"); + assertContainsString(message, "Element allow-user present multiple times with different namespaces"); assertContainsString(message, TEST_NAMESPACE); assertContainsString(message, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); - throw e; } } @@ -491,6 +495,7 @@ public class NetconfMappingTest extends AbstractConfigTest { for (int i = 0; i < TESTS_COUNT; i++) { String file = String.format(format, i + 1); + logger.info("Reading {}", file); try { edit(file); } catch (NetconfDocumentedException e) { @@ -564,23 +569,13 @@ public class NetconfMappingTest extends AbstractConfigTest { assertThat(string, JUnitMatchers.containsString(substring)); } - private void checkEnum(final Document response) throws NetconfDocumentedException { - XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data") - .getOnlyChildElement("modules"); + private void checkEnum(final Document response) throws Exception { - String enumName = "extended-enum"; - String enumContent = "TWO"; + String expectedEnumContent = "TWO"; - for (XmlElement moduleElement : modulesElement.getChildElements("module")) { - String name = moduleElement.getOnlyChildElement("name").getTextContent(); - if(name.equals(INSTANCE_NAME)) { - XmlElement enumAttr = moduleElement.getOnlyChildElement(enumName); - assertEquals(enumContent, enumAttr.getTextContent()); - return; - } - } - - fail("Enum attribute " + enumName + ":" + enumContent + " not present in " + XmlUtil.toString(response)); + XMLAssert.assertXpathEvaluatesTo(expectedEnumContent, + getXpathForNetconfImplSubnode(INSTANCE_NAME,"extended-enum"), + response); } private void checkTestingDeps(Document response) { @@ -588,24 +583,23 @@ public class NetconfMappingTest extends AbstractConfigTest { assertEquals(2, testingDepsSize); } - private void checkTypeConfigAttribute(Document response) throws NetconfDocumentedException { - - XmlElement modulesElement = XmlElement.fromDomElement(response.getDocumentElement()).getOnlyChildElement("data") - .getOnlyChildElement("modules"); - - List expectedValues = Lists.newArrayList("default-string", "configAttributeType"); - Set configAttributeType = Sets.newHashSet(); + private String getXpathForNetconfImplSubnode(String instanceName, String subnode) { + return "/urn:ietf:params:xml:ns:netconf:base:1.0:rpc-reply" + + "/urn:ietf:params:xml:ns:netconf:base:1.0:data" + + "/urn:opendaylight:params:xml:ns:yang:controller:config:modules" + + "/module[name='"+instanceName+"']" + + "/urn:opendaylight:params:xml:ns:yang:controller:test:impl:impl-netconf" + + "/urn:opendaylight:params:xml:ns:yang:controller:test:impl:"+subnode; + } - for (XmlElement moduleElement : modulesElement.getChildElements("module")) { - for (XmlElement type : moduleElement.getChildElements("type")) { - if (type.getNamespaceOptionally().isPresent()) { - configAttributeType.add(type.getTextContent()); - } - } - } + private void checkTypeConfigAttribute(Document response) throws Exception { - for (String expectedValue : expectedValues) { - assertTrue(configAttributeType.contains(expectedValue)); + Map namesToTypeValues = ImmutableMap.of("instance-from-code", "configAttributeType", + "test2", "default-string"); + for (Entry nameToExpectedValue : namesToTypeValues.entrySet()) { + XMLAssert.assertXpathEvaluatesTo(nameToExpectedValue.getValue(), + getXpathForNetconfImplSubnode(nameToExpectedValue.getKey(),"type"), + response); } } @@ -688,7 +682,7 @@ public class NetconfMappingTest extends AbstractConfigTest { } private Document get() throws NetconfDocumentedException, ParserConfigurationException, SAXException, IOException { - Get getOp = new Get(yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID, transactionProvider); + Get getOp = new Get(yangStoreSnapshot, configRegistryClient, NETCONF_SESSION_ID); return executeOp(getOp, "netconfMessages/get.xml"); } diff --git a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java index 57bd3dd620..1ecbc55b2a 100644 --- a/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java +++ b/opendaylight/netconf/netconf-api/src/main/java/org/opendaylight/controller/netconf/api/NetconfDocumentedException.java @@ -62,6 +62,14 @@ public class NetconfDocumentedException extends Exception { private final ErrorSeverity errorSeverity; private final Map errorInfo; + public NetconfDocumentedException(String message) { + this(message, + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error + ); + } + public NetconfDocumentedException(final String message, final ErrorType errorType, final ErrorTag errorTag, final ErrorSeverity errorSeverity) { this(message, errorType, errorTag, errorSeverity, Collections. emptyMap()); diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java index 29afa93d37..148b0446e3 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java @@ -144,12 +144,12 @@ public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest { notificationVerifier.assertNotificationCount(2); notificationVerifier.assertNotificationContent(0, 0, 0, 9); - notificationVerifier.assertNotificationContent(1, 4, 4, 9); + notificationVerifier.assertNotificationContent(1, 4, 3, 9); mockedAggregator.assertSnapshotCount(2); // Capabilities are stripped for persister mockedAggregator.assertSnapshotContent(0, 0, 0, 1); - mockedAggregator.assertSnapshotContent(1, 4, 4, 3); + mockedAggregator.assertSnapshotContent(1, 4, 3, 3); } private VerifyingPersister mockAggregator() throws IOException { diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java index ff950e95e9..c6974d4982 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/NetconfSSHServer.java @@ -27,7 +27,7 @@ public final class NetconfSSHServer implements Runnable { private static final AtomicLong sesssionId = new AtomicLong(); private final InetSocketAddress clientAddress; private final AuthProvider authProvider; - private boolean up = false; + private volatile boolean up = false; private NetconfSSHServer(int serverPort,InetSocketAddress clientAddress, AuthProvider authProvider) throws IllegalStateException, IOException { @@ -68,9 +68,17 @@ public final class NetconfSSHServer implements Runnable { while (up) { logger.trace("Starting new socket thread."); try { - SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(), authProvider); - } catch (IOException e) { - logger.error("Exception occurred during socket thread initialization {}", e); + SocketThread.start(ss.accept(), clientAddress, sesssionId.incrementAndGet(), authProvider); + } + catch (IOException e) { + if( up ) { + logger.error("Exception occurred during socket thread initialization", e); + } + else { + // We're shutting down so an exception is expected as the socket's been closed. + // Log to debug. + logger.debug("Shutting down - got expected exception: " + e); + } } } } diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java index e8a453e5d3..e0d432f27c 100644 --- a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java +++ b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/test/XmlUnitUtil.java @@ -16,6 +16,7 @@ import org.custommonkey.xmlunit.AbstractNodeTester; import org.custommonkey.xmlunit.NodeTest; import org.custommonkey.xmlunit.NodeTestException; import org.custommonkey.xmlunit.NodeTester; +import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -88,7 +89,7 @@ public class XmlUnitUtil { @Override public void noMoreNodes(NodeTest forTest) throws NodeTestException { - assertTrue(elementFound); + assertTrue(XmlUtil.toString(doc), elementFound); } }; assertNodeTestPasses(nt, tester, new short[]{Node.ELEMENT_NODE}, true); 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 35cf2c6a14..5dd5a90f7d 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig.xml @@ -30,78 +30,79 @@ instance-from-code + + + 2.58 + - - 2.58 - + + 10 + - - 10 - + + 20 + - - 20 - + + TWO + - - TWO - + 44 + YmluYXJ5 - 44 - YmluYXJ5 - - configAttributeType - - 444 - 4444 - 454 - - 44 - - 4 - + configAttributeType + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep_user - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + + prefix:testing + ref_dep_user + - - prefix:testing - ref_dep_user - - - prefix:testing - ref_dep_user_two - + + prefix:testing + ref_dep_user + + + prefix:testing + ref_dep_user_two + + @@ -109,12 +110,13 @@ test-impl:impl-netconf test2 - 4 - - - prefix:testing - ref_dep_user_two - + + 4 + + prefix:testing + ref_dep_user_two + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml index ade40f6a49..be3155222a 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.xml @@ -26,46 +26,48 @@ test-impl:impl-netconf instance-from-code - 44 - 8ad1 - - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 8ad1 + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml index 21db4b8e42..3f088e48c9 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_setUnions.xml @@ -15,10 +15,10 @@ instance-from-code - - 127.1.2.3 - randomStringForUnion - + + 127.1.2.3 + randomStringForUnion + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_differentNamespaceTO.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_differentNamespaceTO.xml index df2a5e8452..16947f9ec7 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_differentNamespaceTO.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_differentNamespaceTO.xml @@ -30,52 +30,53 @@ test1 - - 44 - 8545649856 - configAttributeType - - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 8545649856 + configAttributeType + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + + prefix:testing + ref_dep + + @@ -83,10 +84,12 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml index c399c196d3..3dbaef4042 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespaces.xml @@ -24,61 +24,70 @@ + + + test-impl:impl + + + testimpl + 1 + 2 + + test-impl:impl-netconf test1 - - 44 - 44 - 8 - 1 - 0 - configAttributeType - - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 44 + + configAttributeType + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + + prefix:testing + ref_dep + + @@ -86,10 +95,12 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml index 47b82c6114..6ee97ee09c 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_sameAttrDifferentNamespacesList.xml @@ -26,58 +26,12 @@ - test-impl:impl-netconf + test-impl:impl test1 - - 44 - 8 - 1 - 0 - configAttributeType - - 444 - 4444 - 454 - - 44 - - 4 - - 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep - + 1 + 2 @@ -85,33 +39,17 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + - - prefix:testing - - ref_dep - /modules/module[type='impl-dep'][name='dep'] - - - - ref_dep_2 - /modules/module[type='impl-dep'][name='dep2'] - - - - ref_test1 - - /modules/module[type='impl-netconf'][name='test1'] - - - + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml index 02aca8d787..1e5c6da79c 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/namespaces/editConfig_typeNameConfigAttributeMatching.xml @@ -30,51 +30,52 @@ test1 - - 44 - 8545649856 - - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 8545649856 + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + + prefix:testing + ref_dep + + @@ -82,10 +83,12 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised7.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised7.xml index 825be6d19f..156c111408 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised7.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised7.xml @@ -30,52 +30,53 @@ test1 - - 44 - 8545649856 - - error - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 8545649856 + + error + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - - - prefix:testing - ref_dep - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + + + prefix:testing + ref_dep + + @@ -83,10 +84,12 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised8.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised8.xml index 9ef2bed7d7..9b9157e65a 100644 --- a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised8.xml +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/unrecognised/editConfig_unrecognised8.xml @@ -30,52 +30,53 @@ test1 - - 44 - 8545649856 - - 444 - 4444 - 454 - - 44 - - 4 - + + 44 + 8545649856 + + 444 + 4444 + 454 + + 44 + + 4 + + 4 + 4 - - 4 - - 44 - 545 - 454545 - false - - - - 456 - - 44 - - - 4 - 999 - 4 - - port1 - 456 - 44 - - - port23 - 456 - 44 - error - - - prefix:testing - ref_dep - + + 44 + 545 + 454545 + false + + + + 456 + + 44 + + + 4 + 999 + 4 + + port1 + 456 + 44 + + + port23 + 456 + 44 + error + + + prefix:testing + ref_dep + + @@ -83,10 +84,12 @@ test-impl:impl-netconf test2 - - prefix:testing - ref_dep - + + + prefix:testing + ref_dep + + diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java index c30f659032..f101538196 100644 --- a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java @@ -22,6 +22,8 @@ import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD; import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleCRUD; import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase; public class Activator extends ComponentActivatorAbstractBase { @@ -163,5 +165,37 @@ public class Activator extends ComponentActivatorAbstractBase { "setConfigurationContainerService", "unsetConfigurationContainerService").setRequired(true)); } + if (imp.equals(NeutronSecurityGroupInterface.class)) { + // export the service + c.setInterface( + new String[] { INeutronSecurityGroupCRUD.class.getName(), + IConfigurationContainerAware.class.getName()}, null); + Dictionary props = new Hashtable(); + props.put("salListenerName", "neutron"); + c.add(createContainerServiceDependency(containerName) + .setService(IClusterContainerServices.class) + .setCallbacks("setClusterContainerService", + "unsetClusterContainerService").setRequired(true)); + c.add(createContainerServiceDependency(containerName).setService( + IConfigurationContainerService.class).setCallbacks( + "setConfigurationContainerService", + "unsetConfigurationContainerService").setRequired(true)); + } + if (imp.equals(NeutronSecurityRuleInterface.class)) { + // export the service + c.setInterface( + new String[] { INeutronSecurityRuleCRUD.class.getName(), + IConfigurationContainerAware.class.getName()}, null); + Dictionary props = new Hashtable(); + props.put("salListenerName", "neutron"); + c.add(createContainerServiceDependency(containerName) + .setService(IClusterContainerServices.class) + .setCallbacks("setClusterContainerService", + "unsetClusterContainerService").setRequired(true)); + c.add(createContainerServiceDependency(containerName).setService( + IConfigurationContainerService.class).setCallbacks( + "setConfigurationContainerService", + "unsetConfigurationContainerService").setRequired(true)); + } } } diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityGroupInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityGroupInterface.java new file mode 100644 index 0000000000..a991f61fcb --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityGroupInterface.java @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron.implementation; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Map.Entry; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import org.apache.felix.dm.Component; +import org.opendaylight.controller.clustering.services.CacheConfigException; +import org.opendaylight.controller.clustering.services.CacheExistException; +import org.opendaylight.controller.clustering.services.IClusterContainerServices; +import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.ConfigurationObject; +import org.opendaylight.controller.configuration.IConfigurationContainerAware; +import org.opendaylight.controller.configuration.IConfigurationContainerService; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD; +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup; +import org.opendaylight.controller.sal.utils.IObjectReader; +import org.opendaylight.controller.sal.utils.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class NeutronSecurityGroupInterface implements INeutronSecurityGroupCRUD, IConfigurationContainerAware, IObjectReader { + private static final Logger logger = LoggerFactory.getLogger(NeutronSecurityGroupInterface.class); + private static final String FILE_NAME ="neutron.securitygroup.conf"; + private String containerName = null; + + private IClusterContainerServices clusterContainerService = null; + private IConfigurationContainerService configurationService; + private ConcurrentMap securityGroupDB; + + // methods needed for creating caches + void setClusterContainerService(IClusterContainerServices s) { + logger.debug("Cluster Service set"); + clusterContainerService = s; + } + + void unsetClusterContainerService(IClusterContainerServices s) { + if (clusterContainerService == s) { + logger.debug("Cluster Service removed!"); + clusterContainerService = null; + } + } + + public void setConfigurationContainerService(IConfigurationContainerService service) { + logger.trace("Configuration service set: {}", service); + configurationService = service; + } + + public void unsetConfigurationContainerService(IConfigurationContainerService service) { + logger.trace("Configuration service removed: {}", service); + configurationService = null; + } + + private void allocateCache() { + if (this.clusterContainerService == null) { + logger.error("un-initialized clusterContainerService, can't create cache"); + return; + } + logger.debug("Creating Cache for Neutron Security Groups"); + try { + // neutron caches + this.clusterContainerService.createCache("neutronSecurityGroups", + EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL)); + } catch (CacheConfigException cce) { + logger.error("Cache couldn't be created for Neutron Security Groups - check cache mode"); + } catch (CacheExistException cce) { + logger.error("Cache for Neutron Security Groups already exists, destroy and recreate"); + } + logger.debug("Cache successfully created for Neutron Security Groups"); + } + + @SuppressWarnings({ "unchecked" }) + private void retrieveCache() { + if (clusterContainerService == null) { + logger.error("un-initialized clusterContainerService, can't retrieve cache"); + return; + } + + logger.debug("Retrieving cache for Neutron Security Groups"); + securityGroupDB = (ConcurrentMap) clusterContainerService + .getCache("neutronSecurityGroups"); + if (securityGroupDB == null) { + logger.error("Cache couldn't be retrieved for Neutron Security Groups"); + } + logger.debug("Cache was successfully retrieved for Neutron Security Groups"); + } + + private void destroyCache() { + if (clusterContainerService == null) { + logger.error("un-initialized clusterMger, can't destroy cache"); + return; + } + logger.debug("Destroying Cache for Neutron Security Groups"); + clusterContainerService.destroyCache("neutronSecurityGroups"); + } + + private void startUp() { + allocateCache(); + retrieveCache(); + loadConfiguration(); + } + + /** + * Function called by the dependency manager when all the required + * dependencies are satisfied + * + */ + void init(Component c) { + Dictionary props = c.getServiceProperties(); + if (props != null) { + this.containerName = (String) props.get("containerName"); + logger.debug("Running containerName: {}", this.containerName); + } else { + // In the Global instance case the containerName is empty + this.containerName = ""; + } + startUp(); + } + + /** + * Function called by the dependency manager when at least one dependency + * become unsatisfied or when the component is shutting down because for + * example bundle is being stopped. + * + */ + void destroy() { + destroyCache(); + } + + /** + * Function called by dependency manager after "init ()" is called and after + * the services provided by the class are registered in the service registry + * + */ + void start() { + } + + /** + * Function called by the dependency manager before the services exported by + * the component are unregistered, this will be followed by a "destroy ()" + * calls + * + */ + void stop() { + } + + // this method uses reflection to update an object from it's delta. + + private boolean overwrite(Object target, Object delta) { + Method[] methods = target.getClass().getMethods(); + + for(Method toMethod: methods){ + if(toMethod.getDeclaringClass().equals(target.getClass()) + && toMethod.getName().startsWith("set")){ + + String toName = toMethod.getName(); + String fromName = toName.replace("set", "get"); + + try { + Method fromMethod = delta.getClass().getMethod(fromName); + Object value = fromMethod.invoke(delta, (Object[])null); + if(value != null){ + toMethod.invoke(target, value); + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + } + return true; + } + + @Override + public boolean neutronSecurityGroupExists(String uuid) { + return securityGroupDB.containsKey(uuid); + } + + @Override + public NeutronSecurityGroup getNeutronSecurityGroup(String uuid) { + if (!neutronSecurityGroupExists(uuid)) { + logger.debug("No Security Groups Have Been Defined"); + return null; + } + return securityGroupDB.get(uuid); + } + + @Override + public List getAllNeutronSecurityGroups() { + Set allSecurityGroups = new HashSet(); + for (Entry entry : securityGroupDB.entrySet()) { + NeutronSecurityGroup securityGroup = entry.getValue(); + allSecurityGroups.add(securityGroup); + } + logger.debug("Exiting getSecurityGroups, Found {} OpenStackSecurityGroup", allSecurityGroups.size()); + List ans = new ArrayList(); + ans.addAll(allSecurityGroups); + return ans; + } + + @Override + public boolean addNeutronSecurityGroup(NeutronSecurityGroup input) { + if (neutronSecurityGroupExists(input.getSecurityGroupUUID())) { + return false; + } + securityGroupDB.putIfAbsent(input.getSecurityGroupUUID(), input); + return true; + } + + @Override + public boolean removeNeutronSecurityGroup(String uuid) { + if (!neutronSecurityGroupExists(uuid)) { + return false; + } + securityGroupDB.remove(uuid); + return true; + } + + @Override + public boolean updateNeutronSecurityGroup(String uuid, NeutronSecurityGroup delta) { + if (!neutronSecurityGroupExists(uuid)) { + return false; + } + NeutronSecurityGroup target = securityGroupDB.get(uuid); + return overwrite(target, delta); + } + + @Override + public boolean neutronSecurityGroupInUse(String securityGroupUUID) { + return !neutronSecurityGroupExists(securityGroupUUID); + } + + private void loadConfiguration() { + for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, FILE_NAME)) { + NeutronSecurityGroup nn = (NeutronSecurityGroup) conf; + securityGroupDB.put(nn.getSecurityGroupUUID(), nn); + } + } + + @Override + public Status saveConfiguration() { + return configurationService.persistConfiguration(new ArrayList(securityGroupDB.values()), + FILE_NAME); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + +} \ No newline at end of file diff --git a/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityRuleInterface.java b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityRuleInterface.java new file mode 100644 index 0000000000..5ca907b2b3 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSecurityRuleInterface.java @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron.implementation; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Map.Entry; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; + +import org.apache.felix.dm.Component; +import org.opendaylight.controller.clustering.services.CacheConfigException; +import org.opendaylight.controller.clustering.services.CacheExistException; +import org.opendaylight.controller.clustering.services.IClusterContainerServices; +import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.ConfigurationObject; +import org.opendaylight.controller.configuration.IConfigurationContainerAware; +import org.opendaylight.controller.configuration.IConfigurationContainerService; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleCRUD; +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule; +import org.opendaylight.controller.sal.utils.IObjectReader; +import org.opendaylight.controller.sal.utils.Status; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class NeutronSecurityRuleInterface implements INeutronSecurityRuleCRUD, IConfigurationContainerAware, IObjectReader { + private static final Logger logger = LoggerFactory.getLogger(NeutronSecurityRuleInterface.class); + private static final String FILE_NAME = "neutron.securityrule.conf"; + private String containerName = null; + + private IClusterContainerServices clusterContainerService = null; + private IConfigurationContainerService configurationService; + private ConcurrentMap securityRuleDB; + + // methods needed for creating caches + void setClusterContainerService(IClusterContainerServices s) { + logger.debug("Cluster Service set"); + clusterContainerService = s; + } + + void unsetClusterContainerService(IClusterContainerServices s) { + if (clusterContainerService == s) { + logger.debug("Cluster Service removed!"); + clusterContainerService = null; + } + } + + public void setConfigurationContainerService(IConfigurationContainerService service) { + logger.trace("Configuration service set: {}", service); + configurationService = service; + } + + public void unsetConfigurationContainerService(IConfigurationContainerService service) { + logger.trace("Configuration service removed: {}", service); + configurationService = null; + } + + private void allocateCache() { + if (this.clusterContainerService == null) { + logger.error("un-initialized clusterContainerService, can't create cache"); + return; + } + logger.debug("Creating Cache for Neutron Security Rules"); + try { + // neutron caches + this.clusterContainerService.createCache("neutronSecurityRules", + EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL)); + } catch (CacheConfigException cce) { + logger.error("Cache couldn't be created for Neutron Security Rules - check cache mode"); + } catch (CacheExistException cce) { + logger.error("Cache for Neutron Security Rules already exists, destroy and recreate"); + } + logger.debug("Cache successfully created for Neutron Security Rules"); + } + + @SuppressWarnings({"unchecked"}) + private void retrieveCache() { + if (clusterContainerService == null) { + logger.error("un-initialized clusterContainerService, can't retrieve cache"); + return; + } + + logger.debug("Retrieving cache for Neutron Security Rules"); + securityRuleDB = (ConcurrentMap) clusterContainerService + .getCache("neutronSecurityRules"); + if (securityRuleDB == null) { + logger.error("Cache couldn't be retrieved for Neutron Security Rules"); + } + logger.debug("Cache was successfully retrieved for Neutron Security Rules"); + } + + private void destroyCache() { + if (clusterContainerService == null) { + logger.error("un-initialized clusterMger, can't destroy cache"); + return; + } + logger.debug("Destroying Cache for Neutron Security Rules"); + clusterContainerService.destroyCache("neutronSecurityRules"); + } + + private void startUp() { + allocateCache(); + retrieveCache(); + loadConfiguration(); + } + + /** + * Function called by the dependency manager when all the required + * dependencies are satisfied + */ + void init(Component c) { + Dictionary props = c.getServiceProperties(); + if (props != null) { + this.containerName = (String) props.get("containerName"); + logger.debug("Running containerName: {}", this.containerName); + } else { + // In the Global instance case the containerName is empty + this.containerName = ""; + } + startUp(); + } + + /** + * Function called by the dependency manager when at least one dependency + * become unsatisfied or when the component is shutting down because for + * example bundle is being stopped. + */ + void destroy() { + destroyCache(); + } + + /** + * Function called by dependency manager after "init ()" is called and after + * the services provided by the class are registered in the service registry + */ + void start() { + } + + /** + * Function called by the dependency manager before the services exported by + * the component are unregistered, this will be followed by a "destroy ()" + * calls + */ + void stop() { + } + + // this method uses reflection to update an object from it's delta. + private boolean overwrite(Object target, Object delta) { + Method[] methods = target.getClass().getMethods(); + + for (Method toMethod : methods) { + if (toMethod.getDeclaringClass().equals(target.getClass()) + && toMethod.getName().startsWith("set")) { + + String toName = toMethod.getName(); + String fromName = toName.replace("set", "get"); + + try { + Method fromMethod = delta.getClass().getMethod(fromName); + Object value = fromMethod.invoke(delta, (Object[]) null); + if (value != null) { + toMethod.invoke(target, value); + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + } + return true; + } + + @Override + public boolean neutronSecurityRuleExists(String uuid) { + return securityRuleDB.containsKey(uuid); + } + + @Override + public NeutronSecurityRule getNeutronSecurityRule(String uuid) { + if (!neutronSecurityRuleExists(uuid)) { + logger.debug("No Security Rules Have Been Defined"); + return null; + } + return securityRuleDB.get(uuid); + } + + @Override + public List getAllNeutronSecurityRules() { + Set allSecurityRules = new HashSet(); + for (Entry entry : securityRuleDB.entrySet()) { + NeutronSecurityRule securityRule = entry.getValue(); + allSecurityRules.add(securityRule); + } + logger.debug("Exiting getSecurityRule, Found {} OpenStackSecurityRule", allSecurityRules.size()); + List ans = new ArrayList(); + ans.addAll(allSecurityRules); + return ans; + } + + @Override + public boolean addNeutronSecurityRule(NeutronSecurityRule input) { + if (neutronSecurityRuleExists(input.getSecurityRuleUUID())) { + return false; + } + securityRuleDB.putIfAbsent(input.getSecurityRuleUUID(), input); + return true; + } + + @Override + public boolean removeNeutronSecurityRule(String uuid) { + if (!neutronSecurityRuleExists(uuid)) { + return false; + } + securityRuleDB.remove(uuid); + return true; + } + + @Override + public boolean updateNeutronSecurityRule(String uuid, NeutronSecurityRule delta) { + if (!neutronSecurityRuleExists(uuid)) { + return false; + } + NeutronSecurityRule target = securityRuleDB.get(uuid); + return overwrite(target, delta); + } + + @Override + public boolean neutronSecurityRuleInUse(String securityRuleUUID) { + return !neutronSecurityRuleExists(securityRuleUUID); + } + + private void loadConfiguration() { + for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, FILE_NAME)) { + NeutronSecurityRule nn = (NeutronSecurityRule) conf; + securityRuleDB.put(nn.getSecurityRuleUUID(), nn); + } + } + + @Override + public Status saveConfiguration() { + return configurationService.persistConfiguration(new ArrayList(securityRuleDB.values()), + FILE_NAME); + } + + @Override + public Object readObject(ObjectInputStream ois) throws FileNotFoundException, IOException, ClassNotFoundException { + return ois.readObject(); + } + +} \ No newline at end of file diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupAware.java new file mode 100644 index 0000000000..0fdf77f968 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupAware.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron; + +/** + * This interface defines the methods a service that wishes to be aware of Neutron Security Groups needs to implement + */ + +public interface INeutronSecurityGroupAware { + + /** + * Services provide this interface method to indicate if the specified security group can be created + * + * @param securityGroup instance of proposed new Neutron Security Group object + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the create operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canCreateNeutronSecurityGroup(NeutronSecurityGroup securityGroup); + + /** + * Services provide this interface method for taking action after a security group has been created + * + * @param securityGroup instance of new Neutron Security Group object + * @return void + */ + public void neutronSecurityGroupCreated(NeutronSecurityGroup securityGroup); + + /** + * Services provide this interface method to indicate if the specified security group can be changed using the specified + * delta + * + * @param delta updates to the security group object using patch semantics + * @param original instance of the Neutron Security Group object to be updated + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the update operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canUpdateNeutronSecurityGroup(NeutronSecurityGroup delta, NeutronSecurityGroup original); + + /** + * Services provide this interface method for taking action after a security group has been updated + * + * @param securityGroup instance of modified Neutron Security Group object + * @return void + */ + public void neutronSecurityGroupUpdated(NeutronSecurityGroup securityGroup); + + /** + * Services provide this interface method to indicate if the specified security group can be deleted + * + * @param securityGroup instance of the Neutron Security Group object to be deleted + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the delete operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canDeleteNeutronSecurityGroup(NeutronSecurityGroup securityGroup); + + /** + * Services provide this interface method for taking action after a security group has been deleted + * + * @param securityGroup instance of deleted Neutron Security Group object + * @return void + */ + public void neutronSecurityGroupDeleted(NeutronSecurityGroup securityGroup); +} diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupCRUD.java new file mode 100644 index 0000000000..a408ef92a7 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityGroupCRUD.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron; + +import java.util.List; + +/** + * This interface defines the methods for CRUD of NB OpenStack Security Group objects + */ + +public interface INeutronSecurityGroupCRUD { + /** + * Applications call this interface method to determine if a particular + * Security Group object exists + * + * @param uuid UUID of the Security Group object + * @return boolean + */ + + public boolean neutronSecurityGroupExists(String uuid); + + /** + * Applications call this interface method to return if a particular + * Security Group object exists + * + * @param uuid UUID of the Security Group object + * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup.OpenStackSecurity Groups} + * OpenStack Security Group class + */ + + public NeutronSecurityGroup getNeutronSecurityGroup(String uuid); + + /** + * Applications call this interface method to return all Security Group objects + * + * @return List of OpenStackSecurity Groups objects + */ + + public List getAllNeutronSecurityGroups(); + + /** + * Applications call this interface method to add a Security Group object to the + * concurrent map + * + * @param input OpenStackSecurity Group object + * @return boolean on whether the object was added or not + */ + + public boolean addNeutronSecurityGroup(NeutronSecurityGroup input); + + /** + * Applications call this interface method to remove a Neutron Security Group object to the + * concurrent map + * + * @param uuid identifier for the security group object + * @return boolean on whether the object was removed or not + */ + + public boolean removeNeutronSecurityGroup(String uuid); + + /** + * Applications call this interface method to edit a Security Group object + * + * @param uuid identifier of the security group object + * @param delta OpenStackSecurity Group object containing changes to apply + * @return boolean on whether the object was updated or not + */ + + public boolean updateNeutronSecurityGroup(String uuid, NeutronSecurityGroup delta); + + /** + * Applications call this interface method to see if a MAC address is in use + * + * @param uuid identifier of the security group object + * @return boolean on whether the Security Groups is already in use + */ + + public boolean neutronSecurityGroupInUse(String uuid); + +} diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleAware.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleAware.java new file mode 100644 index 0000000000..ff2a1c4978 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleAware.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron; + +/** + * This interface defines the methods required to be aware of Neutron Security Rules + */ + +public interface INeutronSecurityRuleAware { + + /** + * Services provide this interface method to indicate if the specified security rule can be created + * + * @param securityRule instance of proposed new Neutron Security Rule object + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the create operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canCreateNeutronSecurityRule(NeutronSecurityRule securityRule); + + /** + * Services provide this interface method for taking action after a security rule has been created + * + * @param securityRule instance of new Neutron Security Rule object + * @return void + */ + public void neutronSecurityRuleCreated(NeutronSecurityRule securityRule); + + /** + * Services provide this interface method to indicate if the specified security rule can be changed using the specified + * delta + * + * @param delta updates to the security rule object using patch semantics + * @param original instance of the Neutron Security Rule object to be updated + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the update operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canUpdateNeutronSecurityRule(NeutronSecurityRule delta, NeutronSecurityRule original); + + /** + * Services provide this interface method for taking action after a security rule has been updated + * + * @param securityRule instance of modified Neutron Security Rule object + * @return void + */ + public void neutronSecurityRuleUpdated(NeutronSecurityRule securityRule); + + /** + * Services provide this interface method to indicate if the specified security rule can be deleted + * + * @param securityRule instance of the Neutron Security Rule object to be deleted + * @return integer + * the return value is understood to be a HTTP status code. A return value outside of 200 through 299 + * results in the delete operation being interrupted and the returned status value reflected in the + * HTTP response. + */ + public int canDeleteNeutronSecurityRule(NeutronSecurityRule securityRule); + + /** + * Services provide this interface method for taking action after a security rule has been deleted + * + * @param securityRule instance of deleted Neutron Security Rule object + * @return void + */ + public void neutronSecurityRuleDeleted(NeutronSecurityRule securityRule); +} diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleCRUD.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleCRUD.java new file mode 100644 index 0000000000..73b41c71a4 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSecurityRuleCRUD.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron; + +import java.util.List; + +/** + * This interface defines the methods for CRUD of NB OpenStack Security Rule objects + */ + +public interface INeutronSecurityRuleCRUD { + /** + * Applications call this interface method to determine if a particular + * Security Rule object exists + * + * @param uuid UUID of theSecurity Rule object + * @return boolean + */ + + public boolean neutronSecurityRuleExists(String uuid); + + /** + * Applications call this interface method to return if a particular + * Security Rule object exists + * + * @param uuid UUID of the security rule object + * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule.OpenStackNetworks} + * OpenStackSecurity Rule class + */ + + public NeutronSecurityRule getNeutronSecurityRule(String uuid); + + /** + * Applications call this interface method to return all Security Rule objects + * + * @return List of OpenStack SecurityRules objects + */ + + public List getAllNeutronSecurityRules(); + + /** + * Applications call this interface method to add a Security Rule object to the + * concurrent map + * + * @param input OpenStack security rule object + * @return boolean on whether the object was added or not + */ + + public boolean addNeutronSecurityRule(NeutronSecurityRule input); + + /** + * Applications call this interface method to remove a Neutron Security Rule object to the + * concurrent map + * + * @param uuid identifier for the security rule object + * @return boolean on whether the object was removed or not + */ + + public boolean removeNeutronSecurityRule(String uuid); + + /** + * Applications call this interface method to edit aSecurity Rule object + * + * @param uuid identifier of the security rule object + * @param delta OpenStackSecurity Rule object containing changes to apply + * @return boolean on whether the object was updated or not + */ + + public boolean updateNeutronSecurityRule(String uuid, NeutronSecurityRule delta); + + /** + * Applications call this interface method to see if a MAC address is in use + * + * @param uuid identifier of the security rule object + * @return boolean on whether the macAddress is already associated with a + * port or not + */ + + public boolean neutronSecurityRuleInUse(String uuid); + +} diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java index aebecfa93e..21cfdb1305 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java @@ -36,4 +36,14 @@ public class NeutronCRUDInterfaces { INeutronFloatingIPCRUD answer = (INeutronFloatingIPCRUD) ServiceHelper.getGlobalInstance(INeutronFloatingIPCRUD.class, o); return answer; } -} + + public static INeutronSecurityGroupCRUD getINeutronSecurityGroupCRUD(Object o) { + INeutronSecurityGroupCRUD answer = (INeutronSecurityGroupCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityGroupCRUD.class, o); + return answer; + } + + public static INeutronSecurityRuleCRUD getINeutronSecurityRuleCRUD(Object o) { + INeutronSecurityRuleCRUD answer = (INeutronSecurityRuleCRUD) ServiceHelper.getGlobalInstance(INeutronSecurityRuleCRUD.class, o); + return answer; + } +} \ No newline at end of file diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java index c8ee4e8ccc..680a07453b 100644 --- a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java @@ -61,9 +61,8 @@ public class NeutronPort extends ConfigurationObject implements Serializable { @XmlElement (name="tenant_id") String tenantID; - // TODO: add security groups - // @XmlElement (name="security_groups") - // List securityGroups; + @XmlElement (name="security_groups") + List securityGroups; /* this attribute stores the floating IP address assigned to * each fixed IP address @@ -162,6 +161,14 @@ public class NeutronPort extends ConfigurationObject implements Serializable { this.tenantID = tenantID; } + public List getSecurityGroups() { + return securityGroups; + } + + public void setSecurityGroups(List securityGroups) { + this.securityGroups = securityGroups; + } + public NeutronFloatingIP getFloatingIP(String key) { if (!floatingIPMap.containsKey(key)) { return null; @@ -259,6 +266,6 @@ public class NeutronPort extends ConfigurationObject implements Serializable { return "NeutronPort [portUUID=" + portUUID + ", networkUUID=" + networkUUID + ", name=" + name + ", adminStateUp=" + adminStateUp + ", status=" + status + ", macAddress=" + macAddress + ", fixedIPs=" + fixedIPs + ", deviceID=" + deviceID + ", deviceOwner=" + deviceOwner + ", tenantID=" - + tenantID + ", floatingIPMap=" + floatingIPMap + "]"; + + tenantID + ", floatingIPMap=" + floatingIPMap + ", securityGroups=" + securityGroups + "]"; } } diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityGroup.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityGroup.java new file mode 100644 index 0000000000..0f0a14ca58 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityGroup.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron; + +import org.opendaylight.controller.configuration.ConfigurationObject; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * OpenStack Neutron v2.0 Security Group bindings. + * See OpenStack Network API v2.0 Reference for description of + * annotated attributes. The current fields are as follows: + *

    + * id uuid-str unique ID for the security group. + * name String name of the security group. + * description String name of the security group. + * tenant_id uuid-str Owner of security rule.. + * security_group_rules List nested RO in the sec group. + */ + +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) + +public class NeutronSecurityGroup extends ConfigurationObject implements Serializable { + private static final long serialVersionUID = 1L; + + @XmlElement(name = "id") + String securityGroupUUID; + + @XmlElement(name = "name") + String securityGroupName; + + @XmlElement(name = "description") + String securityGroupDescription; + + @XmlElement(name = "tenant_id") + String securityGroupTenantID; + + @XmlElement(name = "security_group_rules") + List neutronSecurityRule; + + List neutronPorts; + + public NeutronSecurityGroup() { + neutronPorts = new ArrayList (); + List securityRules; + + } + + public String getSecurityGroupUUID() { + return securityGroupUUID; + } + + public void setSecurityGroupUUID(String securityGroupUUID) { + this.securityGroupUUID = securityGroupUUID; + } + + public String getSecurityGroupName() { + return securityGroupName; + } + + public void setSecurityGroupName(String securityGroupName) { + this.securityGroupName = securityGroupName; + } + + public String getSecurityGroupDescription() { + return securityGroupDescription; + } + + public void setSecurityGroupDescription(String securityGroupDescription) { + this.securityGroupDescription = securityGroupDescription; + } + + public String getSecurityGroupTenantID() { + return securityGroupTenantID; + } + + public void setSecurityGroupTenantID(String securityGroupTenantID) { + this.securityGroupTenantID = securityGroupTenantID; + } + + // Rules In Group + public List getSecurityRules() { + return neutronSecurityRule; + } + + public void setSecurityRules(NeutronSecurityRule neutronSecurityRule) { + this.neutronSecurityRule = (List) neutronSecurityRule; + } + + public NeutronSecurityGroup extractFields(List fields) { + NeutronSecurityGroup ans = new NeutronSecurityGroup (); + Iterator i = fields.iterator (); + while (i.hasNext ()) { + String s = i.next (); + if (s.equals ("id")) { + ans.setSecurityGroupUUID (this.getSecurityGroupUUID ()); + } + if (s.equals ("name")) { + ans.setSecurityGroupName (this.getSecurityGroupName ()); + } + if (s.equals ("description")) { + ans.setSecurityGroupDescription (this.getSecurityGroupDescription ()); + } + if (s.equals ("tenant_id")) { + ans.setSecurityGroupTenantID (this.getSecurityGroupTenantID ()); + } + if (s.equals ("security_group_rules")) { + ans.setSecurityRules ((NeutronSecurityRule) this.getSecurityRules ()); + } + } + return ans; + } + + @Override + public String toString() { + return "NeutronSecurityGroup{" + + "securityGroupUUID='" + securityGroupUUID + '\'' + + ", securityGroupName='" + securityGroupName + '\'' + + ", securityGroupDescription='" + securityGroupDescription + '\'' + + ", securityGroupTenantID='" + securityGroupTenantID + '\'' + + ", securityRules=" + neutronSecurityRule + "]"; + } + + public void initDefaults() { + //TODO verify no defaults values are nessecary required. + } +} \ No newline at end of file diff --git a/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityRule.java b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityRule.java new file mode 100644 index 0000000000..3fad4fe626 --- /dev/null +++ b/opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSecurityRule.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron; + +import org.opendaylight.controller.configuration.ConfigurationObject; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; + +/** + * See OpenStack Network API v2.0 Reference for description of + * annotated attributes. The current fields are as follows: + *

    + * id uuid (String) UUID for the security group rule. + * security_rule_id uuid (String) The security group to associate rule. + * direction String Direction the VM traffic (ingress/egress). + * security_group_id The security group to associate rule with. + * protocol String IP Protocol (icmp, tcp, udp, etc). + * port_range_min Integer Port at start of range + * port_range_max Integer Port at end of range + * ethertype String ethertype in L2 packet (IPv4, IPv6, etc) + * remote_ip_prefix String (IP cidr) CIDR for address range. + * remote_group_id uuid-str Source security group to apply to rule. + * tenant_id uuid-str Owner of security rule. Admin only outside tenant. + */ + +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) + +public class NeutronSecurityRule extends ConfigurationObject implements Serializable { + private static final long serialVersionUID = 1L; + + @XmlElement(name = "id") + String securityRuleUUID; + + @XmlElement(name = "direction") + String securityRuleDirection; + + @XmlElement(name = "protocol") + String securityRuleProtocol; + + @XmlElement(name = "port_range_min") + Integer securityRulePortMin; + + @XmlElement(name = " port_range_max") + Integer securityRulePortMax; + + @XmlElement(name = "ethertype") + String securityRuleEthertype; + + @XmlElement(name = "remote_ip_prefix") + String securityRuleRemoteIpPrefix; + + @XmlElement(name = "remote_group_id") + String securityRemoteGroupID; + + @XmlElement(name = "security_group_id") + String securityRuleGroupID; + + @XmlElement(name = "tenant_id") + String securityRuleTenantID; + + public NeutronSecurityRule() { + List securityRules; + } + + public String getSecurityRuleUUID() { + return securityRuleUUID; + } + + public void setSecurityRuleUUID(String securityRuleUUID) { + this.securityRuleUUID = securityRuleUUID; + } + + public String getSecurityRuleDirection() { + return securityRuleDirection; + } + + public void setSecurityRuleDirection(String securityRuleDirection) { + this.securityRuleDirection = securityRuleDirection; + } + + public String getSecurityRuleProtocol() { + return securityRuleProtocol; + } + + public void setSecurityRuleProtocol(String securityRuleProtocol) { + this.securityRuleProtocol = securityRuleProtocol; + } + + public Integer getSecurityRulePortMin() { + return securityRulePortMin; + } + + public void setSecurityRulePortMin(Integer securityRulePortMin) { + this.securityRulePortMin = securityRulePortMin; + } + + public Integer getSecurityRulePortMax() { + return securityRulePortMax; + } + + public void setSecurityRulePortMax(Integer securityRulePortMax) { + this.securityRulePortMax = securityRulePortMax; + } + + public String getSecurityRuleEthertype() { + return securityRuleEthertype; + } + + public void setSecurityRuleEthertype(String securityRuleEthertype) { + this.securityRuleEthertype = securityRuleEthertype; + } + + public String getSecurityRuleRemoteIpPrefix() { + return securityRuleRemoteIpPrefix; + } + + public void setSecurityRuleRemoteIpPrefix(String securityRuleRemoteIpPrefix) { + this.securityRuleRemoteIpPrefix = securityRuleRemoteIpPrefix; + } + + public String getSecurityRemoteGroupID() { + return securityRemoteGroupID; + } + + public void setSecurityRemoteGroupID(String securityRemoteGroupID) { + this.securityRemoteGroupID = securityRemoteGroupID; + } + + public String getSecurityRuleGroupID() { + return securityRuleGroupID; + } + + public void setSecurityRuleGroupID(String securityRuleGroupID) { + this.securityRuleGroupID = securityRuleGroupID; + } + + public String getSecurityRuleTenantID() { + return securityRuleTenantID; + } + + public void setSecurityRuleTenantID(String securityRuleTenantID) { + this.securityRuleTenantID = securityRuleTenantID; + } + + public NeutronSecurityRule extractFields(List fields) { + NeutronSecurityRule ans = new NeutronSecurityRule(); + Iterator i = fields.iterator(); + while (i.hasNext()) { + String s = i.next(); + if (s.equals("id")) { + ans.setSecurityRuleUUID(this.getSecurityRuleUUID()); + } + if (s.equals("direction")) { + ans.setSecurityRuleDirection(this.getSecurityRuleDirection()); + } + if (s.equals("protocol")) { + ans.setSecurityRuleProtocol(this.getSecurityRuleProtocol()); + } + if (s.equals("port_range_min")) { + ans.setSecurityRulePortMin(this.getSecurityRulePortMin()); + } + if (s.equals("port_range_max")) { + ans.setSecurityRulePortMax(this.getSecurityRulePortMax()); + } + if (s.equals("ethertype")) { + ans.setSecurityRuleEthertype(this.getSecurityRuleEthertype()); + } + if (s.equals("remote_ip_prefix")) { + ans.setSecurityRuleRemoteIpPrefix(this.getSecurityRuleRemoteIpPrefix()); + } + if (s.equals("remote_group_id")) { + ans.setSecurityRemoteGroupID(this.getSecurityRemoteGroupID()); + } + if (s.equals("security_group_id")) { + ans.setSecurityRuleGroupID(this.getSecurityRuleGroupID()); + } + if (s.equals("tenant_id")) { + ans.setSecurityRuleTenantID(this.getSecurityRuleTenantID()); + } + } + return ans; + } + + @Override + public String toString() { + return "NeutronSecurityRule{" + + "securityRuleUUID='" + securityRuleUUID + '\'' + + ", securityRuleDirection='" + securityRuleDirection + '\'' + + ", securityRuleProtocol='" + securityRuleProtocol + '\'' + + ", securityRulePortMin=" + securityRulePortMin + + ", securityRulePortMax=" + securityRulePortMax + + ", securityRuleEthertype='" + securityRuleEthertype + '\'' + + ", securityRuleRemoteIpPrefix='" + securityRuleRemoteIpPrefix + '\'' + + ", securityRemoteGroupID=" + securityRemoteGroupID + + ", securityRuleGroupID='" + securityRuleGroupID + '\'' + + ", securityRuleTenantID='" + securityRuleTenantID + '\'' + + '}'; + } + + public void initDefaults() { + //TODO verify no defaults values are nessecary required. + } +} \ No newline at end of file diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java index 76c39e4294..3fe03a2dac 100644 --- a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java @@ -32,6 +32,8 @@ public class NeutronNorthboundRSApplication extends Application { classes.add(NeutronPortsNorthbound.class); classes.add(NeutronRoutersNorthbound.class); classes.add(NeutronFloatingIPsNorthbound.class); + classes.add(NeutronSecurityGroupsNorthbound.class); + classes.add(NeutronSecurityRulesNorthbound.class); return classes; } diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupRequest.java new file mode 100644 index 0000000000..6e779d64e2 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupRequest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron.northbound; + +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + + +@XmlRootElement +@XmlAccessorType (XmlAccessType.NONE) + +public class NeutronSecurityGroupRequest { + /** + * See OpenStack Network API v2.0 Reference for a + * description of annotated attributes and operations + */ + + @XmlElement (name = "security_group") + NeutronSecurityGroup singletonSecurityGroup; + + @XmlElement (name = "security_groups") + List bulkRequest; + + NeutronSecurityGroupRequest() { + } + + NeutronSecurityGroupRequest(List bulk) { + bulkRequest = bulk; + singletonSecurityGroup = null; + } + + NeutronSecurityGroupRequest(NeutronSecurityGroup group) { + singletonSecurityGroup = group; + } + + public List getBulk() { + return bulkRequest; + } + + public NeutronSecurityGroup getSingleton() { + return singletonSecurityGroup; + } + + public boolean isSingleton() { + return (singletonSecurityGroup != null); + } +} \ No newline at end of file diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupsNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupsNorthbound.java new file mode 100644 index 0000000000..5e9a3318b9 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityGroupsNorthbound.java @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron.northbound; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.codehaus.enunciate.jaxrs.ResponseCode; +import org.codehaus.enunciate.jaxrs.StatusCodes; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupAware; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD; +import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces; +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup; +import org.opendaylight.controller.northbound.commons.RestMessages; +import org.opendaylight.controller.northbound.commons.exception.BadRequestException; +import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException; +import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException; +import org.opendaylight.controller.sal.utils.ServiceHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Neutron Northbound REST APIs for Security Group.
    + * This class provides REST APIs for managing neutron Security Group + *

    + *
    + *
    + * Authentication scheme : HTTP Basic
    + * Authentication realm : opendaylight
    + * Transport : HTTP and HTTPS
    + *
    + * HTTPS Authentication is disabled by default. Administrator can enable it in + * tomcat-server.xml after adding a proper keystore / SSL certificate from a + * trusted authority.
    + * More info : + * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration + */ +@Path ("/security-groups") +public class NeutronSecurityGroupsNorthbound { + static final Logger logger = LoggerFactory.getLogger(NeutronSecurityGroupsNorthbound.class); + + private NeutronSecurityGroup extractFields(NeutronSecurityGroup o, List fields) { + return o.extractFields(fields); + } + + /** + * Returns a list of all Security Groups + */ + @GET + @Produces ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + + public Response listGroups( + // return fields + @QueryParam ("fields") List fields, + // OpenStack security group attributes + @QueryParam ("id") String querySecurityGroupUUID, + @QueryParam ("name") String querySecurityGroupName, + @QueryParam ("description") String querySecurityDescription, + @QueryParam ("tenant_id") String querySecurityTenantID, + @QueryParam ("limit") String limit, + @QueryParam ("marker") String marker, + @QueryParam ("page_reverse") String pageReverse + ) { + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + List allSecurityGroups = securityGroupInterface.getAllNeutronSecurityGroups(); + List ans = new ArrayList(); + Iterator i = allSecurityGroups.iterator(); + while (i.hasNext()) { + NeutronSecurityGroup nsg = i.next(); + if ((querySecurityGroupUUID == null || + querySecurityGroupUUID.equals(nsg.getSecurityGroupUUID())) && + (querySecurityGroupName == null || + querySecurityGroupName.equals(nsg.getSecurityGroupName())) && + (querySecurityDescription == null || + querySecurityDescription.equals(nsg.getSecurityGroupDescription())) && + (querySecurityTenantID == null || + querySecurityTenantID.equals(nsg.getSecurityGroupTenantID()))) { + if (fields.size() > 0) { + ans.add(extractFields(nsg, fields)); + } else { + ans.add(nsg); + } + } + } + return Response.status(200).entity( + new NeutronSecurityGroupRequest(ans)).build(); + } + + /** + * Returns a specific Security Group + */ + + @Path ("{securityGroupUUID}") + @GET + @Produces ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response showSecurityGroup(@PathParam ("securityGroupUUID") String securityGroupUUID, + // return fields + @QueryParam ("fields") List fields) { + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) { + throw new ResourceNotFoundException("Security Group UUID does not exist."); + } + if (!fields.isEmpty()) { + NeutronSecurityGroup ans = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID); + return Response.status(200).entity( + new NeutronSecurityGroupRequest(extractFields(ans, fields))).build(); + } else { + return Response.status(200).entity(new NeutronSecurityGroupRequest(securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID))).build(); + } + } + + /** + * Creates new Security Group + */ + + @POST + @Produces ({MediaType.APPLICATION_JSON}) + @Consumes ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 201, condition = "Created"), + @ResponseCode (code = 400, condition = "Bad Request"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 403, condition = "Forbidden"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 409, condition = "Conflict"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response createSecurityGroups(final NeutronSecurityGroupRequest input) { + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + if (input.isSingleton()) { + NeutronSecurityGroup singleton = input.getSingleton(); + + /* + * Verify that the Security Group doesn't already exist. + */ + if (securityGroupInterface.neutronSecurityGroupExists(singleton.getSecurityGroupUUID())) { + throw new BadRequestException("Security Group UUID already exists"); + } + + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + int status = service.canCreateNeutronSecurityGroup(singleton); + if (status < 200 || status > 299) { + return Response.status(status).build(); + } + } + } + // Add to Neutron cache + securityGroupInterface.addNeutronSecurityGroup(singleton); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + service.neutronSecurityGroupCreated(singleton); + } + } + } else { + List bulk = input.getBulk(); + Iterator i = bulk.iterator(); + HashMap testMap = new HashMap(); + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null); + while (i.hasNext()) { + NeutronSecurityGroup test = i.next(); + + /* + * Verify that the security group doesn't already exist + */ + + if (securityGroupInterface.neutronSecurityGroupExists(test.getSecurityGroupUUID())) { + throw new BadRequestException("Security Group UUID already is already created"); + } + if (instances != null) for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + int status = service.canCreateNeutronSecurityGroup(test); + if ((status < 200) || (status > 299)) return Response.status(status).build(); + } + } + + /* + * now, each element of the bulk request can be added to the cache + */ + i = bulk.iterator(); + while (i.hasNext()) { + NeutronSecurityGroup test = i.next(); + securityGroupInterface.addNeutronSecurityGroup(test); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + service.neutronSecurityGroupCreated(test); + } + } + } + } + return Response.status(201).entity(input).build(); + } + + /** + * Updates a Security Group + */ + + @Path ("{securityGroupUUID}") + @PUT + @Produces ({MediaType.APPLICATION_JSON}) + @Consumes ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 400, condition = "Bad Request"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 403, condition = "Forbidden"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response updateSecurityGroup( + @PathParam ("securityGroupUUID") String securityGroupUUID, final NeutronSecurityGroupRequest input) { + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + /* + * verify the Security Group exists and there is only one delta provided + */ + if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) { + throw new ResourceNotFoundException("Security Group UUID does not exist."); + } + if (!input.isSingleton()) { + throw new BadRequestException("Only singleton edit supported"); + } + NeutronSecurityGroup delta = input.getSingleton(); + NeutronSecurityGroup original = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID); + + if (delta.getSecurityGroupUUID() != null || + delta.getSecurityGroupTenantID() != null || + delta.getSecurityGroupName() != null || + delta.getSecurityGroupDescription() != null) { + throw new BadRequestException("Attribute edit blocked by Neutron"); + } + + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + int status = service.canUpdateNeutronSecurityGroup(delta, original); + if (status < 200 || status > 299) { + return Response.status(status).build(); + } + } + } + + /* + * update the object and return it + */ + securityGroupInterface.updateNeutronSecurityGroup(securityGroupUUID, delta); + NeutronSecurityGroup updatedSecurityGroup = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + service.neutronSecurityGroupUpdated(updatedSecurityGroup); + } + } + return Response.status(200).entity(new NeutronSecurityGroupRequest(securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID))).build(); + } + + /** + * Deletes a Security Group + */ + + @Path ("{securityGroupUUID}") + @DELETE + @StatusCodes ({ + @ResponseCode (code = 204, condition = "No Content"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 409, condition = "Conflict"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response deleteSecurityGroup( + @PathParam ("securityGroupUUID") String securityGroupUUID) { + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + /* + * verify the Security Group exists and it isn't currently in use + */ + if (!securityGroupInterface.neutronSecurityGroupExists(securityGroupUUID)) { + throw new ResourceNotFoundException("Security Group UUID does not exist."); + } + if (securityGroupInterface.neutronSecurityGroupInUse(securityGroupUUID)) { + return Response.status(409).build(); + } + NeutronSecurityGroup singleton = securityGroupInterface.getNeutronSecurityGroup(securityGroupUUID); + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityGroupAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + int status = service.canDeleteNeutronSecurityGroup(singleton); + if ((status < 200) || (status > 299)) { + return Response.status(status).build(); + } + } + } + + /* + * remove it and return 204 status + */ + securityGroupInterface.removeNeutronSecurityGroup(securityGroupUUID); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityGroupAware service = (INeutronSecurityGroupAware) instance; + service.neutronSecurityGroupDeleted(singleton); + } + } + return Response.status(204).build(); + } +} \ No newline at end of file diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRuleRequest.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRuleRequest.java new file mode 100644 index 0000000000..b805bd63bc --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRuleRequest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron.northbound; + +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + + +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) + +public class NeutronSecurityRuleRequest { + /** + * See OpenStack Network API v2.0 Reference for a + * description of annotated attributes and operations + */ + + @XmlElement(name="security_group_rule") + NeutronSecurityRule singletonSecurityRule; + + @XmlElement(name="security_group_rules") + List bulkRequest; + + NeutronSecurityRuleRequest() { + } + + NeutronSecurityRuleRequest(List bulk) { + bulkRequest = bulk; + singletonSecurityRule = null; + } + + NeutronSecurityRuleRequest(NeutronSecurityRule rule) { + singletonSecurityRule = rule; + } + + public NeutronSecurityRule getSingleton() { + return singletonSecurityRule; + } + + public boolean isSingleton() { + return (singletonSecurityRule != null); + } + public List getBulk() { + return bulkRequest; + } + +} \ No newline at end of file diff --git a/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRulesNorthbound.java b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRulesNorthbound.java new file mode 100644 index 0000000000..b2c05e0071 --- /dev/null +++ b/opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSecurityRulesNorthbound.java @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * 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.networkconfig.neutron.northbound; + + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.codehaus.enunciate.jaxrs.ResponseCode; +import org.codehaus.enunciate.jaxrs.StatusCodes; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupCRUD; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleAware; +import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleCRUD; +import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces; +import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule; +import org.opendaylight.controller.northbound.commons.RestMessages; +import org.opendaylight.controller.northbound.commons.exception.BadRequestException; +import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException; +import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException; +import org.opendaylight.controller.sal.utils.ServiceHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Neutron Northbound REST APIs for Security Rule.
    + * This class provides REST APIs for managing neutron Security Rule + *

    + *
    + *
    + * Authentication scheme : HTTP Basic
    + * Authentication realm : opendaylight
    + * Transport : HTTP and HTTPS
    + *
    + * HTTPS Authentication is disabled by default. Administrator can enable it in + * tomcat-server.xml after adding a proper keystore / SSL certificate from a + * trusted authority.
    + * More info : + * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration + */ + +@Path ("/security-group-rules") +public class NeutronSecurityRulesNorthbound { + static final Logger logger = LoggerFactory.getLogger(NeutronSecurityRulesNorthbound.class); + + private NeutronSecurityRule extractFields(NeutronSecurityRule o, List fields) { + return o.extractFields(fields); + } + + /** + * Returns a list of all Security Rules + */ + @GET + @Produces ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response listRules( + // return fields + @QueryParam ("fields") List fields, + // OpenStack security rule attributes + @QueryParam ("id") String querySecurityRuleUUID, + @QueryParam ("direction") String querySecurityRuleDirection, + @QueryParam ("protocol") String querySecurityRuleProtocol, + @QueryParam ("port_range_min") Integer querySecurityRulePortMin, + @QueryParam ("port_range_max") Integer querySecurityRulePortMax, + @QueryParam ("ethertype") String querySecurityRuleEthertype, + @QueryParam ("remote_ip_prefix") String querySecurityRuleIpPrefix, + @QueryParam ("remote_group_id") String querySecurityRemoteGroupID, + @QueryParam ("security_group_id") String querySecurityRuleGroupID, + @QueryParam ("tenant_id") String querySecurityRuleTenantID, + @QueryParam ("limit") String limit, + @QueryParam ("marker") String marker, + @QueryParam ("page_reverse") String pageReverse + ) { + INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this); + if (securityRuleInterface == null) { + throw new ServiceUnavailableException("Security Rule CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + List allSecurityRules = securityRuleInterface.getAllNeutronSecurityRules(); + List ans = new ArrayList(); + Iterator i = allSecurityRules.iterator(); + while (i.hasNext()) { + NeutronSecurityRule nsr = i.next(); + if ((querySecurityRuleUUID == null || + querySecurityRuleUUID.equals(nsr.getSecurityRuleUUID())) && + (querySecurityRuleDirection == null || + querySecurityRuleDirection.equals(nsr.getSecurityRuleDirection())) && + (querySecurityRuleProtocol == null || + querySecurityRuleProtocol.equals(nsr.getSecurityRuleProtocol())) && + (querySecurityRulePortMin == null || + querySecurityRulePortMin.equals(nsr.getSecurityRulePortMin())) && + (querySecurityRulePortMax == null || + querySecurityRulePortMax.equals(nsr.getSecurityRulePortMax())) && + (querySecurityRuleEthertype == null || + querySecurityRuleEthertype.equals(nsr.getSecurityRuleEthertype())) && + (querySecurityRuleIpPrefix == null || + querySecurityRuleIpPrefix.equals(nsr.getSecurityRuleRemoteIpPrefix())) && + (querySecurityRuleGroupID == null || + querySecurityRuleGroupID.equals(nsr.getSecurityRuleGroupID())) && + (querySecurityRemoteGroupID == null || + querySecurityRemoteGroupID.equals(nsr.getSecurityRemoteGroupID())) && + (querySecurityRuleTenantID == null || + querySecurityRuleTenantID.equals(nsr.getSecurityRuleTenantID()))) { + if (fields.size() > 0) { + ans.add(extractFields(nsr, fields)); + } else { + ans.add(nsr); + } + } + } + return Response.status(200).entity( + new NeutronSecurityRuleRequest(ans)).build(); + } + + /** + * Returns a specific Security Rule + */ + + @Path ("{securityRuleUUID}") + @GET + @Produces ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response showSecurityRule(@PathParam ("securityRuleUUID") String securityRuleUUID, + // return fields + @QueryParam ("fields") List fields) { + INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this); + if (securityRuleInterface == null) { + throw new ServiceUnavailableException("Security Rule CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) { + throw new ResourceNotFoundException("Security Rule UUID does not exist."); + } + if (!fields.isEmpty()) { + NeutronSecurityRule ans = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID); + return Response.status(200).entity( + new NeutronSecurityRuleRequest(extractFields(ans, fields))).build(); + } else { + return Response.status(200).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build(); + } + } + + /** + * Creates new Security Rule + */ + + @POST + @Produces ({MediaType.APPLICATION_JSON}) + @Consumes ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 201, condition = "Created"), + @ResponseCode (code = 400, condition = "Bad Request"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 403, condition = "Forbidden"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 409, condition = "Conflict"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response createSecurityRules(final NeutronSecurityRuleRequest input) { + INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this); + if (securityRuleInterface == null) { + throw new ServiceUnavailableException("Security Rule CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + INeutronSecurityGroupCRUD securityGroupInterface = NeutronCRUDInterfaces.getINeutronSecurityGroupCRUD(this); + if (securityGroupInterface == null) { + throw new ServiceUnavailableException("Security Group CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + /* + * Existing entry checks + */ + + if (input.isSingleton()) { + NeutronSecurityRule singleton = input.getSingleton(); + + if (securityRuleInterface.neutronSecurityRuleExists(singleton.getSecurityRuleUUID())) { + throw new BadRequestException("Security Rule UUID already exists"); + } + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + int status = service.canCreateNeutronSecurityRule(singleton); + if ((status < 200) || (status > 299)) { + return Response.status(status).build(); + } + } + } + + // add rule to cache + singleton.initDefaults(); + securityRuleInterface.addNeutronSecurityRule(singleton); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + service.neutronSecurityRuleCreated(singleton); + } + } + + securityRuleInterface.addNeutronSecurityRule(singleton); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + service.neutronSecurityRuleCreated(singleton); + } + } + } else { + List bulk = input.getBulk(); + Iterator i = bulk.iterator(); + HashMap testMap = new HashMap(); + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null); + while (i.hasNext()) { + NeutronSecurityRule test = i.next(); + + /* + * Verify that the security rule doesn't already exist + */ + + if (securityRuleInterface.neutronSecurityRuleExists(test.getSecurityRuleUUID())) { + throw new BadRequestException("Security Rule UUID already exists"); + } + if (testMap.containsKey(test.getSecurityRuleUUID())) { + throw new BadRequestException("Security Rule UUID already exists"); + } + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + int status = service.canCreateNeutronSecurityRule(test); + if ((status < 200) || (status > 299)) { + return Response.status(status).build(); + } + } + } + } + + /* + * now, each element of the bulk request can be added to the cache + */ + i = bulk.iterator(); + while (i.hasNext()) { + NeutronSecurityRule test = i.next(); + securityRuleInterface.addNeutronSecurityRule(test); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + service.neutronSecurityRuleCreated(test); + } + } + } + } + return Response.status(201).entity(input).build(); + } + + /** + * Updates a Security Rule + */ + + @Path ("{securityRuleUUID}") + @PUT + @Produces ({MediaType.APPLICATION_JSON}) + @Consumes ({MediaType.APPLICATION_JSON}) + @StatusCodes ({ + @ResponseCode (code = 200, condition = "Operation successful"), + @ResponseCode (code = 400, condition = "Bad Request"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 403, condition = "Forbidden"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response updateSecurityRule( + @PathParam ("securityRuleUUID") String securityRuleUUID, final NeutronSecurityRuleRequest input) { + INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this); + if (securityRuleInterface == null) { + throw new ServiceUnavailableException("Security Rule CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + /* + * verify the Security Rule exists and there is only one delta provided + */ + if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) { + throw new ResourceNotFoundException("Security Rule UUID does not exist."); + } + if (!input.isSingleton()) { + throw new BadRequestException("Only singleton edit supported"); + } + NeutronSecurityRule delta = input.getSingleton(); + NeutronSecurityRule original = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID); + + /* + * updates restricted by Neutron + * + */ + if (delta.getSecurityRuleUUID() != null || + delta.getSecurityRuleDirection() != null || + delta.getSecurityRuleProtocol() != null || + delta.getSecurityRulePortMin() != null || + delta.getSecurityRulePortMax() != null || + delta.getSecurityRuleEthertype() != null || + delta.getSecurityRuleRemoteIpPrefix() != null || + delta.getSecurityRuleGroupID() != null || + delta.getSecurityRemoteGroupID() != null || + delta.getSecurityRuleTenantID() != null) { + throw new BadRequestException("Attribute edit blocked by Neutron"); + } + + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + int status = service.canUpdateNeutronSecurityRule(delta, original); + if (status < 200 || status > 299) { + return Response.status(status).build(); + } + } + } + + /* + * update the object and return it + */ + securityRuleInterface.updateNeutronSecurityRule(securityRuleUUID, delta); + NeutronSecurityRule updatedSecurityRule = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + service.neutronSecurityRuleUpdated(updatedSecurityRule); + } + } + return Response.status(200).entity(new NeutronSecurityRuleRequest(securityRuleInterface.getNeutronSecurityRule(securityRuleUUID))).build(); + } + + /** + * Deletes a Security Rule + */ + + @Path ("{securityRuleUUID}") + @DELETE + @StatusCodes ({ + @ResponseCode (code = 204, condition = "No Content"), + @ResponseCode (code = 401, condition = "Unauthorized"), + @ResponseCode (code = 404, condition = "Not Found"), + @ResponseCode (code = 409, condition = "Conflict"), + @ResponseCode (code = 501, condition = "Not Implemented")}) + public Response deleteSecurityRule( + @PathParam ("securityRuleUUID") String securityRuleUUID) { + INeutronSecurityRuleCRUD securityRuleInterface = NeutronCRUDInterfaces.getINeutronSecurityRuleCRUD(this); + if (securityRuleInterface == null) { + throw new ServiceUnavailableException("Security Rule CRUD Interface " + + RestMessages.SERVICEUNAVAILABLE.toString()); + } + + /* + * verify the Security Rule exists and it isn't currently in use + */ + if (!securityRuleInterface.neutronSecurityRuleExists(securityRuleUUID)) { + throw new ResourceNotFoundException("Security Rule UUID does not exist."); + } + if (securityRuleInterface.neutronSecurityRuleInUse(securityRuleUUID)) { + return Response.status(409).build(); + } + NeutronSecurityRule singleton = securityRuleInterface.getNeutronSecurityRule(securityRuleUUID); + Object[] instances = ServiceHelper.getGlobalInstances(INeutronSecurityRuleAware.class, this, null); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + int status = service.canDeleteNeutronSecurityRule(singleton); + if (status < 200 || status > 299) { + return Response.status(status).build(); + } + } + } + + /* + * remove it and return 204 status + */ + securityRuleInterface.removeNeutronSecurityRule(securityRuleUUID); + if (instances != null) { + for (Object instance : instances) { + INeutronSecurityRuleAware service = (INeutronSecurityRuleAware) instance; + service.neutronSecurityRuleDeleted(singleton); + } + } + return Response.status(204).build(); + } +} \ No newline at end of file