X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fconfig-netconf-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fconfignetconfconnector%2Fmapping%2Fconfig%2FConfig.java;h=decb091f866f085ae36034d21c7ee4908685170b;hp=f33a32271fd189dd39a61b7403069d765e4d1615;hb=9c9d6e69da3aff2d0576d8c15ea0fa0692595b6d;hpb=4f4df9918bc2d1447393edac6fbf3a2d4f9d9186 diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java index f33a32271f..decb091f86 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java @@ -8,13 +8,22 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -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 static com.google.common.base.Preconditions.checkState; +import static java.lang.String.format; + +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.management.ObjectName; + import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig; import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -24,17 +33,12 @@ import org.slf4j.LoggerFactory; 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.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import static com.google.common.base.Preconditions.checkState; -import static java.lang.String.format; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; public class Config { private final Logger logger = LoggerFactory.getLogger(Config.class); @@ -43,17 +47,24 @@ public class Config { Map> moduleConfigs; private final Map moduleNamesToConfigs; + private final Map> identityMap; + public Config(Map> moduleConfigs) { + this(moduleConfigs, Collections.>emptyMap()); + } + + public Config(Map> moduleConfigs, Map> identityMap) { this.moduleConfigs = moduleConfigs; Map moduleNamesToConfigs = new HashMap<>(); for (Entry> entry : moduleConfigs.entrySet()) { moduleNamesToConfigs.putAll(entry.getValue()); } this.moduleNamesToConfigs = Collections.unmodifiableMap(moduleNamesToConfigs); + this.identityMap = identityMap; } public static Map>> getMappedInstances(Set instancesToMap, - Services serviceTracker, Map> configs) { + Map> configs) { Multimap moduleToInstances = mapInstancesToModules(instancesToMap); Map>> retVal = Maps.newLinkedHashMap(); @@ -75,13 +86,6 @@ public class Config { innerRetVal.put(moduleName, instances); - // All found instances add to service tracker in advance - // This way all instances will be serialized as all available - // services when get-config is triggered - // (even if they are not used as services by other instances) - // = more user friendly - addServices(serviceTracker, instances, mbeEntry.getValue().getProvidedServices()); - } retVal.put(namespace, innerRetVal); @@ -89,15 +93,6 @@ public class Config { return retVal; } - private static void addServices(Services serviceTracker, Collection instances, - Multimap providedServices) { - for (ObjectName instanceOn : instances) { - for (Entry serviceName : providedServices.entries()) { - serviceTracker.addServiceEntry(serviceName.getKey(), serviceName.getValue(), instanceOn); - } - } - } - private static Multimap mapInstancesToModules(Set instancesToMap) { Multimap retVal = HashMultimap.create(); @@ -114,20 +109,17 @@ public class Config { // } public Element toXml(Set instancesToMap, Optional maybeNamespace, Document document, - Element dataElement) { - Services serviceTracker = new Services(); + Element dataElement, ServiceRegistryWrapper serviceTracker) { Map>> moduleToInstances = getMappedInstances(instancesToMap, - serviceTracker, moduleConfigs); + moduleConfigs); Element root = dataElement; if (maybeNamespace.isPresent()) { - XmlUtil.addNamespaceAttr(root, maybeNamespace.get()); + root.setAttributeNS(maybeNamespace.get(), dataElement.getNodeName(), "xmlns"); } - Element modulesElement = document.createElement(XmlNetconfConstants.MODULES_KEY); - XmlUtil.addNamespaceAttr(modulesElement, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + Element modulesElement = XmlUtil.createElement(document, XmlNetconfConstants.MODULES_KEY, Optional.of(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG)); root.appendChild(modulesElement); for (String moduleNamespace : moduleToInstances.keySet()) { for (Entry> moduleMappingEntry : moduleToInstances.get(moduleNamespace) @@ -136,62 +128,84 @@ public class Config { ModuleConfig mapping = moduleConfigs.get(moduleNamespace).get(moduleMappingEntry.getKey()); if (moduleMappingEntry.getValue().isEmpty()) { - addEmptyModulesCommented(document, modulesElement, moduleNamespace, moduleMappingEntry); - } else { - for (ObjectName objectName : moduleMappingEntry.getValue()) { - modulesElement - .appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace)); - } + continue; + } + + for (ObjectName objectName : moduleMappingEntry.getValue()) { + modulesElement.appendChild(mapping.toXml(objectName, serviceTracker, document, moduleNamespace)); } } } - root.appendChild(serviceTracker.toXml(serviceTracker.getMappedServices(), document)); + root.appendChild(Services.toXml(serviceTracker, document)); return root; } - // TODO remove commented modules from output - private void addEmptyModulesCommented(Document document, Element root, String moduleNamespace, - Entry> moduleMappingEntry) { - Element emptyModule = document.createElement(XmlNetconfConstants.MODULE_KEY); - - Element typeElement = XmlUtil.createTextElement(document, XmlNetconfConstants.TYPE_KEY, - moduleMappingEntry.getKey()); - emptyModule.appendChild(typeElement); - - root.appendChild(document.createComment(XmlUtil.toString(emptyModule, false))); - } - // TODO refactor, replace string representing namespace with namespace class // TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved // class - public Map> fromXml(XmlElement xml, Set instancesForFillingServiceRefMapping, - EditStrategyType defaultEditStrategyType) { + + public Map> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + Optional modulesElement = getModulesElement(xml); + List moduleElements = getModulesElementList(modulesElement); + Map> retVal = Maps.newHashMap(); - List recognisedChildren = Lists.newArrayList(); + for (XmlElement moduleElement : moduleElements) { + ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { + @Override + public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) { + return moduleMapping.fromXml(moduleElement, serviceTracker, + instanceName, moduleNamespace, defaultStrategy, identityMap); + } + }; + + resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy); + } + return retVal; + } - Services serviceTracker = fromXmlServices(xml, recognisedChildren, instancesForFillingServiceRefMapping); - List moduleElements = fromXmlModules(xml, recognisedChildren); + /** + * return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted. + */ + public Map> fromXmlModulesMap(XmlElement xml, + EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) { + Optional modulesElement = getModulesElement(xml); + List moduleElements = getModulesElementList(modulesElement); - xml.checkUnrecognisedElements(recognisedChildren); + Map> retVal = Maps.newHashMap(); for (XmlElement moduleElement : moduleElements) { - resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType); - } + ResolvingStrategy resolvingStrategy = new ResolvingStrategy() { + @Override + public ModuleElementDefinition resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, + ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, + EditStrategyType defaultStrategy) { + // TODO: add check for conflicts between global and local + // edit strategy + String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY, + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); + return new ModuleElementDefinition(instanceName, perInstanceEditStrategy, defaultStrategy); + } + }; + resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy); + } return retVal; } - private List fromXmlModules(XmlElement xml, List recognisedChildren) { - Optional modulesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + private static Optional getModulesElement(XmlElement xml) { + return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY, + XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + } + + private List getModulesElementList(Optional modulesElement) { List moduleElements; + if (modulesElement.isPresent()) { moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY); - recognisedChildren.add(modulesElement.get()); modulesElement.get().checkUnrecognisedElements(moduleElements); } else { moduleElements = Lists.newArrayList(); @@ -199,8 +213,8 @@ public class Config { return moduleElements; } - private void resolveModule(Map> retVal, Services serviceTracker, - XmlElement moduleElement, EditStrategyType defaultStrategy) { + private void resolveModule(Map> retVal, ServiceRegistryWrapper serviceTracker, + XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy resolvingStrategy) { XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); Entry prefixToNamespace = typeElement.findNamespaceOfTextContent(); String moduleNamespace = prefixToNamespace.getValue(); @@ -212,47 +226,47 @@ public class Config { ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName); - Multimap innerMap = retVal.get(moduleNamespace); + Multimap innerMap = retVal.get(moduleNamespace); if (innerMap == null) { innerMap = HashMultimap.create(); retVal.put(moduleNamespace, innerMap); } - ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker, + T resolvedElement = resolvingStrategy.resolveElement(moduleMapping, moduleElement, serviceTracker, instanceName, moduleNamespace, defaultStrategy); - innerMap.put(factoryName, moduleElementResolved); + innerMap.put(factoryName, resolvedElement); } - private Services fromXmlServices(XmlElement xml, List recognisedChildren, Set instancesForFillingServiceRefMapping) { - Optional servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY, - XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + public Services fromXmlServices(XmlElement xml) { + Optional servicesElement = getServicesElement(xml); - Map>> mappedServices; + Services services; if (servicesElement.isPresent()) { - mappedServices = Services.fromXml(servicesElement.get()); - recognisedChildren.add(servicesElement.get()); + services = Services.fromXml(servicesElement.get()); } else { - mappedServices = new HashMap<>(); + services = new Services(); } - Services services = Services.resolveServices(mappedServices); - // merge with what candidate db contains by default - ref_ - for(ObjectName existingON: instancesForFillingServiceRefMapping) { - logger.trace("Filling services from {}", existingON); - // get all its services - String factoryName = ObjectNameUtil.getFactoryName(existingON); - ModuleConfig moduleConfig = moduleNamesToConfigs.get(factoryName); + return services; + } - checkState(moduleConfig != null, "Cannot find ModuleConfig with name " + factoryName + " in " + moduleNamesToConfigs); - // Set services = ; - for (Entry serviceName : moduleConfig.getProvidedServices().entries()) { + private static Optional getServicesElement(XmlElement xml) { + return xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY, + XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + } - services.addServiceEntry(serviceName.getKey(), serviceName.getValue(), existingON); - } - } + public static void checkUnrecognisedChildren(XmlElement parent) { + Optional servicesOpt = getServicesElement(parent); + Optional modulesOpt = getModulesElement(parent); - return services; + List recognised = Lists.newArrayList(); + if(servicesOpt.isPresent()) + recognised.add(servicesOpt.get()); + if(modulesOpt.isPresent()) + recognised.add(modulesOpt.get()); + + parent.checkUnrecognisedElements(recognised); } private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) { @@ -282,4 +296,8 @@ public class Config { return moduleMapping; } + private interface ResolvingStrategy { + public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, + String instanceName, String moduleNamespace, EditStrategyType defaultStrategy); + } }