Merge "Fixed bug when converting augmentation in Instance Identifier"
[controller.git] / opendaylight / netconf / config-netconf-connector / src / main / java / org / opendaylight / controller / netconf / confignetconfconnector / mapping / config / ServiceRegistryWrapper.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
9
10 import com.google.common.annotations.VisibleForTesting;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.Maps;
13 import com.google.common.collect.Sets;
14 import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
15
16 import javax.management.InstanceNotFoundException;
17 import javax.management.ObjectName;
18 import java.util.Collection;
19 import java.util.Collections;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
24
25 public class ServiceRegistryWrapper {
26
27     private ServiceReferenceReadableRegistry configServiceRefRegistry;
28
29     private long suffix = 1;
30
31     public ServiceRegistryWrapper(ServiceReferenceReadableRegistry configServiceRefRegistry) {
32         this.configServiceRefRegistry = configServiceRefRegistry;
33     }
34
35
36     public boolean hasRefName(String namespace, String serviceName, ObjectName on) {
37         String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
38         Map<String, ObjectName> forQName = configServiceRefRegistry.getServiceMapping().get(qname);
39         if(forQName==null) return false;
40         return forQName.values().contains(on);
41     }
42
43     public ObjectName getByServiceAndRefName(String namespace, String serviceName, String refName) {
44         Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
45
46         Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
47
48         Map<String, String> refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
49         Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , "
50                 + serviceNameToRefNameToInstance.keySet());
51
52         String instanceId = refNameToInstance.get(refName);
53         Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":"
54                 + refName + ", " + serviceNameToRefNameToInstance.keySet());
55
56         Services.ServiceInstance serviceInstance = Services.ServiceInstance.fromString(instanceId);
57         Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName
58                 + " under service name " + serviceName + " , " + refNameToInstance.keySet());
59
60         String qNameOfService = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
61         try {
62             return configServiceRefRegistry.getServiceReference(qNameOfService, refName);
63         } catch (InstanceNotFoundException e) {
64             throw new IllegalArgumentException("No serviceInstance mapped to " + refName
65                     + " under service name " + serviceName + " , " + refNameToInstance.keySet(), e);
66
67         }
68     }
69
70     public Map<String, Map<String, Map<String, String>>> getMappedServices() {
71         Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
72
73         Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
74         for (String serviceQName : serviceMapping.keySet())
75             for (String refName : serviceMapping.get(serviceQName).keySet()) {
76
77                 ObjectName on = serviceMapping.get(serviceQName).get(refName);
78                 Services.ServiceInstance si = Services.ServiceInstance.fromObjectName(on);
79
80                 // FIXME use QName's new String constructor, after it is fixed
81 //                QName qname;
82 //                try {
83 //                    qname = new QName(serviceQName);
84 //                } catch (ParseException e) {
85 //                    throw new IllegalStateException("Unable to parse qname of a service " + serviceQName, e);
86 //                }
87                 Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)");
88                 Matcher matcher = p.matcher(serviceQName);
89                 Preconditions.checkArgument(matcher.matches());
90                 String namespace = matcher.group(1);
91                 String localName = matcher.group(2);
92
93 //                String namespace = qname.getNamespace().toString();
94                 Map<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
95                 if(serviceToRefs==null) {
96                     serviceToRefs = Maps.newHashMap();
97                     retVal.put(namespace, serviceToRefs);
98                 }
99
100 //                String localName = qname.getLocalName();
101                 Map<String, String> refsToSis = serviceToRefs.get(localName);
102                 if(refsToSis==null) {
103                     refsToSis = Maps.newHashMap();
104                     serviceToRefs.put(localName, refsToSis);
105                 }
106
107                 Preconditions.checkState(refsToSis.containsKey(refName) == false,
108                         "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
109                         localName, on);
110                 refsToSis.put(refName, si.toString());
111             }
112
113         return retVal;
114     }
115
116     @VisibleForTesting
117     public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) {
118         String refName;
119         refName = "ref_" + instanceName;
120
121         Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
122
123         Map<String, String> refNameToInstance;
124         if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
125             refNameToInstance = Collections.emptyMap();
126         } else
127             refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
128
129         final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
130         if (refNamesAsSet.contains(refName)) {
131             refName = findAvailableRefName(refName, refNamesAsSet);
132         }
133
134         return refName;
135     }
136
137
138     private Set<String> toSet(Collection<String> values) {
139         Set<String> refNamesAsSet = Sets.newHashSet();
140
141         for (String refName : values) {
142             boolean resultAdd = refNamesAsSet.add(refName);
143             Preconditions.checkState(resultAdd,
144                     "Error occurred building services element, reference name {} was present twice", refName);
145         }
146
147         return refNamesAsSet;
148     }
149
150     private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
151         String intitialRefName = refName;
152
153         while (true) {
154             refName = intitialRefName + "_" + suffix++;
155             if (refNamesAsSet.contains(refName) == false)
156                 return refName;
157         }
158     }
159 }