Update service reference persistance according to new ServiceRegistry API in config... 21/3821/2
authorMaros Marsalek <mmarsale@cisco.com>
Tue, 17 Dec 2013 13:13:43 +0000 (14:13 +0100)
committerMaros Marsalek <mmarsale@cisco.com>
Thu, 19 Dec 2013 08:55:05 +0000 (09:55 +0100)
Utilize new proxy service mbeans that store reference name for dependency attributes.

Change-Id: Ia6652643eefc545bc546902de6f3786fe91d63a5
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
32 files changed:
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/AttributesConstants.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/AttributeConfigElement.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectMapper.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/mapping/ObjectNameAttributeMappingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectResolver.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleElementDefinition.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ServiceRegistryWrapper.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/ModuleRuntime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/runtime/Runtime.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/AbstractEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/DeleteEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MergeEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/MissingInstanceHandlingStrategy.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/NoneEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/RemoveEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategy.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/PropertiesProviderBaseImpl.java
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_addServiceNameOnTest.xml [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/test/resources/netconfMessages/editConfig_none.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 (file)
index 23cdabf..0000000
+++ /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";
-}
index a1f46dde54ff078596b709e12e0eeeb8914e7056..dbc1b48d4f9abebe5fc89c306f65b68fcee924d2 100644 (file)
@@ -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) {
index fb385221c8877b9ffceadf53cd355f8c78197811..506d7d61c347016ef76a6601500ed773762dafb0 100644 (file)
@@ -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<AttributeMappingStrategy<?, ? extends OpenType<?>>> {
 
-    private final Services dependencyTracker;
+    private final ServiceRegistryWrapper dependencyTracker;
 
-    public ObjectMapper(Services depTracker) {
+    public ObjectMapper(ServiceRegistryWrapper depTracker) {
         this.dependencyTracker = depTracker;
     }
 
index 842634163607315bd018d00d43c29b1db2dd83d0..83e8086eef2507b648d918cf4592d9d7c553c1b6 100644 (file)
@@ -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<ObjectNameAttributeMappingStrategy.MappedDependency, SimpleType<?>> {
 
-    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.<String> absent())
-                : tracker.getRefName(namespace, serviceName, on, Optional.of(expectedRefName));
+        String refName = ObjectNameUtil.getReferenceName(on);
 
         return Optional.of(new MappedDependency(namespace, serviceName, refName));
     }
index d8f0e2357ea0fb57063121b2758aca908b553eb5..57a44d8af0ec2d11cb30f3a86393ac015bac814c 100644 (file)
@@ -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<ObjectName, SimpleType<?>> {
 
-    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);
index a3e2813fa0d383f6db78c6a2c2d52e32d03dc5e1..82c8c1ec6b537f2ca25cc585dfe4c795cd2b7350 100644 (file)
@@ -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<AttributeResolvingStrategy<?, ? extends OpenType<?>>> {
 
-    private final Services serviceTracker;
+    private final ServiceRegistryWrapper serviceTracker;
 
-    public ObjectResolver(Services serviceTracker) {
+    public ObjectResolver(ServiceRegistryWrapper serviceTracker) {
         this.serviceTracker = serviceTracker;
     }
 
index 3a5fa1170fec28922155e8e7b2748eb7393448b5..fc6499e06e803761270e7b42c4135f2c152950e9 100644 (file)
@@ -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<ObjectName> instancesToMap, Optional<String> maybeNamespace, Document document,
-            Element dataElement, Services serviceTracker) {
+            Element dataElement, ServiceRegistryWrapper serviceTracker) {
 
         Map<String, Map<String, Collection<ObjectName>>> 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<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
-
-        List<XmlElement> recognisedChildren = Lists.newArrayList();
 
-        Services serviceTracker = fromXmlServices(xml, recognisedChildren, taClient);
-        List<XmlElement> moduleElements = fromXmlModules(xml, recognisedChildren);
+    public Map<String, Multimap<String, ModuleElementResolved>> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+        Optional<XmlElement> modulesElement = getModulesElement(xml);
+        List<XmlElement> moduleElements = getModulesElementList(modulesElement);
 
-        xml.checkUnrecognisedElements(recognisedChildren);
+        Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
 
         for (XmlElement moduleElement : moduleElements) {
-            resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType);
-        }
+            ResolvingStrategy<ModuleElementResolved> resolvingStrategy = new ResolvingStrategy<ModuleElementResolved>() {
+                @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<String, Multimap<String, ModuleElementDefinition>> fromXmlModulesMap(XmlElement xml,
+            EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+        Optional<XmlElement> modulesElement = getModulesElement(xml);
+        List<XmlElement> moduleElements = getModulesElementList(modulesElement);
 
-        private final Map<String, Multimap<String, ModuleElementResolved>> resolvedModules;
-        private final Services services;
+        Map<String, Multimap<String, ModuleElementDefinition>> retVal = Maps.newHashMap();
 
-        public ConfigElementResolved(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker) {
-            this.resolvedModules = retVal;
-            this.services = serviceTracker;
-        }
+        for (XmlElement moduleElement : moduleElements) {
+            ResolvingStrategy<ModuleElementDefinition> resolvingStrategy = new ResolvingStrategy<ModuleElementDefinition>() {
+                @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<String, Multimap<String, ModuleElementResolved>> getResolvedModules() {
-            return resolvedModules;
+            resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
         }
+        return retVal;
+    }
 
-        public Services getServices() {
-            return services;
-        }
+    private static Optional<XmlElement> getModulesElement(XmlElement xml) {
+        return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
+                    XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
     }
 
-    private List<XmlElement> fromXmlModules(XmlElement xml, List<XmlElement> recognisedChildren) {
-        Optional<XmlElement> modulesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
-                XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+    private List<XmlElement> getModulesElementList(Optional<XmlElement> modulesElement) {
         List<XmlElement> 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<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker,
-            XmlElement moduleElement, EditStrategyType defaultStrategy) {
+    private <T> void resolveModule(Map<String, Multimap<String, T>> retVal, ServiceRegistryWrapper serviceTracker,
+            XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy<T> resolvingStrategy) {
         XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
         Entry<String, String> prefixToNamespace = typeElement.findNamespaceOfTextContent();
         String moduleNamespace = prefixToNamespace.getValue();
@@ -215,35 +230,49 @@ public class Config {
 
         ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName);
 
-        Multimap<String, ModuleElementResolved> innerMap = retVal.get(moduleNamespace);
+        Multimap<String, T> 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<XmlElement> recognisedChildren,
-                                     ServiceReferenceReadableRegistry taClient) {
-        Optional<XmlElement> servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
-                XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+    public Services fromXmlServices(XmlElement xml) {
+        Optional<XmlElement> servicesElement = getServicesElement(xml);
 
-        Map<String, Map<String, Map<String, String>>> 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<XmlElement> 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<XmlElement> servicesOpt = getServicesElement(parent);
+        Optional<XmlElement> modulesOpt = getModulesElement(parent);
+
+        List<XmlElement> 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<T> {
+        public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker,
+                String instanceName, String moduleNamespace, EditStrategyType defaultStrategy);
+    }
 }
index aae1636165c07c6822fbadf10ddfeafad2d28653..b8870e51ce8bd0907655054a0b9c4566e1343cf4 100644 (file)
@@ -52,7 +52,7 @@ public final class InstanceConfig {
         this.configRegistryClient = configRegistryClient;
     }
 
-    private Map<String, Object> getMappedConfiguration(ObjectName on, Services depTracker) {
+    private Map<String, Object> getMappedConfiguration(ObjectName on, ServiceRegistryWrapper depTracker) {
 
         // TODO make field, mappingStrategies can be instantiated only once
         Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> 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<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> 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<String, String> providedServices) {
         Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
 
index 55cb60bed5e7df0268908b160650ecd46101e137..0bb4191bf2f33817d4bd395e3f29c0110139835b 100644 (file)
@@ -28,7 +28,7 @@ public class InstanceConfigElementResolved {
     private final Multimap<String, String> providedServices;
 
     public InstanceConfigElementResolved(String currentStrategy, Map<String, AttributeConfigElement> configuration, EditStrategyType defaultStrategy, Multimap<String, String> 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;
     }
 
 
index 2ac6fe0a9bb650116e5f3591fb35cdf8655ee311..48ff835a451e789d51826c4a9c65ba4241d3329b 100644 (file)
@@ -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 (file)
index 0000000..9111701
--- /dev/null
@@ -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 (file)
index 0000000..7df6712
--- /dev/null
@@ -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<String, ObjectName> 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<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
+
+        Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
+
+        Map<String, String> 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<String, Map<String, Map<String, String>>> getMappedServices() {
+        Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
+
+        Map<String, Map<String, ObjectName>> 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<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
+                if(serviceToRefs==null) {
+                    serviceToRefs = Maps.newHashMap();
+                    retVal.put(namespace, serviceToRefs);
+                }
+
+//                String localName = qname.getLocalName();
+                Map<String, String> 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<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
+
+        Map<String, String> refNameToInstance;
+        if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
+            refNameToInstance = Collections.emptyMap();
+        } else
+            refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+
+        final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
+        if (refNamesAsSet.contains(refName)) {
+            refName = findAvailableRefName(refName, refNamesAsSet);
+        }
+
+        return refName;
+    }
+
+
+    private Set<String> toSet(Collection<String> values) {
+        Set<String> 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<String> refNamesAsSet) {
+        String intitialRefName = refName;
+
+        while (true) {
+            refName = intitialRefName + "_" + suffix++;
+            if (refNamesAsSet.contains(refName) == false)
+                return refName;
+        }
+    }
+}
index 77f3cf283fc2daf77c18766c4a9dacd4185f2536..7de7ea8c7169086afe4aa6ce1a2cf858718d20e3 100644 (file)
@@ -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<String /*Namespace*/, Map<String/* ServiceName */, Map<String/* refName */, ServiceInstance>>> 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<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
-
-        Map<String, String> refNameToInstance;
-        if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
-            refNameToInstance = Collections.emptyMap();
-        } else
-            refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
-
-        final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
-        if (refNamesAsSet.contains(refName)) {
-            refName = findAvailableRefName(refName, refNamesAsSet);
-        }
-
-        return refName;
-    }
-
-    private Set<String> toSet(Collection<String> values) {
-        Set<String> 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<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
-
-        Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
-
-        Map<String, String> 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<String, Map<String, Map<String, String>>> getMappedServices() {
-        Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
-
-        for (String namespace : namespaceToServiceNameToRefNameToInstance.keySet()) {
-
-            Map<String, Map<String, ServiceInstance>> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance
-                    .get(namespace);
-            Map<String, Map<String, String>> innerRetVal = Maps.newHashMap();
-
-            for (String serviceName : serviceNameToRefNameToInstance.keySet()) {
-
-                Map<String, String> innerInnerRetVal = Maps.newHashMap();
-                for (Entry<String, ServiceInstance> refNameToSi : serviceNameToRefNameToInstance.get(serviceName).entrySet()) {
-                    innerInnerRetVal.put(refNameToSi.getKey(), refNameToSi.getValue().toString());
-                }
-                innerRetVal.put(serviceName, innerInnerRetVal);
-            }
-            retVal.put(namespace, innerRetVal);
-        }
-
-        Map<String, Map<String, ObjectName>> 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<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
-                if(serviceToRefs==null) {
-                    serviceToRefs = Maps.newHashMap();
-                    retVal.put(namespace, serviceToRefs);
-                }
-
-                Map<String, String> 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<String, Map<String, Map<String, String>>> mappedServices, ServiceReferenceReadableRegistry taClient) {
-        Services tracker = new Services(taClient);
+    private static Services resolveServices(Map<String, Map<String, Map<String, String>>> mappedServices) {
+        Services tracker = new Services();
 
         for (Entry<String, Map<String, Map<String, String>>> namespaceEntry : mappedServices.entrySet()) {
             String namespace = namespaceEntry.getKey();
@@ -210,7 +83,7 @@ public final class Services {
 
     // TODO support edit strategies on services
 
-    public static Map<String, Map<String, Map<String, String>>> fromXml(XmlElement xml) {
+    public static Services fromXml(XmlElement xml) {
         Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
 
         List<XmlElement> services = xml.getChildElements(SERVICE_KEY);
@@ -250,23 +123,14 @@ public final class Services {
             }
         }
 
-        return retVal;
-    }
-
-    private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
-        String intitialRefName = refName;
-
-        while (true) {
-            refName = intitialRefName + "_" + suffix++;
-            if (refNamesAsSet.contains(refName) == false)
-                return refName;
-        }
+        return resolveServices(retVal);
     }
 
-    public Element toXml(Map<String, Map<String, Map<String, String>>> 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<String, Map<String, Map<String, String>>> mappedServices = serviceRegistryWrapper.getMappedServices();
         for (String namespace : mappedServices.keySet()) {
 
             for (Entry<String, Map<String, String>> 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<String> expectedRefName) {
-        Optional<String> 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<String> getRefNameOptional(String namespace, String serviceName, ObjectName on,
-            Optional<String> expectedRefName) {
-        Map<String, Map<String, String>> services = getMappedServices().get(namespace);
-
-        if(services == null) return Optional.absent();
-        Map<String, String> refs = services.get(serviceName);
-
-        if(refs == null) return Optional.absent();
-        Multimap<ServiceInstance, String> reverted = revertMap(refs);
-
-        ServiceInstance serviceInstance = ServiceInstance.fromObjectName(on);
-        Collection<String> 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<ServiceInstance, String> revertMap(Map<String, String> refs) {
-        Multimap<ServiceInstance, String> multimap = HashMultimap.create();
-
-        for (Entry<String, String> 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.<String>absent()).isPresent();
-    }
-
     public static final class ServiceInstance {
         public ServiceInstance(String moduleName, String instanceName) {
             this.moduleName = moduleName;
index 11e97ebdbb9fc27c63e87d71c9962bcc494217ce..4936d1dbcda833b7fb5fdfe904d8b5e1493f6b34 100644 (file)
@@ -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<ObjectName> 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);
 
index 89c782c51c86e6acda56b426e6d76a70c2bc0c30..129143835fd024e53c290509662f968f9e691b6c 100644 (file)
@@ -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<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, ServiceReferenceReadableRegistry serviceRegistry) {
-        Services serviceTracker = new Services(serviceRegistry);
-
+    public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> 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);
                 }
index 65df965afd1e08167c63f70ba0c56159a085d2db..1d37fcd49378de3d577db338b034f987634f9518 100644 (file)
@@ -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<String, AttributeConfigElement> 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<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                                        String module, String instance, Services services);
+                                        String module, String instance, ServiceRegistryWrapper services);
 
     abstract void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
-                                  ObjectName objectName, Services services);
+                                  ObjectName objectName, ServiceRegistryWrapper services);
 
 }
index 12beaf8f8e19ff29048cb12c426c372ff047d14c..13e8c30211539485e0ac91ca1eb0ec06704e8409 100644 (file)
@@ -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<String, AttributeConfigElement> 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<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+    void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
         try {
             ta.destroyModule(on);
             logger.debug("ServiceInstance {} deleted successfully", on);
index 1bb1d9bfba7babf8fa2dc504909e4f89b6730530..ca9fb604238dcbc0a58f9359a96c22a8adece2ad 100644 (file)
@@ -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<String, Map<String, Map<String, Services.ServiceInstance>>> 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<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements, Services services, ObjectName taON) {
-        ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+    private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+
+        for (Multimap<String, ModuleElementResolved> modulesToResolved : execution.getResolvedXmlElements(ta).values()) {
 
-        for (Multimap<String, ModuleElementResolved> modulesToResolved : resolvedXmlElements.values()) {
             for (Entry<String, ModuleElementResolved> 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<String,ModuleElementDefinition> modulesToResolved : execution.getModulesDefinition(ta).values()) {
+            for (Entry<String, ModuleElementDefinition> 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));
             }
         }
     }
index 23166e8cca5c6e0d4c6fbc955de83de8db94a6f3..cebcb0239bc81cda1d7ef6a83bc0f15b8c3bdd90 100644 (file)
@@ -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<String, AttributeConfigElement> configuration,
-                              ConfigTransactionClient ta, Services services);
+                              ConfigTransactionClient ta, ServiceRegistryWrapper services);
 
 }
index 81327133b82a440c9b7599672134e7b63fd00f49..e481bbe57f68bf4d043a8365362ce2c90ab46893 100644 (file)
@@ -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<String, Multimap<String, ModuleElementResolved>> 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<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements() {
-            return resolvedXmlElements;
+        Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) {
+            return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
+        }
+
+        ServiceRegistryWrapper getServiceRegistryWrapper(ServiceReferenceReadableRegistry serviceRegistry) {
+            // TODO cache service registry
+            return new ServiceRegistryWrapper(serviceRegistry);
+        }
+
+        Map<String, Multimap<String,ModuleElementDefinition>> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) {
+            return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
         }
 
         EditStrategyType getDefaultStrategy() {
index 06befb0565067592b58465782d66caa74a568100..f2e2b193a8f1b7d90380c3cee6916a1a9b0514c1 100644 (file)
@@ -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<String, AttributeConfigElement> 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<String, String> providedServices, String module,
-            String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
+    private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
         for (Entry<String, String> 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<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+    void executeStrategy(Map<String, AttributeConfigElement> 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<String, AttributeConfigElement> 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 (file)
index 0000000..8ed9eb8
--- /dev/null
@@ -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<String, AttributeConfigElement> 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<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+            ObjectName objectName, ServiceRegistryWrapper services) {
+        return;
+    }
+}
index 8347c6b88e23325fa579527a5f30785a99216b7d..bd182a4267280021ef2c6a66f50db98af020c26b 100644 (file)
@@ -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<String, AttributeConfigElement> configuration,
-                                     ConfigTransactionClient ta, Services services) {
+                                     ConfigTransactionClient ta, ServiceRegistryWrapper services) {
         logger.debug("Skipping configuration element for {}:{}", module, instance);
     }
 
index 64f082da40773b4a6dab473bed7e45722847ffca..df1f65372aea4068fdea45fde41c20c4217a9181 100644 (file)
@@ -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<String, AttributeConfigElement> 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);
     }
 }
index 43d852e76a32f3b35a8bee016b6ca4ab4f8c6d04..4976244eae57cb6eadfec806620a10f43a2387d4 100644 (file)
@@ -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<String, AttributeConfigElement> 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<String, String> providedServices, String module,
-                             String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
+    private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
         for (Entry<String, String> 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<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+    void executeStrategy(Map<String, AttributeConfigElement> 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<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
             try {
                 AttributeConfigElement ace = configAttributeEntry.getValue();
index efe4f7dde9b483bd488e753a90cee2a335b4de05..21771b64c78bd6412c51032f207d2d2c90b32ae3 100644 (file)
@@ -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);
 
index d75cfd5d6f049d9d586ac856fa0ccd7b70b3c00c..42f8c2dd8bede11c30fc183ebcdfd84b603c3a79 100644 (file)
@@ -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);
index 11cf1aae6a42bc184dda8288dddcafa9ba47f419..9511673ea40781446c4134f02d3b1defbe47353a 100644 (file)
@@ -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);
 
 
index 6e7a225f38452250ca4803c17ac56a2d2999822f..505a91c6cec4ba7f4ce1139059538d322cf8ed69 100644 (file)
@@ -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<String, Multimap<String, ModuleElementDefinition>> result = Maps.newHashMap();
+
+        Multimap<String, ModuleElementDefinition> innerMultimap = HashMultimap.create();
+        Map<String, AttributeConfigElement> 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<String, Multimap<String, ModuleElementResolved>> getMapping(EditConfigStrategy editStrat) {
index 15ed5c48fab01635635ea6578c3017d1bcd94a82..2a95cca937ddbee88a7f0723b47f2991d0c64a5f 100644 (file)
@@ -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 (file)
index 0000000..6e68326
--- /dev/null
@@ -0,0 +1,38 @@
+<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+    <edit-config>
+        <target>
+            <candidate/>
+        </target>
+        <test-option>
+            test-only
+        </test-option>
+        <default-operation>merge</default-operation>
+        <config>
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+                <module>
+                    <name>instance-from-code_dep</name>
+                    <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+                        test-impl:impl-dep
+                    </type>
+                </module>
+            </modules>
+
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <service>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+                    <instance>
+                        <name>ref_dep_user_another_test1</name>
+                        <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
+                        </provider>
+                    </instance>
+                    <instance>
+                        <name>ref_dep_user_another_test2</name>
+                        <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
+                        </provider>
+                    </instance>
+                </service>
+            </services>
+        </config>
+    </edit-config>
+</rpc>
index a7f1c863910f4b24b421531b82ffb9cb68499452..ade40f6a49c94f2a682b7e55e1ec1a3d79e03ecc 100644 (file)
                     </type>
                 </module>
 
-
                 <module>
                     <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
                         test-impl:impl-netconf
                     </type>
-                    <name>test1</name>
+                    <name>instance-from-code</name>
                     <simple-long-2>44</simple-long-2>
                     <binaryLeaf>8ad1</binaryLeaf>
                     <dto_d>
@@ -72,7 +71,7 @@
                     <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
                         test-impl:impl-netconf
                     </type>
-                    <name>test2</name>
+                    <name>test3</name>
                 </module>
             </modules>