X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fconfig-netconf-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fconfignetconfconnector%2Fmapping%2Fconfig%2FServices.java;h=77f3cf283fc2daf77c18766c4a9dacd4185f2536;hb=d1ab4c3ea79bcd74e02aa9334bc660cb7fc6d037;hp=f522668733497333b7b2ac2052fe5949985f8f51;hpb=ac65af650d550ae56dd02b660e1c5eef24b78740;p=controller.git 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 f522668733..77f3cf283f 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 @@ -9,10 +9,14 @@ 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.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; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -22,9 +26,9 @@ 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.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -33,6 +37,7 @@ 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"; @@ -42,58 +47,33 @@ public final class Services { private long suffix = 1; - private final Map instanceToRef = Maps.newHashMap(); private final Map>> namespaceToServiceNameToRefNameToInstance = Maps .newHashMap(); + private ServiceReferenceReadableRegistry configServiceRefRegistry; - 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 Services(ServiceReferenceReadableRegistry configServiceRefRegistry) { + this.configServiceRefRegistry = configServiceRefRegistry; } @VisibleForTesting - public String addServiceEntry(String namespace, String serviceName, String moduleName, String instanceName) { - ServiceInstance serviceInstance = new ServiceInstance(moduleName, instanceName); - serviceInstance.setServiceName(serviceName); + public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) { + String refName; + refName = "ref_" + instanceName; - String refName = instanceToRef.get(serviceInstance); + Map> serviceNameToRefNameToInstance = getMappedServices().get(namespace); - Map> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance.get(namespace); - if (serviceNameToRefNameToInstance == null) { - serviceNameToRefNameToInstance = Maps.newHashMap(); - namespaceToServiceNameToRefNameToInstance.put(namespace, serviceNameToRefNameToInstance); - } + Map refNameToInstance; + if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) { + refNameToInstance = Collections.emptyMap(); + } else + refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); - if (refNameToInstance == null) { - refNameToInstance = Maps.newHashMap(); - serviceNameToRefNameToInstance.put(serviceName, refNameToInstance); + final Set refNamesAsSet = toSet(refNameToInstance.keySet()); + if (refNamesAsSet.contains(refName)) { + refName = findAvailableRefName(refName, refNamesAsSet); } - 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; - } + return refName; } private Set toSet(Collection values) { @@ -109,15 +89,19 @@ public final class Services { } 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> serviceNameToRefNameToInstance = getMappedServices().get(namespace); + + Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace); - Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); + Map refNameToInstance = serviceNameToRefNameToInstance.get(serviceName); Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , " + serviceNameToRefNameToInstance.keySet()); - ServiceInstance serviceInstance = refNameToInstance.get(refName); + 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; @@ -136,26 +120,61 @@ public final class Services { 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(); - } - }); + Map innerInnerRetVal = Maps.newHashMap(); + for (Entry refNameToSi : serviceNameToRefNameToInstance.get(serviceName).entrySet()) { + innerInnerRetVal.put(refNameToSi.getKey(), refNameToSi.getValue().toString()); + } innerRetVal.put(serviceName, innerInnerRetVal); } retVal.put(namespace, innerRetVal); } + Map> serviceMapping = configServiceRefRegistry.getServiceMapping(); + for (String serviceQName : serviceMapping.keySet()) + for (String refName : serviceMapping.get(serviceQName).keySet()) { + + ObjectName on = serviceMapping.get(serviceQName).get(refName); + ServiceInstance si = ServiceInstance.fromObjectName(on); + + // FIXME use QName's new String constructor, after its implemented + Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)"); + Matcher matcher = p.matcher(serviceQName); + Preconditions.checkArgument(matcher.matches()); + String namespace = matcher.group(1); + String localName = matcher.group(2); + + Map> serviceToRefs = retVal.get(namespace); + if(serviceToRefs==null) { + serviceToRefs = Maps.newHashMap(); + retVal.put(namespace, serviceToRefs); + } + + Map refsToSis = serviceToRefs.get(localName); + if(refsToSis==null) { + refsToSis = Maps.newHashMap(); + serviceToRefs.put(localName, refsToSis); + } + + Preconditions.checkState(refsToSis.containsKey(refName) == false, + "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace, + localName, on); + refsToSis.put(refName, si.toString()); + } + return retVal; } + /** + * + */ + public Map>> getNamespaceToServiceNameToRefNameToInstance() { + return namespaceToServiceNameToRefNameToInstance; + } + // TODO hide resolveServices, call it explicitly in fromXml - public static Services resolveServices(Map>> mappedServices) { - Services tracker = new Services(); + public static Services resolveServices(Map>> mappedServices, ServiceReferenceReadableRegistry taClient) { + Services tracker = new Services(taClient); for (Entry>> namespaceEntry : mappedServices.entrySet()) { String namespace = namespaceEntry.getKey(); @@ -179,18 +198,18 @@ 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; } + // TODO support edit strategies on services + public static Map>> fromXml(XmlElement xml) { Map>> retVal = Maps.newHashMap(); @@ -275,6 +294,51 @@ public final class Services { return root; } + public String getRefName(String namespace, String serviceName, ObjectName on, Optional expectedRefName) { + Optional refNameOptional = getRefNameOptional(namespace, serviceName, on, expectedRefName); + Preconditions.checkState(refNameOptional.isPresent(), "No reference names mapped to %s, %s, %s", namespace, + serviceName, on); + return refNameOptional.get(); + } + + public Optional getRefNameOptional(String namespace, String serviceName, ObjectName on, + Optional expectedRefName) { + Map> services = getMappedServices().get(namespace); + + if(services == null) return Optional.absent(); + Map refs = services.get(serviceName); + + if(refs == null) return Optional.absent(); + Multimap reverted = revertMap(refs); + + ServiceInstance serviceInstance = ServiceInstance.fromObjectName(on); + Collection references = reverted.get(serviceInstance); + + if (expectedRefName.isPresent() && references.contains(expectedRefName.get())) { + logger.debug("Returning expected ref name {} for {}", expectedRefName.get(), on); + return expectedRefName; + } else if (references.size() > 0) { + String next = references.iterator().next(); + logger.debug("Returning random ref name {} for {}", next, on); + return Optional.of(next); + } else + return Optional.absent(); + } + + private Multimap revertMap(Map refs) { + Multimap multimap = HashMultimap.create(); + + for (Entry e : refs.entrySet()) { + multimap.put(ServiceInstance.fromString(e.getValue()), e.getKey()); + } + + return multimap; + } + + public boolean hasRefName(String key, String value, ObjectName on) { + return getRefNameOptional(key, value, on, Optional.absent()).isPresent(); + } + public static final class ServiceInstance { public ServiceInstance(String moduleName, String instanceName) { this.moduleName = moduleName; @@ -372,6 +436,13 @@ public final class Services { 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)); + } } }