From 662465381994f266eb32aa3dceba426e747df678 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Tue, 17 Dec 2013 14:13:43 +0100 Subject: [PATCH] Update service reference persistance according to new ServiceRegistry API in config subsystem. Utilize new proxy service mbeans that store reference name for dependency attributes. Change-Id: Ia6652643eefc545bc546902de6f3786fe91d63a5 Signed-off-by: Maros Marsalek --- .../attributes/AttributesConstants.java | 16 -- .../fromxml/AttributeConfigElement.java | 1 - .../attributes/mapping/ObjectMapper.java | 6 +- .../ObjectNameAttributeMappingStrategy.java | 13 +- .../ObjectNameAttributeResolvingStrategy.java | 13 +- .../attributes/resolving/ObjectResolver.java | 6 +- .../mapping/config/Config.java | 121 +++++++---- .../mapping/config/InstanceConfig.java | 8 +- .../config/InstanceConfigElementResolved.java | 10 +- .../mapping/config/ModuleConfig.java | 4 +- .../config/ModuleElementDefinition.java | 48 +++++ .../config/ServiceRegistryWrapper.java | 159 +++++++++++++++ .../mapping/config/Services.java | 193 +----------------- .../mapping/runtime/ModuleRuntime.java | 4 +- .../mapping/runtime/Runtime.java | 11 +- .../AbstractEditConfigStrategy.java | 11 +- .../editconfig/DeleteEditConfigStrategy.java | 6 +- .../operations/editconfig/EditConfig.java | 55 +++-- .../editconfig/EditConfigStrategy.java | 4 +- .../editconfig/EditConfigXmlParser.java | 37 ++-- .../editconfig/MergeEditConfigStrategy.java | 33 ++- .../MissingInstanceHandlingStrategy.java | 42 ++++ .../editconfig/NoneEditConfigStrategy.java | 8 +- .../editconfig/RemoveEditConfigStrategy.java | 4 +- .../editconfig/ReplaceEditConfigStrategy.java | 35 ++-- .../operations/get/Get.java | 3 +- .../operations/getconfig/GetConfig.java | 4 +- .../NetconfMappingTest.java | 8 + .../operations/editconfig/EditConfigTest.java | 44 +++- .../impl/osgi/PropertiesProviderBaseImpl.java | 11 +- .../editConfig_addServiceNameOnTest.xml | 38 ++++ .../netconfMessages/editConfig_none.xml | 5 +- 32 files changed, 565 insertions(+), 396 deletions(-) delete mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java create mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java create mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java create mode 100644 opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java create mode 100644 opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java deleted file mode 100644 index 23cdabf69f..0000000000 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java +++ /dev/null @@ -1,16 +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; - -public class AttributesConstants { - - /** - * Property placed into object names for dependencies to preserve reference name - */ - public static final String REF_NAME_ON_PROPERTY_KEY = "X-refName"; -} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java index a1f46dde54..dbc1b48d4f 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java @@ -43,7 +43,6 @@ public class AttributeConfigElement { resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value); Optional resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue); resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null; - } public static AttributeConfigElement create(Object nullableDefault, Object value) { 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 fb385221c8..506d7d61c3 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 @@ -16,7 +16,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeType; @@ -27,9 +27,9 @@ import java.util.Map.Entry; public class ObjectMapper extends AttributeIfcSwitchStatement>> { - private final Services dependencyTracker; + private final ServiceRegistryWrapper dependencyTracker; - public ObjectMapper(Services depTracker) { + public ObjectMapper(ServiceRegistryWrapper depTracker) { this.dependencyTracker = depTracker; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java index 8426341636..83e8086eef 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java @@ -10,8 +10,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attri import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import javax.management.ObjectName; @@ -20,11 +20,11 @@ import javax.management.openmbean.SimpleType; public class ObjectNameAttributeMappingStrategy extends AbstractAttributeMappingStrategy> { - private final Services tracker; + private final ServiceRegistryWrapper tracker; private final String serviceName; private final String namespace; - public ObjectNameAttributeMappingStrategy(SimpleType openType, Services dependencyTracker, String serviceName, String namespace) { + public ObjectNameAttributeMappingStrategy(SimpleType openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) { super(openType); this.tracker = dependencyTracker; this.serviceName = serviceName; @@ -44,10 +44,7 @@ public class ObjectNameAttributeMappingStrategy extends ObjectName on = (ObjectName) value; - String expectedRefName = on.getKeyProperty(AttributesConstants.REF_NAME_ON_PROPERTY_KEY); - - String refName = expectedRefName == null ? tracker.getRefName(namespace, serviceName, on, Optional. absent()) - : tracker.getRefName(namespace, serviceName, on, Optional.of(expectedRefName)); + String refName = ObjectNameUtil.getReferenceName(on); return Optional.of(new MappedDependency(namespace, serviceName, refName)); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java index d8f0e2357e..57a44d8af0 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java @@ -9,11 +9,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving; import com.google.common.base.Optional; -import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services.ServiceInstance; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,10 +20,10 @@ import javax.management.openmbean.SimpleType; public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy> { - private final Services serviceTracker; + private final ServiceRegistryWrapper serviceTracker; private static final Logger logger = LoggerFactory.getLogger(ObjectNameAttributeResolvingStrategy.class); - ObjectNameAttributeResolvingStrategy(Services serviceTracker) { + ObjectNameAttributeResolvingStrategy(ServiceRegistryWrapper serviceTracker) { super(SimpleType.OBJECTNAME); this.serviceTracker = serviceTracker; } @@ -45,9 +42,7 @@ public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResol String namespace = mappedDep.getNamespace(); logger.trace("Getting service instance by service name {} : {} and ref name {}", namespace, serviceName, refName); - ServiceInstance byRefName = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName); - ObjectName on = ObjectNameUtil.createReadOnlyModuleON(byRefName.getModuleName(), byRefName.getInstanceName()); - on = ObjectNameUtil.createON(on.toString() + "," + AttributesConstants.REF_NAME_ON_PROPERTY_KEY + "=" + refName); + ObjectName on = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName); logger.debug("Attribute {} : {} parsed to type {}", attrName, value, getOpenType()); return Optional.of(on); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java index a3e2813fa0..82c8c1ec6b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java @@ -15,7 +15,7 @@ import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListAttribu import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute; import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import javax.management.openmbean.ArrayType; import javax.management.openmbean.CompositeType; @@ -26,9 +26,9 @@ import java.util.Map.Entry; public class ObjectResolver extends AttributeIfcSwitchStatement>> { - private final Services serviceTracker; + private final ServiceRegistryWrapper serviceTracker; - public ObjectResolver(Services serviceTracker) { + public ObjectResolver(ServiceRegistryWrapper serviceTracker) { this.serviceTracker = serviceTracker; } 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 3a5fa1170f..fc6499e06e 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 @@ -14,7 +14,6 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; -import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -99,7 +98,7 @@ public class Config { // } public Element toXml(Set instancesToMap, Optional maybeNamespace, Document document, - Element dataElement, Services serviceTracker) { + Element dataElement, ServiceRegistryWrapper serviceTracker) { Map>> moduleToInstances = getMappedInstances(instancesToMap, moduleConfigs); @@ -131,7 +130,7 @@ public class Config { } } - root.appendChild(serviceTracker.toXml(serviceTracker.getMappedServices(), document)); + root.appendChild(Services.toXml(serviceTracker, document)); return root; } @@ -151,50 +150,66 @@ public class Config { // TODO refactor, replace string representing namespace with namespace class // TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved // class - public ConfigElementResolved fromXml(XmlElement xml, - EditStrategyType defaultEditStrategyType, ServiceReferenceReadableRegistry taClient) { - Map> retVal = Maps.newHashMap(); - - List recognisedChildren = Lists.newArrayList(); - Services serviceTracker = fromXmlServices(xml, recognisedChildren, taClient); - List moduleElements = fromXmlModules(xml, recognisedChildren); + public Map> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + Optional modulesElement = getModulesElement(xml); + List moduleElements = getModulesElementList(modulesElement); - xml.checkUnrecognisedElements(recognisedChildren); + Map> retVal = Maps.newHashMap(); for (XmlElement moduleElement : moduleElements) { - resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType); - } + ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { + @Override + public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) { + return moduleMapping.fromXml(moduleElement, serviceTracker, + instanceName, moduleNamespace, defaultStrategy); + } + }; - return new ConfigElementResolved(retVal, serviceTracker); + resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy); + } + return retVal; } - public static class ConfigElementResolved { + /** + * return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted. + */ + public Map> fromXmlModulesMap(XmlElement xml, + EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + Optional modulesElement = getModulesElement(xml); + List moduleElements = getModulesElementList(modulesElement); - private final Map> resolvedModules; - private final Services services; + Map> retVal = Maps.newHashMap(); - public ConfigElementResolved(Map> retVal, Services serviceTracker) { - this.resolvedModules = retVal; - this.services = serviceTracker; - } + for (XmlElement moduleElement : moduleElements) { + ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { + @Override + public ModuleElementDefinition resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, + ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, + EditStrategyType defaultStrategy) { + // 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); + return new ModuleElementDefinition(instanceName, perInstanceEditStrategy, defaultStrategy); + } + }; - public Map> getResolvedModules() { - return resolvedModules; + resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy); } + return retVal; + } - public Services getServices() { - return services; - } + private static Optional getModulesElement(XmlElement xml) { + return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, + XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); } - private List fromXmlModules(XmlElement xml, List recognisedChildren) { - Optional modulesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + private List getModulesElementList(Optional modulesElement) { List moduleElements; + if (modulesElement.isPresent()) { moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY); - recognisedChildren.add(modulesElement.get()); modulesElement.get().checkUnrecognisedElements(moduleElements); } else { moduleElements = Lists.newArrayList(); @@ -202,8 +217,8 @@ public class Config { return moduleElements; } - private void resolveModule(Map> retVal, Services serviceTracker, - XmlElement moduleElement, EditStrategyType defaultStrategy) { + private void resolveModule(Map> retVal, ServiceRegistryWrapper serviceTracker, + XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy resolvingStrategy) { XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); Entry prefixToNamespace = typeElement.findNamespaceOfTextContent(); String moduleNamespace = prefixToNamespace.getValue(); @@ -215,35 +230,49 @@ public class Config { ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName); - Multimap innerMap = retVal.get(moduleNamespace); + Multimap innerMap = retVal.get(moduleNamespace); if (innerMap == null) { innerMap = HashMultimap.create(); retVal.put(moduleNamespace, innerMap); } - ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker, + T resolvedElement = resolvingStrategy.resolveElement(moduleMapping, moduleElement, serviceTracker, instanceName, moduleNamespace, defaultStrategy); - innerMap.put(factoryName, moduleElementResolved); + innerMap.put(factoryName, resolvedElement); } - private Services fromXmlServices(XmlElement xml, List recognisedChildren, - ServiceReferenceReadableRegistry taClient) { - Optional servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + public Services fromXmlServices(XmlElement xml) { + Optional servicesElement = getServicesElement(xml); - Map>> mappedServices; + Services services; if (servicesElement.isPresent()) { - mappedServices = Services.fromXml(servicesElement.get()); - recognisedChildren.add(servicesElement.get()); + services = Services.fromXml(servicesElement.get()); } else { - mappedServices = new HashMap<>(); + services = new Services(); } - Services services = Services.resolveServices(mappedServices, taClient); return services; } + private static Optional getServicesElement(XmlElement xml) { + return xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY, + XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + } + + public static void checkUnrecognisedChildren(XmlElement parent) { + Optional servicesOpt = getServicesElement(parent); + Optional modulesOpt = getModulesElement(parent); + + List recognised = Lists.newArrayList(); + if(servicesOpt.isPresent()) + recognised.add(servicesOpt.get()); + if(modulesOpt.isPresent()) + recognised.add(modulesOpt.get()); + + parent.checkUnrecognisedElements(recognised); + } + private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) { checkState( factoryNameWithPrefix.startsWith(prefixOrEmptyString), @@ -271,4 +300,8 @@ public class Config { return moduleMapping; } + private interface ResolvingStrategy { + public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, + String instanceName, String moduleNamespace, EditStrategyType defaultStrategy); + } } 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 aae1636165..b8870e51ce 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 @@ -52,7 +52,7 @@ public final class InstanceConfig { this.configRegistryClient = configRegistryClient; } - private Map getMappedConfiguration(ObjectName on, Services depTracker) { + private Map getMappedConfiguration(ObjectName on, ServiceRegistryWrapper depTracker) { // TODO make field, mappingStrategies can be instantiated only once Map>> mappingStrategies = new ObjectMapper(depTracker) @@ -84,7 +84,7 @@ public final class InstanceConfig { return toXml; } - public Element toXml(ObjectName on, Services depTracker, String namespace, Document document, Element rootElement) { + public Element toXml(ObjectName on, ServiceRegistryWrapper depTracker, String namespace, Document document, Element rootElement) { Element cfgElement = rootElement; @@ -104,7 +104,7 @@ public final class InstanceConfig { return cfgElement; } - private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, Services depTracker) { + private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker) { // TODO make field, resolvingStrategies can be instantiated only once Map>> resolvingStrategies = new ObjectResolver( @@ -128,7 +128,7 @@ public final class InstanceConfig { } } - public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace, + public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace, EditStrategyType defaultStrategy, Multimap providedServices) { Map retVal = Maps.newHashMap(); 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 55cb60bed5..0bb4191bf2 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 @@ -28,7 +28,7 @@ public class InstanceConfigElementResolved { private final Multimap providedServices; public InstanceConfigElementResolved(String currentStrategy, Map configuration, EditStrategyType defaultStrategy, Multimap providedServices) { - EditStrategyType valueOf = checkStrategy(currentStrategy, defaultStrategy); + EditStrategyType valueOf = parseStrategy(currentStrategy, defaultStrategy); this.editStrategy = valueOf; this.configuration = configuration; this.providedServices = providedServices; @@ -41,19 +41,19 @@ public class InstanceConfigElementResolved { } - EditStrategyType checkStrategy(String currentStrategy, EditStrategyType defaultStrategy) { - EditStrategyType valueOf = EditStrategyType.valueOf(currentStrategy); + static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) { + EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy); if (defaultStrategy.isEnforcing()) { Preconditions .checkArgument( - valueOf == defaultStrategy, + parsedStrategy == defaultStrategy, "With " + defaultStrategy + " as " + EditConfigXmlParser.DEFAULT_OPERATION_KEY + " operations on module elements are not permitted since the default option is restrictive"); } - return valueOf; + return parsedStrategy; } 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 2ac6fe0a9b..48ff835a45 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 @@ -53,7 +53,7 @@ public class ModuleConfig { return providedServices; } - public Element toXml(ObjectName instanceON, Services depTracker, Document document, String namespace) { + public Element toXml(ObjectName instanceON, ServiceRegistryWrapper depTracker, Document document, String namespace) { Element root = document.createElement(XmlNetconfConstants.MODULE_KEY); // Xml.addNamespaceAttr(document, root, namespace); @@ -84,7 +84,7 @@ public class ModuleConfig { } - public ModuleElementResolved fromXml(XmlElement moduleElement, Services depTracker, String instanceName, + public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) { InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices); 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 new file mode 100644 index 0000000000..9111701ba0 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; + +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.MissingInstanceHandlingStrategy; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.NoneEditConfigStrategy; + +public class ModuleElementDefinition { + + public static final NoneEditConfigStrategy NONE_EDIT_CONFIG_STRATEGY = new NoneEditConfigStrategy(); + public static final MissingInstanceHandlingStrategy MISSING_INSTANCE_HANDLING_STRATEGY = new MissingInstanceHandlingStrategy(); + + private final String instanceName; + private final EditStrategyType editStrategy; + + public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) { + this.instanceName = instanceName; + if (currentStrategy == null || currentStrategy.isEmpty()) + this.editStrategy = defaultStrategy; + else + this.editStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy); + } + + public String getInstanceName() { + return instanceName; + } + + public EditStrategyType getEditStrategyType() { + return editStrategy; + } + + public EditConfigStrategy getEditStrategy() { + switch (editStrategy) { + case delete : + case remove : + case none : return NONE_EDIT_CONFIG_STRATEGY; + default : return MISSING_INSTANCE_HANDLING_STRATEGY; + } + } +} 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 new file mode 100644 index 0000000000..7df671297c --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java @@ -0,0 +1,159 @@ +/* + * 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.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 javax.management.InstanceNotFoundException; +import javax.management.ObjectName; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +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); + + Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); + Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , " + + serviceNameToRefNameToInstance.keySet()); + + String instanceId = refNameToInstance.get(refName); + Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":" + + refName + ", " + serviceNameToRefNameToInstance.keySet()); + + Services.ServiceInstance serviceInstance = Services.ServiceInstance.fromString(instanceId); + Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName + + " under service name " + serviceName + " , " + refNameToInstance.keySet()); + + String qNameOfService = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName); + try { + return configServiceRefRegistry.getServiceReference(qNameOfService, refName); + } catch (InstanceNotFoundException e) { + throw new IllegalArgumentException("No serviceInstance mapped to " + refName + + " under service name " + serviceName + " , " + refNameToInstance.keySet(), e); + + } + } + + public Map>> getMappedServices() { + Map>> retVal = Maps.newHashMap(); + + Map> serviceMapping = configServiceRefRegistry.getServiceMapping(); + for (String serviceQName : serviceMapping.keySet()) + for (String refName : serviceMapping.get(serviceQName).keySet()) { + + ObjectName on = serviceMapping.get(serviceQName).get(refName); + Services.ServiceInstance si = Services.ServiceInstance.fromObjectName(on); + + // FIXME use QName's new String constructor, after it is fixed +// QName qname; +// try { +// qname = new QName(serviceQName); +// } catch (ParseException e) { +// throw new IllegalStateException("Unable to parse qname of a service " + serviceQName, e); +// } + Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)"); + Matcher matcher = p.matcher(serviceQName); + Preconditions.checkArgument(matcher.matches()); + String namespace = matcher.group(1); + String localName = matcher.group(2); + +// String namespace = qname.getNamespace().toString(); + Map> serviceToRefs = retVal.get(namespace); + if(serviceToRefs==null) { + serviceToRefs = Maps.newHashMap(); + retVal.put(namespace, serviceToRefs); + } + +// String localName = qname.getLocalName(); + Map refsToSis = serviceToRefs.get(localName); + if(refsToSis==null) { + refsToSis = Maps.newHashMap(); + serviceToRefs.put(localName, refsToSis); + } + + Preconditions.checkState(refsToSis.containsKey(refName) == false, + "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace, + localName, on); + refsToSis.put(refName, si.toString()); + } + + 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) == false) { + 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 intitialRefName = refName; + + while (true) { + refName = intitialRefName + "_" + suffix++; + if (refNamesAsSet.contains(refName) == false) + return refName; + } + } +} diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java index 77f3cf283f..7de7ea8c71 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java @@ -8,14 +8,8 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.collect.HashMultimap; import com.google.common.collect.Maps; -import com.google.common.collect.Multimap; -import com.google.common.collect.Sets; -import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy; import org.opendaylight.controller.netconf.util.xml.XmlElement; @@ -27,12 +21,9 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.management.ObjectName; -import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -45,124 +36,8 @@ public final class Services { public static final String TYPE_KEY = "type"; public static final String SERVICE_KEY = "service"; - private long suffix = 1; - private final Map>> namespaceToServiceNameToRefNameToInstance = Maps .newHashMap(); - private ServiceReferenceReadableRegistry configServiceRefRegistry; - - public Services(ServiceReferenceReadableRegistry configServiceRefRegistry) { - this.configServiceRefRegistry = configServiceRefRegistry; - } - - @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) == false) { - 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; - } - - public ServiceInstance getByServiceAndRefName(String namespace, String serviceName, String refName) { - Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); - - Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace); - - Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , " - + serviceNameToRefNameToInstance.keySet()); - - String instanceId = refNameToInstance.get(refName); - Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":" - + refName + ", " + serviceNameToRefNameToInstance.keySet()); - - ServiceInstance serviceInstance = ServiceInstance.fromString(instanceId); - Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName - + " under service name " + serviceName + " , " + refNameToInstance.keySet()); - return serviceInstance; - } - - // TODO hide getMappedServices, call it explicitly in toXml - - public Map>> getMappedServices() { - Map>> retVal = Maps.newHashMap(); - - for (String namespace : namespaceToServiceNameToRefNameToInstance.keySet()) { - - Map> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance - .get(namespace); - Map> innerRetVal = Maps.newHashMap(); - - for (String serviceName : serviceNameToRefNameToInstance.keySet()) { - - Map innerInnerRetVal = Maps.newHashMap(); - for (Entry refNameToSi : serviceNameToRefNameToInstance.get(serviceName).entrySet()) { - innerInnerRetVal.put(refNameToSi.getKey(), refNameToSi.getValue().toString()); - } - innerRetVal.put(serviceName, innerInnerRetVal); - } - retVal.put(namespace, innerRetVal); - } - - Map> serviceMapping = configServiceRefRegistry.getServiceMapping(); - for (String serviceQName : serviceMapping.keySet()) - for (String refName : serviceMapping.get(serviceQName).keySet()) { - - ObjectName on = serviceMapping.get(serviceQName).get(refName); - ServiceInstance si = ServiceInstance.fromObjectName(on); - - // FIXME use QName's new String constructor, after its implemented - Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)"); - Matcher matcher = p.matcher(serviceQName); - Preconditions.checkArgument(matcher.matches()); - String namespace = matcher.group(1); - String localName = matcher.group(2); - - Map> serviceToRefs = retVal.get(namespace); - if(serviceToRefs==null) { - serviceToRefs = Maps.newHashMap(); - retVal.put(namespace, serviceToRefs); - } - - Map refsToSis = serviceToRefs.get(localName); - if(refsToSis==null) { - refsToSis = Maps.newHashMap(); - serviceToRefs.put(localName, refsToSis); - } - - Preconditions.checkState(refsToSis.containsKey(refName) == false, - "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace, - localName, on); - refsToSis.put(refName, si.toString()); - } - - return retVal; - } /** * @@ -171,10 +46,8 @@ public final class Services { return namespaceToServiceNameToRefNameToInstance; } - // TODO hide resolveServices, call it explicitly in fromXml - - public static Services resolveServices(Map>> mappedServices, ServiceReferenceReadableRegistry taClient) { - Services tracker = new Services(taClient); + private static Services resolveServices(Map>> mappedServices) { + Services tracker = new Services(); for (Entry>> namespaceEntry : mappedServices.entrySet()) { String namespace = namespaceEntry.getKey(); @@ -210,7 +83,7 @@ public final class Services { // TODO support edit strategies on services - public static Map>> fromXml(XmlElement xml) { + public static Services fromXml(XmlElement xml) { Map>> retVal = Maps.newHashMap(); List services = xml.getChildElements(SERVICE_KEY); @@ -250,23 +123,14 @@ public final class Services { } } - return retVal; - } - - private String findAvailableRefName(String refName, Set refNamesAsSet) { - String intitialRefName = refName; - - while (true) { - refName = intitialRefName + "_" + suffix++; - if (refNamesAsSet.contains(refName) == false) - return refName; - } + return resolveServices(retVal); } - public Element toXml(Map>> mappedServices, Document document) { + public static Element toXml(ServiceRegistryWrapper serviceRegistryWrapper, Document document) { Element root = document.createElement(XmlNetconfConstants.SERVICES_KEY); XmlUtil.addNamespaceAttr(root, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + Map>> mappedServices = serviceRegistryWrapper.getMappedServices(); for (String namespace : mappedServices.keySet()) { for (Entry> serviceEntry : mappedServices.get(namespace).entrySet()) { @@ -294,51 +158,6 @@ public final class Services { return root; } - public String getRefName(String namespace, String serviceName, ObjectName on, Optional expectedRefName) { - Optional refNameOptional = getRefNameOptional(namespace, serviceName, on, expectedRefName); - Preconditions.checkState(refNameOptional.isPresent(), "No reference names mapped to %s, %s, %s", namespace, - serviceName, on); - return refNameOptional.get(); - } - - public Optional getRefNameOptional(String namespace, String serviceName, ObjectName on, - Optional expectedRefName) { - Map> services = getMappedServices().get(namespace); - - if(services == null) return Optional.absent(); - Map refs = services.get(serviceName); - - if(refs == null) return Optional.absent(); - Multimap reverted = revertMap(refs); - - ServiceInstance serviceInstance = ServiceInstance.fromObjectName(on); - Collection references = reverted.get(serviceInstance); - - if (expectedRefName.isPresent() && references.contains(expectedRefName.get())) { - logger.debug("Returning expected ref name {} for {}", expectedRefName.get(), on); - return expectedRefName; - } else if (references.size() > 0) { - String next = references.iterator().next(); - logger.debug("Returning random ref name {} for {}", next, on); - return Optional.of(next); - } else - return Optional.absent(); - } - - private Multimap revertMap(Map refs) { - Multimap multimap = HashMultimap.create(); - - for (Entry e : refs.entrySet()) { - multimap.put(ServiceInstance.fromString(e.getValue()), e.getKey()); - } - - return multimap; - } - - public boolean hasRefName(String key, String value, ObjectName on) { - return getRefNameOptional(key, value, on, Optional.absent()).isPresent(); - } - public static final class ServiceInstance { public ServiceInstance(String moduleName, String instanceName) { this.moduleName = moduleName; 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 11e97ebdbb..4936d1dbcd 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 @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti import com.google.common.collect.Sets; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -41,7 +41,7 @@ public class ModuleRuntime { } public Element toXml(String namespace, Collection runtimeBeanOns, - Document document, ModuleConfig moduleConfig, ObjectName configBeanON, Services serviceTracker) { + Document document, ModuleConfig moduleConfig, ObjectName configBeanON, ServiceRegistryWrapper serviceTracker) { Element moduleElement = moduleConfig.toXml(configBeanON, serviceTracker, document, namespace); 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 89c782c51c..129143835f 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 @@ -11,11 +11,10 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.runti import com.google.common.collect.HashMultimap; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; -import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; 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.Services; +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; @@ -61,9 +60,7 @@ public class Runtime { return retVal; } - public Element toXml(Set instancesToMap, Set configBeans, Document document, ServiceReferenceReadableRegistry serviceRegistry) { - Services serviceTracker = new Services(serviceRegistry); - + public Element toXml(Set instancesToMap, Set configBeans, Document document, ServiceRegistryWrapper serviceRegistry) { Element root = document.createElement(XmlNetconfConstants.DATA_KEY); Element modulesElement = document.createElement(XmlNetconfConstants.MODULES_KEY); @@ -88,11 +85,11 @@ public class Runtime { Element runtimeXml; ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName); if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) { - runtimeXml = moduleConfig.toXml(instanceON, serviceTracker, document, localNamespace); + runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace); } else { ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName); runtimeXml = moduleRuntime.toXml(localNamespace, instanceToRbe.get(instanceName), document, - moduleConfig, instanceON, serviceTracker); + moduleConfig, instanceON, serviceRegistry); } modulesElement.appendChild(runtimeXml); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java index 65df965afd..1d37fcd493 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,7 +24,7 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy { @Override public void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, Services services) { + ConfigTransactionClient ta, ServiceRegistryWrapper services) { try { ObjectName on = ta.lookupConfigBean(module, instance); @@ -36,10 +36,13 @@ public abstract class AbstractEditConfigStrategy implements EditConfigStrategy { } + // TODO split missing instances handling strategies from edit config strategies in this hierarchy = REFACTOR + // edit configs should not handle missing + abstract void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services); + String module, String instance, ServiceRegistryWrapper services); abstract void executeStrategy(Map configuration, ConfigTransactionClient ta, - ObjectName objectName, Services services); + ObjectName objectName, ServiceRegistryWrapper services); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java index 12beaf8f8e..13e8c30211 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java @@ -12,7 +12,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,12 +36,12 @@ public class DeleteEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { + String module, String instance, ServiceRegistryWrapper services) { throw new IllegalStateException("Unable to delete " + module + ":" + instance + " , ServiceInstance not found"); } @Override - void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, Services services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { try { ta.destroyModule(on); logger.debug("ServiceInstance {} deleted successfully", on); 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 1bb1d9bfba..ca9fb60423 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 @@ -25,6 +25,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; @@ -105,8 +106,8 @@ public class EditConfig extends AbstractConfigNetconfOperation { logger.debug("Test phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG); } - private void test(ConfigRegistryClient configRegistryClient, - EditConfigExecution execution, EditStrategyType editStrategyType) { + private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution, + EditStrategyType editStrategyType) { ObjectName taON = transactionProvider.getTestTransaction(); try { @@ -115,8 +116,11 @@ public class EditConfig extends AbstractConfigNetconfOperation { transactionProvider.wipeTestTransaction(taON); } - setOnTransaction(configRegistryClient, execution.getResolvedXmlElements(), execution.getServices(), taON); - // TODO add service reference persistance testing here + ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + + handleMisssingInstancesOnTransaction(ta, execution); + setServicesOnTransaction(ta, execution); + setOnTransaction(ta, execution); transactionProvider.validateTestTransaction(taON); } finally { transactionProvider.abortTestTransaction(taON); @@ -132,14 +136,16 @@ public class EditConfig extends AbstractConfigNetconfOperation { transactionProvider.wipeTransaction(); } - setOnTransaction(configRegistryClient, editConfigExecution.getResolvedXmlElements(), - editConfigExecution.getServices(), taON); - setServicesOnTransaction(configRegistryClient, editConfigExecution.getServices(), taON); + ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + + handleMisssingInstancesOnTransaction(ta, editConfigExecution); + setServicesOnTransaction(ta, editConfigExecution); + setOnTransaction(ta, editConfigExecution); } - private void setServicesOnTransaction(ConfigRegistryClient configRegistryClient, Services services, - ObjectName taON) { - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) { + + Services services = execution.getServices(); Map>> namespaceToServiceNameToRefNameToInstance = services .getNamespaceToServiceNameToRefNameToInstance(); @@ -153,9 +159,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { for (String refName : refNameToInstance.keySet()) { ObjectName on = refNameToInstance.get(refName).getObjectName(ta.getTransactionName()); - // TODO check for duplicates try { - ta.saveServiceReference(qnameOfService, refName, on); + ObjectName saved = ta.saveServiceReference(qnameOfService, refName, on); + logger.debug("Saving service {} with on {} under name {} with service on {}", qnameOfService, + on, refName, saved); } catch (InstanceNotFoundException e) { throw new IllegalStateException("Unable to save ref name " + refName + " for instance " + on, e); } @@ -168,11 +175,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { return ta.getServiceInterfaceName(namespace, serviceName); } - private void setOnTransaction(ConfigRegistryClient configRegistryClient, - Map> resolvedXmlElements, Services services, ObjectName taON) { - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); + private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) { + + for (Multimap modulesToResolved : execution.getResolvedXmlElements(ta).values()) { - for (Multimap modulesToResolved : resolvedXmlElements.values()) { for (Entry moduleToResolved : modulesToResolved.entries()) { String moduleName = moduleToResolved.getKey(); @@ -181,7 +187,22 @@ public class EditConfig extends AbstractConfigNetconfOperation { InstanceConfigElementResolved ice = moduleElementResolved.getInstanceConfigElementResolved(); EditConfigStrategy strategy = ice.getEditStrategy(); - strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, services); + strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, execution.getServiceRegistryWrapper(ta)); + } + } + } + + private void handleMisssingInstancesOnTransaction(ConfigTransactionClient ta, + EditConfigExecution execution) { + + for (Multimap modulesToResolved : execution.getModulesDefinition(ta).values()) { + for (Entry moduleToResolved : modulesToResolved.entries()) { + String moduleName = moduleToResolved.getKey(); + + ModuleElementDefinition moduleElementDefinition = moduleToResolved.getValue(); + + EditConfigStrategy strategy = moduleElementDefinition.getEditStrategy(); + strategy.executeConfiguration(moduleName, moduleElementDefinition.getInstanceName(), null, ta, execution.getServiceRegistryWrapper(ta)); } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java index 23166e8cca..cebcb0239b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java @@ -10,13 +10,13 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import java.util.Map; public interface EditConfigStrategy { void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, Services services); + ConfigTransactionClient ta, ServiceRegistryWrapper services); } 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 81327133b8..e481bbe57f 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 @@ -14,10 +14,11 @@ import com.google.common.base.Preconditions; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry; import org.opendaylight.controller.config.util.ConfigRegistryClient; -import org.opendaylight.controller.config.util.ConfigTransactionClient; 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; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; +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; @@ -26,7 +27,6 @@ import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.ObjectName; import java.util.Arrays; import java.util.Map; @@ -98,11 +98,7 @@ public class EditConfigXmlParser { XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY); - ObjectName taON = transactionProvider.getOrCreateTransaction(); - ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON); - - return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, - ta, editStrategyType); + return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, editStrategyType); } @VisibleForTesting @@ -132,15 +128,17 @@ public class EditConfigXmlParser { @VisibleForTesting static class EditConfigExecution { - private final Map> resolvedXmlElements; private final TestOption testOption; private final EditStrategyType defaultEditStrategyType; private final Services services; - - EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, ServiceReferenceReadableRegistry ta, EditStrategyType defaultStrategy) { - Config.ConfigElementResolved configElementResolved = configResolver.fromXml(configElement, defaultStrategy, ta); - this.resolvedXmlElements = configElementResolved.getResolvedModules(); - this.services = configElementResolved.getServices(); + private final Config configResolver; + private final XmlElement configElement; + + EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) { + Config.checkUnrecognisedChildren(configElement); + this.configResolver = configResolver; + this.configElement = configElement; + this.services = configResolver.fromXmlServices(configElement); this.testOption = testOption; this.defaultEditStrategyType = defaultStrategy; } @@ -153,8 +151,17 @@ public class EditConfigXmlParser { return testOption == TestOption.set || testOption == TestOption.testThenSet; } - Map> getResolvedXmlElements() { - return resolvedXmlElements; + Map> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) { + return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry)); + } + + ServiceRegistryWrapper getServiceRegistryWrapper(ServiceReferenceReadableRegistry serviceRegistry) { + // TODO cache service registry + return new ServiceRegistryWrapper(serviceRegistry); + } + + Map> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) { + return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry)); } EditStrategyType getDefaultStrategy() { 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 06befb0565..f2e2b193a8 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 @@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.Attribute; -import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; import java.util.Map; @@ -38,22 +38,13 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { - ObjectName on = null; - try { - on = ta.createModule(module, instance); - logger.info("New instance for {} {} created under name {}", module, instance, on); - addRefNames(services, providedServices, module, instance, ta, on); - executeStrategy(configuration, ta, on, services); - } catch (InstanceAlreadyExistsException e1) { - throw new IllegalStateException("Unable to create instance for " + module + " : " + instance); - } catch (InstanceNotFoundException e) { - throw new IllegalStateException("Unable to save default ref name for instance " + on, e); - } + String module, String instance, ServiceRegistryWrapper services) { + throw new IllegalStateException( + "Unable to handle missing instance, no missing instances should appear at this point, missing: " + + module + ":" + instance); } - private void addRefNames(Services services, Multimap providedServices, String module, - String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { + private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), @@ -61,14 +52,20 @@ public class MergeEditConfigStrategy extends AbstractEditConfigStrategy { continue; String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), - module, instance); + 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, Services services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { + try { + addRefNames(services, providedServices, ta, on); + } catch (InstanceNotFoundException e) { + throw new IllegalStateException("Unable to save default ref name for instance " + on, e); + } + 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/editconfig/MissingInstanceHandlingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java new file mode 100644 index 0000000000..8ed9eb8731 --- /dev/null +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java @@ -0,0 +1,42 @@ +/* + * 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.operations.editconfig; + +import org.opendaylight.controller.config.util.ConfigTransactionClient; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.management.InstanceAlreadyExistsException; +import javax.management.ObjectName; +import java.util.Map; + +public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy { + + private static final Logger logger = LoggerFactory.getLogger(MissingInstanceHandlingStrategy.class); + + @Override + void handleMissingInstance(Map configuration, ConfigTransactionClient ta, + String module, String instance, ServiceRegistryWrapper services) { + ObjectName on = null; + try { + on = ta.createModule(module, instance); + logger.info("New instance for {} {} created under name {}", module, instance, on); + } catch (InstanceAlreadyExistsException e1) { + throw new IllegalStateException("Unable to create instance for " + module + " : " + instance); + } + } + + @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/NoneEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java index 8347c6b88e..bd182a4267 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java @@ -8,21 +8,21 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig; -import java.util.Map; - import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; + public class NoneEditConfigStrategy implements EditConfigStrategy { private static final Logger logger = LoggerFactory.getLogger(NoneEditConfigStrategy.class); @Override public void executeConfiguration(String module, String instance, Map configuration, - ConfigTransactionClient ta, Services services) { + ConfigTransactionClient ta, ServiceRegistryWrapper services) { logger.debug("Skipping configuration element for {}:{}", module, instance); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java index 64f082da40..df1f65372a 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java @@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,7 +22,7 @@ public class RemoveEditConfigStrategy extends DeleteEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { + String module, String instance, ServiceRegistryWrapper services) { logger.warn("Unable to delete {}:{}, ServiceInstance not found", module, instance); } } 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 43d852e76a..4976244eae 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 @@ -10,14 +10,14 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.config.util.ConfigTransactionClient; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.Attribute; -import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.ObjectName; import java.util.Map; @@ -39,23 +39,13 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { @Override void handleMissingInstance(Map configuration, ConfigTransactionClient ta, - String module, String instance, Services services) { - ObjectName on = null; - try { - on = ta.createModule(module, instance); - logger.debug("New instance for {} {} created under name {}", module, instance, on); - addRefNames(services, providedServices, module, instance, ta, on); - executeStrategy(configuration, ta, on, services); - } catch (InstanceAlreadyExistsException e) { - logger.warn("Error creating instance {}:{}, replace failed", module, instance, e); - throw new IllegalStateException("Unable to create new instance for " + module + " : " + instance, e); - } catch (InstanceNotFoundException e) { - throw new IllegalStateException("Unable to save default ref name for instance " + on, e); - } + String module, String instance, ServiceRegistryWrapper services) { + throw new IllegalStateException( + "Unable to handle missing instance, no missing instances should appear at this point, missing: " + + module + ":" + instance); } - private void addRefNames(Services services, Multimap providedServices, String module, - String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { + private void addRefNames(ServiceRegistryWrapper services, Multimap providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException { for (Entry namespaceToService : providedServices.entries()) { if(services.hasRefName(namespaceToService.getKey(), @@ -63,13 +53,20 @@ public class ReplaceEditConfigStrategy extends AbstractEditConfigStrategy { continue; String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(), - module, instance); + 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, Services services) { + void executeStrategy(Map configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) { + try { + addRefNames(services, providedServices, ta, on); + } catch (InstanceNotFoundException e) { + throw new IllegalStateException("Unable to save default ref name for instance " + on, e); + } + 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 efe4f7dde9..21771b64c7 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 @@ -20,6 +20,7 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorT import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType; 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; @@ -150,7 +151,7 @@ public class Get extends AbstractConfigNetconfOperation { ObjectName txOn = transactionProvider.getOrCreateTransaction(); ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn); - final Element element = runtime.toXml(runtimeBeans, configBeans, document, ta); + final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta)); logger.info("{} 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 d75cfd5d6f..42f8c2dd8b 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 @@ -21,7 +21,7 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorT 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.ModuleConfig; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; @@ -90,7 +90,7 @@ public class GetConfig extends AbstractConfigNetconfOperation { ObjectName on = transactionProvider.getOrCreateTransaction(); ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(on); - Services serviceTracker = new Services(ta); + ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(ta); dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker); logger.info("{} operation successful", GET_CONFIG); 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 11cf1aae6a..9511673ea4 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 @@ -143,12 +143,19 @@ public class NetconfMappingTest extends AbstractConfigTest { "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, 7, "ref_test2", "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, 7, "ref_test2", "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); @@ -229,6 +236,7 @@ public class NetconfMappingTest extends AbstractConfigTest { edit("netconfMessages/editConfig.xml"); Element configCandidate = getConfigCandidate(); + System.err.println(XmlUtil.toString(configCandidate)); checkBinaryLeafEdited(configCandidate); diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java index 6e7a225f38..505a91c6ce 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java @@ -23,7 +23,9 @@ import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved; +import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; +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.ValidateTest; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution; @@ -35,7 +37,7 @@ import java.util.Collections; import java.util.Map; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyMap; +import static org.mockito.Matchers.anyMapOf; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -82,8 +84,8 @@ public class EditConfigTest { ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING); EditConfigStrategy editStrat = mock(EditConfigStrategy.class); - doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMap(), - any(ConfigTransactionClient.class), any(Services.class)); + doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMapOf(String.class, AttributeConfigElement.class), + any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class)); EditConfigExecution editConfigExecution = mockExecution(editStrat); @@ -96,20 +98,44 @@ public class EditConfigTest { verify(provider).getOrCreateTransaction(); // For every instance execute strat - verify(editStrat, times(2/* Test */+ 2/* Set */)).executeConfiguration(anyString(), anyString(), anyMap(), - any(ConfigTransactionClient.class), any(Services.class)); + verify(editStrat, times(2/* Test */+ 2/* Set */ + 2/*Handle missing instance Test*/ + 2 /*Handle missing instance Set*/)).executeConfiguration(anyString(), + anyString(), anyMapOf(String.class, AttributeConfigElement.class), + any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class)); } private EditConfigExecution mockExecution(EditConfigStrategy editStrat) { EditConfigExecution mock = mock(EditConfigExecution.class); - doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(); + doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class)); + doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class)); doReturn(EditStrategyType.merge).when(mock).getDefaultStrategy(); doReturn(true).when(mock).shouldSet(); doReturn(true).when(mock).shouldTest(); - doReturn(mockServices()).when(mock).getServices(); + doReturn(mockServices()).when(mock).getServiceRegistryWrapper(any(ConfigTransactionClient.class)); + doReturn(new Services()).when(mock).getServices(); return mock; } + private Object getMappingDefinition(EditConfigStrategy editStrat) { + Map> result = Maps.newHashMap(); + + Multimap innerMultimap = HashMultimap.create(); + Map attributes = getSimpleAttributes(); + + ModuleElementDefinition mockedDefinition = mock(ModuleElementDefinition.class); + doReturn(editStrat).when(mockedDefinition).getEditStrategy(); + doReturn("i1").when(mockedDefinition).getInstanceName(); + innerMultimap.put("m1", mockedDefinition); + + ModuleElementDefinition mockedDefinition2 = mock(ModuleElementDefinition.class); + doReturn(editStrat).when(mockedDefinition2).getEditStrategy(); + doReturn("i2").when(mockedDefinition2).getInstanceName(); + innerMultimap.put("m1", mockedDefinition2); + + result.put("n1", innerMultimap); + + return result; + } + private static ServiceReferenceReadableRegistry mockServiceRegistry() { ServiceReferenceReadableRegistry mock = mock(ServiceReferenceReadableRegistry.class); doReturn( @@ -120,8 +146,8 @@ public class EditConfigTest { return mock; } - static Services mockServices() { - return new Services(mockServiceRegistry()); + static ServiceRegistryWrapper mockServices() { + return new ServiceRegistryWrapper(mockServiceRegistry()); } private Map> getMapping(EditConfigStrategy editStrat) { diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java index 15ed5c48fa..2a95cca937 100644 --- a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java +++ b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java @@ -1,10 +1,9 @@ -/** - * @author Tomas Olvecky +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * - * 11 2013 - * - * Copyright (c) 2013 by Cisco Systems, Inc. - * 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.persist.impl.osgi; diff --git a/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml new file mode 100644 index 0000000000..6e68326382 --- /dev/null +++ b/opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml @@ -0,0 +1,38 @@ + + + + + + + test-only + + merge + + + + + instance-from-code_dep + + test-impl:impl-dep + + + + + + + prefix:testing + + ref_dep_user_another_test1 + /modules/module[type='impl-dep'][name='instance-from-code_dep'] + + + + ref_dep_user_another_test2 + /modules/module[type='impl-dep'][name='instance-from-code_dep'] + + + + + + + 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 a7f1c86391..ade40f6a49 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 @@ -21,12 +21,11 @@ - test-impl:impl-netconf - test1 + instance-from-code 44 8ad1 @@ -72,7 +71,7 @@ test-impl:impl-netconf - test2 + test3 -- 2.36.6