3 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
11 package org.opendaylight.controller.cluster.datastore.util;
13 import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
14 import org.opendaylight.controller.cluster.datastore.node.utils.QNameFactory;
15 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.List;
29 * This class contains utility methods for converting an MD-SAL
30 * YangInstanceIdentifier to and from other representations.
32 * The representations convered for now are,
36 * <li>Protocol Buffer</li>
39 public class InstanceIdentifierUtils {
41 protected static final Logger logger = LoggerFactory
42 .getLogger(InstanceIdentifierUtils.class);
45 public static YangInstanceIdentifier from(String path) {
46 String[] ids = path.split("/");
48 List<YangInstanceIdentifier.PathArgument> pathArguments =
50 for (String nodeId : ids) {
51 if (!"".equals(nodeId)) {
53 .add(NodeIdentifierFactory.getArgument(nodeId));
56 final YangInstanceIdentifier instanceIdentifier =
57 YangInstanceIdentifier.create(pathArguments);
58 return instanceIdentifier;
63 * Convert an MD-SAL YangInstanceIdentifier into a protocol buffer version of it
65 * @param path an MD-SAL YangInstanceIdentifier
66 * @return a protocol buffer version of the MD-SAL YangInstanceIdentifier
68 public static NormalizedNodeMessages.InstanceIdentifier toSerializable(YangInstanceIdentifier path){
69 NormalizedNodeMessages.InstanceIdentifier.Builder builder =
70 NormalizedNodeMessages.InstanceIdentifier.newBuilder();
74 for (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument pathArgument : path
75 .getPathArguments()) {
78 if(!(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier)){
79 nodeType = pathArgument.getNodeType().toString();
82 NormalizedNodeMessages.PathArgument serializablePathArgument =
83 NormalizedNodeMessages.PathArgument.newBuilder()
84 .setValue(pathArgument.toString())
85 .setType(pathArgument.getClass().getSimpleName())
86 .setNodeType(NormalizedNodeMessages.QName.newBuilder()
88 .addAllAttributes(getPathArgumentAttributes(
92 builder.addArguments(serializablePathArgument);
96 logger.error("An exception occurred", e);
98 return builder.build();
103 * Convert a protocol buffer version of the MD-SAL YangInstanceIdentifier into
104 * the MD-SAL version of the YangInstanceIdentifier
106 * @param path a protocol buffer version of the MD-SAL YangInstanceIdentifier
107 * @return an MD-SAL YangInstanceIdentifier
109 public static YangInstanceIdentifier fromSerializable(NormalizedNodeMessages.InstanceIdentifier path){
111 List<YangInstanceIdentifier.PathArgument> pathArguments =
114 for(NormalizedNodeMessages.PathArgument pathArgument : path.getArgumentsList()){
117 .add(parsePathArgument(pathArgument));
121 final YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier.create(pathArguments);
123 return instanceIdentifier;
127 * Take the various attributes of a PathArgument and package them up as
128 * protocol buffer attributes.
131 * PathArguments have 4 subtypes and each of the various subtypes have
132 * different attributes
135 * NodeIdentifier is the most basic PathArgument. It is used for
136 * ContainerNode, LeafNode etc and has no attributes
139 * NodeWithValue has only a single attribute. It is used for
140 * LeafListEntryNodes and the attribute it contains is the value
144 * NodeIdentifierWithPredicates has a map of attributes.
145 * It is used to represent a ListItemNode. Each entry
146 * in the map of attributes represents the key and value of the
147 * keys in that entry.
150 * AugmentationIdentifier has a list of unnamed attributes. Each
151 * attribute represents the possible children that can go within
152 * an augmentation entry.
155 * @param pathArgument
158 private static Iterable<? extends NormalizedNodeMessages.Attribute> getPathArgumentAttributes(
159 YangInstanceIdentifier.PathArgument pathArgument) {
160 List<NormalizedNodeMessages.Attribute> attributes = new ArrayList<>();
164 if (pathArgument instanceof YangInstanceIdentifier.NodeWithValue) {
165 YangInstanceIdentifier.NodeWithValue identifier
166 = (YangInstanceIdentifier.NodeWithValue) pathArgument;
168 NormalizedNodeMessages.Attribute attribute =
169 NormalizedNodeMessages.Attribute.newBuilder()
171 .setValue(identifier.getValue().toString())
172 .setType(identifier.getValue().getClass().getSimpleName())
175 attributes.add(attribute);
176 } else if (pathArgument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
177 YangInstanceIdentifier.NodeIdentifierWithPredicates identifier
178 = (YangInstanceIdentifier.NodeIdentifierWithPredicates) pathArgument;
180 for (QName key : identifier.getKeyValues().keySet()) {
181 Object value = identifier.getKeyValues().get(key);
182 NormalizedNodeMessages.Attribute attribute =
183 NormalizedNodeMessages.Attribute.newBuilder()
184 .setName(key.toString())
185 .setValue(value.toString())
186 .setType(value.getClass().getSimpleName())
189 attributes.add(attribute);
193 } else if(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier) {
194 YangInstanceIdentifier.AugmentationIdentifier identifier
195 = (YangInstanceIdentifier.AugmentationIdentifier) pathArgument;
197 for (QName key : identifier.getPossibleChildNames()) {
199 NormalizedNodeMessages.Attribute attribute =
200 NormalizedNodeMessages.Attribute.newBuilder()
201 .setName(key.toString())
202 .setValue(value.toString())
203 .setType(value.getClass().getSimpleName())
206 attributes.add(attribute);
216 * Parse a protocol buffer PathArgument and return an MD-SAL PathArgument
218 * @param pathArgument protocol buffer PathArgument
219 * @return MD-SAL PathArgument
221 private static YangInstanceIdentifier.PathArgument parsePathArgument(NormalizedNodeMessages.PathArgument pathArgument) {
222 if (YangInstanceIdentifier.NodeWithValue.class.getSimpleName().equals(pathArgument.getType())) {
224 YangInstanceIdentifier.NodeWithValue nodeWithValue =
225 new YangInstanceIdentifier.NodeWithValue(
226 QNameFactory.create(pathArgument.getNodeType().getValue()),
227 parseAttribute(pathArgument.getAttributes(0)));
229 return nodeWithValue;
231 } else if(YangInstanceIdentifier.NodeIdentifierWithPredicates.class.getSimpleName().equals(pathArgument.getType())){
233 YangInstanceIdentifier.NodeIdentifierWithPredicates
234 nodeIdentifierWithPredicates =
235 new YangInstanceIdentifier.NodeIdentifierWithPredicates(
236 QNameFactory.create(pathArgument.getNodeType().getValue()), toAttributesMap(pathArgument.getAttributesList()));
238 return nodeIdentifierWithPredicates;
240 } else if(YangInstanceIdentifier.AugmentationIdentifier.class.getSimpleName().equals(pathArgument.getType())){
242 Set<QName> qNameSet = new HashSet<>();
244 for(NormalizedNodeMessages.Attribute attribute : pathArgument.getAttributesList()){
245 qNameSet.add(QNameFactory.create(attribute.getValue()));
248 return new YangInstanceIdentifier.AugmentationIdentifier(qNameSet);
251 return NodeIdentifierFactory.getArgument(pathArgument.getValue());
254 private static Map<QName, Object> toAttributesMap(
255 List<NormalizedNodeMessages.Attribute> attributesList) {
257 Map<QName, Object> map = new HashMap<>();
259 for(NormalizedNodeMessages.Attribute attribute : attributesList){
260 String name = attribute.getName();
261 Object value = parseAttribute(attribute);
263 map.put(QNameFactory.create(name), value);
270 * FIXME: This method only covers a subset of values that may go in an InstanceIdentifier
275 private static Object parseAttribute(NormalizedNodeMessages.Attribute attribute){
276 if(Short.class.getSimpleName().equals(attribute.getType())) {
277 return Short.parseShort(attribute.getValue());
278 } else if(Long.class.getSimpleName().equals(attribute.getType())){
279 return Long.parseLong(attribute.getValue());
280 } else if(Boolean.class.getSimpleName().equals(attribute.getType())){
281 return Boolean.parseBoolean(attribute.getValue());
282 } else if(Integer.class.getSimpleName().equals(attribute.getType())){
283 return Integer.parseInt(attribute.getValue());
286 return attribute.getValue();