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%2FServices.java;h=eb5c018cf3db0af76ced902576543861b732a4f6;hp=e4fa6f504b7b86799c1276875c2471a5719f5892;hb=3e20a64a21d5b7bced26b03108aedcd025dd8be6;hpb=a87db38d47967eae159c5be17ab334bb6a4edffc diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java index e4fa6f504b..eb5c018cf3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java @@ -8,153 +8,43 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; +import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; -import javax.annotation.Nullable; import javax.management.ObjectName; -import java.util.Collection; 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; public final class Services { - private static final Logger logger = LoggerFactory.getLogger(Services.class); private static final String PROVIDER_KEY = "provider"; private static final String NAME_KEY = "name"; public static final String TYPE_KEY = "type"; public static final String SERVICE_KEY = "service"; - private long suffix = 1; - - private final Map instanceToRef = Maps.newHashMap(); private final Map>> namespaceToServiceNameToRefNameToInstance = Maps .newHashMap(); - public String addServiceEntry(String namespace, String serviceName, ObjectName on) { - - String moduleName = on.getKeyProperty("moduleFactoryName"); - String instanceName = on.getKeyProperty("instanceName"); - - String refName = addServiceEntry(namespace, serviceName, moduleName, instanceName); - logger.trace("Added service entry to tracker. Service name {}, ref name {}, module name {}, instance name {}", - serviceName, refName, moduleName, instanceName); - return refName; + /** + * + */ + public Map>> getNamespaceToServiceNameToRefNameToInstance() { + return namespaceToServiceNameToRefNameToInstance; } - @VisibleForTesting - public String addServiceEntry(String namespace, String serviceName, String moduleName, String instanceName) { - ServiceInstance serviceInstance = new ServiceInstance(moduleName, instanceName); - serviceInstance.setServiceName(serviceName); - - String refName = instanceToRef.get(serviceInstance); - - Map> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance.get(namespace); - if (serviceNameToRefNameToInstance == null) { - serviceNameToRefNameToInstance = Maps.newHashMap(); - namespaceToServiceNameToRefNameToInstance.put(namespace, serviceNameToRefNameToInstance); - } - - Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - if (refNameToInstance == null) { - refNameToInstance = Maps.newHashMap(); - serviceNameToRefNameToInstance.put(serviceName, refNameToInstance); - } - - if (refName != null) { - if (serviceNameToRefNameToInstance.get(serviceName).containsKey(moduleName) == false) { - refNameToInstance.put(refName, serviceInstance); - } - return refName; - } else { - refName = "ref_" + instanceName; - - final Set refNamesAsSet = toSet(instanceToRef.values()); - if (refNamesAsSet.contains(refName)) { - refName = findAvailableRefName(refName, refNamesAsSet); - } - - instanceToRef.put(serviceInstance, refName); - refNameToInstance.put(refName, serviceInstance); - - return refName; - } - } - - private Set toSet(Collection values) { - Set refNamesAsSet = Sets.newHashSet(); - - for (String refName : values) { - boolean resultAdd = refNamesAsSet.add(refName); - Preconditions.checkState(resultAdd, - "Error occurred building services element, reference name {} was present twice", refName); - } - - return refNamesAsSet; - } - - public ServiceInstance getByServiceAndRefName(String namespace, String serviceName, String refName) { - Map> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance.get(namespace); - Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace + " , " - + serviceNameToRefNameToInstance.keySet()); - - Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , " - + serviceNameToRefNameToInstance.keySet()); - - ServiceInstance serviceInstance = refNameToInstance.get(refName); - Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName - + " under service name " + serviceName + " , " + refNameToInstance.keySet()); - return serviceInstance; - } - - // TODO hide getMappedServices, call it explicitly in toXml - - public Map>> getMappedServices() { - Map>> retVal = Maps.newHashMap(); - - for (String namespace : namespaceToServiceNameToRefNameToInstance.keySet()) { - - Map> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance - .get(namespace); - Map> innerRetVal = Maps.newHashMap(); - - for (String serviceName : serviceNameToRefNameToInstance.keySet()) { - - Map innerInnerRetVal = Maps.transformValues( - serviceNameToRefNameToInstance.get(serviceName), new Function() { - @Nullable - @Override - public String apply(@Nullable ServiceInstance serviceInstance) { - return serviceInstance.toString(); - } - }); - innerRetVal.put(serviceName, innerInnerRetVal); - } - retVal.put(namespace, innerRetVal); - } - - return retVal; - } - - // TODO hide resolveServices, call it explicitly in fromXml - - public static Services resolveServices(Map>> mappedServices) { + private static Services resolveServices(Map>> mappedServices) { Services tracker = new Services(); for (Entry>> namespaceEntry : mappedServices.entrySet()) { @@ -179,19 +69,19 @@ public final class Services { } String refName = refEntry.getKey(); - Preconditions.checkState(false == refNameToInstance.containsKey(refName), - "Duplicate reference name to service " + refName + " under service " + serviceName); + ServiceInstance serviceInstance = ServiceInstance.fromString(refEntry.getValue()); refNameToInstance.put(refName, serviceInstance); - tracker.instanceToRef.put(serviceInstance, refEntry.getKey()); } } } return tracker; } - public static Map>> fromXml(XmlElement xml) { + // TODO support edit strategies on services + + public static Services fromXml(XmlElement xml) throws NetconfDocumentedException { Map>> retVal = Maps.newHashMap(); List services = xml.getChildElements(SERVICE_KEY); @@ -202,7 +92,7 @@ public final class Services { XmlElement typeElement = service.getOnlyChildElement(TYPE_KEY); Entry prefixNamespace = typeElement.findNamespaceOfTextContent(); - Preconditions.checkState(prefixNamespace.getKey()!=null && prefixNamespace.getKey().equals("") == false, "Type attribute was not prefixed"); + Preconditions.checkState(prefixNamespace.getKey()!=null && !prefixNamespace.getKey().equals(""), "Type attribute was not prefixed"); Map> namespaceToServices = retVal.get(prefixNamespace.getValue()); if(namespaceToServices == null) { @@ -231,42 +121,31 @@ public final class Services { } } - return retVal; + return resolveServices(retVal); } - private String findAvailableRefName(String refName, Set refNamesAsSet) { - String intitialRefName = refName; - - while (true) { - refName = intitialRefName + "_" + suffix++; - if (refNamesAsSet.contains(refName) == false) - return refName; - } - } - - public Element toXml(Map>> mappedServices, Document document) { - Element root = document.createElement(XmlNetconfConstants.SERVICES_KEY); - XmlUtil.addNamespaceAttr(root, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + public static Element toXml(ServiceRegistryWrapper serviceRegistryWrapper, Document document) { + Element root = XmlUtil.createElement(document, XmlNetconfConstants.SERVICES_KEY, Optional.of(XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG)); + Map>> mappedServices = serviceRegistryWrapper.getMappedServices(); for (String namespace : mappedServices.keySet()) { for (Entry> serviceEntry : mappedServices.get(namespace).entrySet()) { - Element serviceElement = document.createElement(SERVICE_KEY); + Element serviceElement = XmlUtil.createElement(document, SERVICE_KEY, Optional.absent()); root.appendChild(serviceElement); - Element typeElement = XmlUtil.createPrefixedTextElement(document, TYPE_KEY, XmlNetconfConstants.PREFIX, - serviceEntry.getKey()); - XmlUtil.addPrefixedNamespaceAttr(typeElement, XmlNetconfConstants.PREFIX, namespace); + Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(XmlNetconfConstants.PREFIX, TYPE_KEY), XmlNetconfConstants.PREFIX, + serviceEntry.getKey(), Optional.of(namespace)); serviceElement.appendChild(typeElement); for (Entry instanceEntry : serviceEntry.getValue().entrySet()) { - Element instanceElement = document.createElement(XmlNetconfConstants.INSTANCE_KEY); + Element instanceElement = XmlUtil.createElement(document, XmlNetconfConstants.INSTANCE_KEY, Optional.absent()); serviceElement.appendChild(instanceElement); - Element nameElement = XmlUtil.createTextElement(document, NAME_KEY, instanceEntry.getKey()); + Element nameElement = XmlUtil.createTextElement(document, NAME_KEY, instanceEntry.getKey(), Optional.absent()); instanceElement.appendChild(nameElement); - Element providerElement = XmlUtil.createTextElement(document, PROVIDER_KEY, instanceEntry.getValue()); + Element providerElement = XmlUtil.createTextElement(document, PROVIDER_KEY, instanceEntry.getValue(), Optional.absent()); instanceElement.appendChild(providerElement); } } @@ -284,8 +163,13 @@ public final class Services { public static ServiceInstance fromString(String instanceId) { instanceId = instanceId.trim(); Matcher matcher = p.matcher(instanceId); + if(!matcher.matches()) { + matcher = pDeprecated.matcher(instanceId); + } + Preconditions.checkArgument(matcher.matches(), "Unexpected format for provider, expected " + p.toString() - + " but was " + instanceId); + + " or " + pDeprecated.toString() + " but was " + instanceId); + String factoryName = matcher.group(1); String instanceName = matcher.group(2); return new ServiceInstance(factoryName, instanceName); @@ -310,16 +194,25 @@ public final class Services { return instanceName; } - private static final String blueprint = "/" + XmlNetconfConstants.CONFIG_KEY + "/" + private static final String blueprint = "/" + XmlNetconfConstants.MODULES_KEY + "/" + XmlNetconfConstants.MODULE_KEY + "[" - + XmlNetconfConstants.NAME_KEY + "='%s']/" + XmlNetconfConstants.INSTANCE_KEY + "[" + + XmlNetconfConstants.TYPE_KEY + "='%s'][" + XmlNetconfConstants.NAME_KEY + "='%s']"; - private static final String blueprintR = "/" + XmlNetconfConstants.CONFIG_KEY + "/" + // TODO unify with xpath in RuntimeRpc + + // Previous version of xpath, needs to be supported for backwards compatibility (persisted configs by config-persister) + private static final String blueprintRDeprecated = "/" + XmlNetconfConstants.CONFIG_KEY + "/" + XmlNetconfConstants.MODULES_KEY + "/" + XmlNetconfConstants.MODULE_KEY + "\\[" + XmlNetconfConstants.NAME_KEY + "='%s'\\]/" + XmlNetconfConstants.INSTANCE_KEY + "\\[" + XmlNetconfConstants.NAME_KEY + "='%s'\\]"; + private static final String blueprintR = "/" + + XmlNetconfConstants.MODULES_KEY + "/" + XmlNetconfConstants.MODULE_KEY + "\\[" + + XmlNetconfConstants.TYPE_KEY + "='%s'\\]\\[" + + XmlNetconfConstants.NAME_KEY + "='%s'\\]"; + + private static final Pattern pDeprecated = Pattern.compile(String.format(blueprintRDeprecated, "(.+)", "(.+)")); private static final Pattern p = Pattern.compile(String.format(blueprintR, "(.+)", "(.+)")); @Override @@ -338,26 +231,40 @@ public final class Services { @Override public boolean equals(Object obj) { - if (this == obj) + if (this == obj){ return true; - if (obj == null) + } + if (obj == null){ return false; - if (getClass() != obj.getClass()) + } + if (getClass() != obj.getClass()){ return false; + } ServiceInstance other = (ServiceInstance) obj; if (instanceName == null) { - if (other.instanceName != null) + if (other.instanceName != null){ return false; - } else if (!instanceName.equals(other.instanceName)) + } + } else if (!instanceName.equals(other.instanceName)){ return false; + } if (moduleName == null) { - if (other.moduleName != null) + if (other.moduleName != null){ return false; - } else if (!moduleName.equals(other.moduleName)) + } + } else if (!moduleName.equals(other.moduleName)){ return false; + } return true; } + public ObjectName getObjectName(String transactionName) { + return ObjectNameUtil.createTransactionModuleON(transactionName, moduleName, instanceName); + } + + public static ServiceInstance fromObjectName(ObjectName on) { + return new ServiceInstance(ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on)); + } } }