Merge "Bug-835:Reserve ports should be logical ports"
[controller.git] / opendaylight / netconf / config-netconf-connector / src / main / java / org / opendaylight / controller / netconf / confignetconfconnector / operations / runtimerpc / RuntimeRpcElementResolved.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
9 package org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc;
10
11 import com.google.common.base.Preconditions;
12 import com.google.common.base.Strings;
13 import com.google.common.collect.Maps;
14
15 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
16 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
17 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.ModuleRpcs;
18
19 import javax.management.ObjectName;
20
21 import java.util.HashMap;
22 import java.util.Map;
23 import java.util.regex.Matcher;
24 import java.util.regex.Pattern;
25
26 /**
27  * Represents parsed xpath to runtime bean instance
28  */
29 public final class RuntimeRpcElementResolved {
30     private final String moduleName;
31     private final String instanceName;
32     private final String namespace;
33     private final String runtimeBeanName;
34     private final Map<String, String> additionalAttributes;
35
36     private RuntimeRpcElementResolved(String namespace, String moduleName, String instanceName, String runtimeBeanName,
37             Map<String, String> additionalAttributes) {
38         this.moduleName = Preconditions.checkNotNull(moduleName, "Module name");
39         this.instanceName =  Preconditions.checkNotNull(instanceName, "Instance name");
40         this.additionalAttributes = additionalAttributes;
41         this.namespace = Preconditions.checkNotNull(namespace, "Namespace");
42         this.runtimeBeanName = Preconditions.checkNotNull(runtimeBeanName, "Runtime bean name");
43     }
44
45     public String getModuleName() {
46         return moduleName;
47     }
48
49     public String getInstanceName() {
50         return instanceName;
51     }
52
53     public String getNamespace() {
54         return namespace;
55     }
56
57     public String getRuntimeBeanName() {
58         return runtimeBeanName;
59     }
60
61     public ObjectName getObjectName(ModuleRpcs rpcMapping) {
62         Map<String, String> additionalAttributesJavaNames = Maps
63                 .newHashMapWithExpectedSize(additionalAttributes.size());
64         for (String attributeYangName : additionalAttributes.keySet()) {
65             String attributeJavaName = rpcMapping.getRbeJavaName(attributeYangName);
66             Preconditions.checkState(attributeJavaName != null,
67                     "Cannot find java name for runtime bean wtih yang name %s", attributeYangName);
68             additionalAttributesJavaNames.put(attributeJavaName, additionalAttributes.get(attributeYangName));
69         }
70         return ObjectNameUtil.createRuntimeBeanName(moduleName, instanceName, additionalAttributesJavaNames);
71     }
72
73     private static final String xpathPatternBlueprint =
74             "/" + XmlNetconfConstants.MODULES_KEY
75             + "/" + XmlNetconfConstants.MODULE_KEY
76             + "\\["
77
78             + "(?<key1>type|name)"
79             + "='(?<value1>[^']+)'"
80             + "( and |\\]\\[)"
81             + "(?<key2>type|name)"
82             + "='(?<value2>[^']+)'"
83
84             + "\\]"
85             + "(?<additional>.*)";
86
87     private static final Pattern xpathPattern = Pattern.compile(xpathPatternBlueprint);
88     private static final String additionalPatternBlueprint = "(?<additionalKey>.+)\\[(.+)='(?<additionalValue>.+)'\\]";
89     private static final Pattern additionalPattern = Pattern.compile(additionalPatternBlueprint);
90
91     public static RuntimeRpcElementResolved fromXpath(String xpath, String elementName, String namespace) {
92         Matcher matcher = xpathPattern.matcher(xpath);
93         Preconditions.checkState(matcher.matches(),
94                 "Node %s with value '%s' not in required form on rpc element %s, required format is %s",
95                 RuntimeRpc.CONTEXT_INSTANCE, xpath, elementName, xpathPatternBlueprint);
96
97         PatternGroupResolver groups = new PatternGroupResolver(matcher.group("key1"), matcher.group("value1"),
98                 matcher.group("value2"), matcher.group("additional"));
99
100         String moduleName = groups.getModuleName();
101         String instanceName = groups.getInstanceName();
102
103         Map<String, String> additionalAttributes = groups.getAdditionalKeys(elementName, moduleName);
104
105         return new RuntimeRpcElementResolved(namespace, moduleName, instanceName, groups.getRuntimeBeanYangName(),
106                 additionalAttributes);
107     }
108
109     private static final class PatternGroupResolver {
110
111         private final String key1, value1, value2;
112         private final String additional;
113         private String runtimeBeanYangName;
114
115         PatternGroupResolver(String key1, String value1,  String value2, String additional) {
116             this.key1 = Preconditions.checkNotNull(key1);
117             this.value1 = Preconditions.checkNotNull(value1);
118
119             this.value2 = Preconditions.checkNotNull(value2);
120
121             this.additional = Preconditions.checkNotNull(additional);
122         }
123
124         String getModuleName() {
125             return key1.equals(XmlNetconfConstants.TYPE_KEY) ? value1 : value2;
126         }
127
128         String getInstanceName() {
129             return key1.equals(XmlNetconfConstants.NAME_KEY) ? value1 : value2;
130         }
131
132         Map<String, String> getAdditionalKeys(String elementName, String moduleName) {
133             HashMap<String, String> additionalAttributes = Maps.newHashMap();
134
135             runtimeBeanYangName = moduleName;
136             for (String additionalKeyValue : additional.split("/")) {
137                 if (Strings.isNullOrEmpty(additionalKeyValue)){
138                     continue;
139                 }
140                 Matcher matcher = additionalPattern.matcher(additionalKeyValue);
141                 Preconditions
142                         .checkState(
143                                 matcher.matches(),
144                                 "Attribute %s not in required form on rpc element %s, required format for additional attributes is  %s",
145                                 additionalKeyValue, elementName, additionalPatternBlueprint);
146                 String name = matcher.group("additionalKey");
147                 runtimeBeanYangName = name;
148                 additionalAttributes.put(name, matcher.group("additionalValue"));
149             }
150             return additionalAttributes;
151         }
152
153         private String getRuntimeBeanYangName() {
154             Preconditions.checkState(runtimeBeanYangName!=null);
155             return runtimeBeanYangName;
156         }
157     }
158 }