2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc;
11 import java.util.HashMap;
13 import java.util.regex.Matcher;
14 import java.util.regex.Pattern;
16 import javax.management.ObjectName;
18 import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
19 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
20 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.ModuleRpcs;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.Modules;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.rev130405.modules.Module;
24 import com.google.common.annotations.VisibleForTesting;
25 import com.google.common.base.Preconditions;
26 import com.google.common.base.Strings;
27 import com.google.common.collect.Maps;
30 * Represents parsed xpath to runtime bean instance
32 public final class RuntimeRpcElementResolved {
33 private final String moduleName;
34 private final String instanceName;
35 private final String namespace;
36 private final String runtimeBeanName;
37 private final Map<String, String> additionalAttributes;
39 private RuntimeRpcElementResolved(String namespace, String moduleName, String instanceName, String runtimeBeanName,
40 Map<String, String> additionalAttributes) {
41 this.moduleName = Preconditions.checkNotNull(moduleName, "Module name");
42 this.instanceName = Preconditions.checkNotNull(instanceName, "Instance name");
43 this.additionalAttributes = additionalAttributes;
44 this.namespace = Preconditions.checkNotNull(namespace, "Namespace");
45 this.runtimeBeanName = Preconditions.checkNotNull(runtimeBeanName, "Runtime bean name");
48 public String getModuleName() {
53 Map<String, String> getAdditionalAttributes() {
54 return additionalAttributes;
57 public String getInstanceName() {
61 public String getNamespace() {
65 public String getRuntimeBeanName() {
66 return runtimeBeanName;
69 public ObjectName getObjectName(ModuleRpcs rpcMapping) {
70 Map<String, String> additionalAttributesJavaNames = Maps
71 .newHashMapWithExpectedSize(additionalAttributes.size());
72 for (String attributeYangName : additionalAttributes.keySet()) {
73 String attributeJavaName = rpcMapping.getRbeJavaName(attributeYangName);
74 Preconditions.checkState(attributeJavaName != null,
75 "Cannot find java name for runtime bean wtih yang name %s", attributeYangName);
76 additionalAttributesJavaNames.put(attributeJavaName, additionalAttributes.get(attributeYangName));
78 return ObjectNameUtil.createRuntimeBeanName(moduleName, instanceName, additionalAttributesJavaNames);
82 * Pattern for an absolute instance identifier xpath pointing to a runtime bean instance e.g:
84 * /modules/module[name=instanceName][type=moduleType]
88 * /a:modules/a:module[a:name=instanceName][a:type=moduleType]
91 private static final String xpathPatternBlueprint =
92 "/" + getRegExForPrefixedName(Modules.QNAME.getLocalName())+ "/" + getRegExForPrefixedName(Module.QNAME.getLocalName())
95 + "(?<key1>" + getRegExForPrefixedName(XmlNetconfConstants.TYPE_KEY) + "|" + getRegExForPrefixedName(XmlNetconfConstants.NAME_KEY) + ")"
96 + "=('|\")?(?<value1>[^'\"\\]]+)('|\")?"
98 + "(?<key2>" + getRegExForPrefixedName(XmlNetconfConstants.TYPE_KEY) + "|" + getRegExForPrefixedName(XmlNetconfConstants.NAME_KEY) + ")"
99 + "=('|\")?(?<value2>[^'\"\\]]+)('|\")?"
102 + "(?<additional>.*)";
105 * Return reg ex that matches either the name with or without a prefix
107 private static String getRegExForPrefixedName(final String name) {
108 return "([^:]+:)?" + name;
111 private static final Pattern xpathPattern = Pattern.compile(xpathPatternBlueprint);
114 * Pattern for additional path elements inside xpath for instance identifier pointing to an inner runtime bean e.g:
116 * /modules/module[name=instanceName and type=moduleType]/inner[key=b]
119 private static final String additionalPatternBlueprint = getRegExForPrefixedName("(?<additionalKey>.+)") + "\\[(?<prefixedKey>" + getRegExForPrefixedName("(.+)") + ")=('|\")?(?<additionalValue>[^'\"\\]]+)('|\")?\\]";
120 private static final Pattern additionalPattern = Pattern.compile(additionalPatternBlueprint);
122 public static RuntimeRpcElementResolved fromXpath(String xpath, String elementName, String namespace) {
123 Matcher matcher = xpathPattern.matcher(xpath);
124 Preconditions.checkState(matcher.matches(),
125 "Node %s with value '%s' not in required form on rpc element %s, required format is %s",
126 RuntimeRpc.CONTEXT_INSTANCE, xpath, elementName, xpathPatternBlueprint);
128 PatternGroupResolver groups = new PatternGroupResolver(matcher.group("key1"), matcher.group("value1"),
129 matcher.group("value2"), matcher.group("additional"));
131 String moduleName = groups.getModuleName();
132 String instanceName = groups.getInstanceName();
134 Map<String, String> additionalAttributes = groups.getAdditionalKeys(elementName, moduleName);
136 return new RuntimeRpcElementResolved(namespace, moduleName, instanceName, groups.getRuntimeBeanYangName(),
137 additionalAttributes);
140 private static final class PatternGroupResolver {
142 private final String key1, value1, value2;
143 private final String additional;
144 private String runtimeBeanYangName;
146 PatternGroupResolver(String key1, String value1, String value2, String additional) {
147 this.key1 = Preconditions.checkNotNull(key1);
148 this.value1 = Preconditions.checkNotNull(value1);
149 this.value2 = Preconditions.checkNotNull(value2);
150 this.additional = Preconditions.checkNotNull(additional);
153 String getModuleName() {
154 return key1.contains(XmlNetconfConstants.TYPE_KEY) ? value1 : value2;
157 String getInstanceName() {
158 return key1.contains(XmlNetconfConstants.NAME_KEY) ? value1 : value2;
162 Map<String, String> getAdditionalKeys(String elementName, String moduleName) {
163 HashMap<String, String> additionalAttributes = Maps.newHashMap();
165 runtimeBeanYangName = moduleName;
166 for (String additionalKeyValue : additional.split("/")) {
167 if (Strings.isNullOrEmpty(additionalKeyValue)){
170 Matcher matcher = additionalPattern.matcher(additionalKeyValue);
174 "Attribute %s not in required form on rpc element %s, required format for additional attributes is: %s",
175 additionalKeyValue, elementName, additionalPatternBlueprint);
176 String name = matcher.group("additionalKey");
177 runtimeBeanYangName = name;
178 additionalAttributes.put(name, matcher.group("additionalValue"));
180 return additionalAttributes;
183 private String getRuntimeBeanYangName() {
184 Preconditions.checkState(runtimeBeanYangName!=null);
185 return runtimeBeanYangName;