1 package org.opendaylight.controller.cluster.datastore.util;
3 import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
4 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
5 import org.opendaylight.yangtools.yang.common.QName;
6 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
10 import java.util.ArrayList;
11 import java.util.HashMap;
12 import java.util.HashSet;
13 import java.util.List;
18 * This class contains utility methods for converting an MD-SAL
19 * YangInstanceIdentifier to and from other representations.
21 * The representations convered for now are,
25 * <li>Protocol Buffer</li>
28 public class InstanceIdentifierUtils {
30 protected static final Logger logger = LoggerFactory
31 .getLogger(InstanceIdentifierUtils.class);
34 public static YangInstanceIdentifier from(String path) {
35 String[] ids = path.split("/");
37 List<YangInstanceIdentifier.PathArgument> pathArguments =
39 for (String nodeId : ids) {
40 if (!"".equals(nodeId)) {
42 .add(NodeIdentifierFactory.getArgument(nodeId));
45 final YangInstanceIdentifier instanceIdentifier =
46 YangInstanceIdentifier.create(pathArguments);
47 return instanceIdentifier;
52 * Convert an MD-SAL YangInstanceIdentifier into a protocol buffer version of it
54 * @param path an MD-SAL YangInstanceIdentifier
55 * @return a protocol buffer version of the MD-SAL YangInstanceIdentifier
57 public static NormalizedNodeMessages.InstanceIdentifier toSerializable(YangInstanceIdentifier path){
58 NormalizedNodeMessages.InstanceIdentifier.Builder builder =
59 NormalizedNodeMessages.InstanceIdentifier.newBuilder();
63 for (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument pathArgument : path
64 .getPathArguments()) {
67 if(!(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier)){
68 nodeType = pathArgument.getNodeType().toString();
71 NormalizedNodeMessages.PathArgument serializablePathArgument =
72 NormalizedNodeMessages.PathArgument.newBuilder()
73 .setValue(pathArgument.toString())
74 .setType(pathArgument.getClass().getSimpleName())
75 .setNodeType(NormalizedNodeMessages.QName.newBuilder()
77 .addAllAttributes(getPathArgumentAttributes(
81 builder.addArguments(serializablePathArgument);
85 logger.error("An exception occurred", e);
87 return builder.build();
92 * Convert a protocol buffer version of the MD-SAL YangInstanceIdentifier into
93 * the MD-SAL version of the YangInstanceIdentifier
95 * @param path a protocol buffer version of the MD-SAL YangInstanceIdentifier
96 * @return an MD-SAL YangInstanceIdentifier
98 public static YangInstanceIdentifier fromSerializable(NormalizedNodeMessages.InstanceIdentifier path){
100 List<YangInstanceIdentifier.PathArgument> pathArguments =
103 for(NormalizedNodeMessages.PathArgument pathArgument : path.getArgumentsList()){
106 .add(parsePathArgument(pathArgument));
110 final YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier.create(pathArguments);
112 return instanceIdentifier;
116 * Take the various attributes of a PathArgument and package them up as
117 * protocol buffer attributes.
120 * PathArguments have 4 subtypes and each of the various subtypes have
121 * different attributes
124 * NodeIdentifier is the most basic PathArgument. It is used for
125 * ContainerNode, LeafNode etc and has no attributes
128 * NodeWithValue has only a single attribute. It is used for
129 * LeafListEntryNodes and the attribute it contains is the value
133 * NodeIdentifierWithPredicates has a map of attributes.
134 * It is used to represent a ListItemNode. Each entry
135 * in the map of attributes represents the key and value of the
136 * keys in that entry.
139 * AugmentationIdentifier has a list of unnamed attributes. Each
140 * attribute represents the possible children that can go within
141 * an augmentation entry.
144 * @param pathArgument
147 private static Iterable<? extends NormalizedNodeMessages.Attribute> getPathArgumentAttributes(
148 YangInstanceIdentifier.PathArgument pathArgument) {
149 List<NormalizedNodeMessages.Attribute> attributes = new ArrayList<>();
153 if (pathArgument instanceof YangInstanceIdentifier.NodeWithValue) {
154 YangInstanceIdentifier.NodeWithValue identifier
155 = (YangInstanceIdentifier.NodeWithValue) pathArgument;
157 NormalizedNodeMessages.Attribute attribute =
158 NormalizedNodeMessages.Attribute.newBuilder()
160 .setValue(identifier.getValue().toString())
161 .setType(identifier.getValue().getClass().getSimpleName())
164 attributes.add(attribute);
165 } else if (pathArgument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
166 YangInstanceIdentifier.NodeIdentifierWithPredicates identifier
167 = (YangInstanceIdentifier.NodeIdentifierWithPredicates) pathArgument;
169 for (QName key : identifier.getKeyValues().keySet()) {
170 Object value = identifier.getKeyValues().get(key);
171 NormalizedNodeMessages.Attribute attribute =
172 NormalizedNodeMessages.Attribute.newBuilder()
173 .setName(key.toString())
174 .setValue(value.toString())
175 .setType(value.getClass().getSimpleName())
178 attributes.add(attribute);
182 } else if(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier) {
183 YangInstanceIdentifier.AugmentationIdentifier identifier
184 = (YangInstanceIdentifier.AugmentationIdentifier) pathArgument;
186 for (QName key : identifier.getPossibleChildNames()) {
188 NormalizedNodeMessages.Attribute attribute =
189 NormalizedNodeMessages.Attribute.newBuilder()
190 .setName(key.toString())
191 .setValue(value.toString())
192 .setType(value.getClass().getSimpleName())
195 attributes.add(attribute);
205 * Parse a protocol buffer PathArgument and return an MD-SAL PathArgument
207 * @param pathArgument protocol buffer PathArgument
208 * @return MD-SAL PathArgument
210 private static YangInstanceIdentifier.PathArgument parsePathArgument(NormalizedNodeMessages.PathArgument pathArgument) {
211 if (YangInstanceIdentifier.NodeWithValue.class.getSimpleName().equals(pathArgument.getType())) {
213 YangInstanceIdentifier.NodeWithValue nodeWithValue =
214 new YangInstanceIdentifier.NodeWithValue(
215 QName.create(pathArgument.getNodeType().getValue()),
216 parseAttribute(pathArgument.getAttributes(0)));
218 return nodeWithValue;
220 } else if(YangInstanceIdentifier.NodeIdentifierWithPredicates.class.getSimpleName().equals(pathArgument.getType())){
222 YangInstanceIdentifier.NodeIdentifierWithPredicates
223 nodeIdentifierWithPredicates =
224 new YangInstanceIdentifier.NodeIdentifierWithPredicates(
225 QName.create(pathArgument.getNodeType().getValue()), toAttributesMap(pathArgument.getAttributesList()));
227 return nodeIdentifierWithPredicates;
229 } else if(YangInstanceIdentifier.AugmentationIdentifier.class.getSimpleName().equals(pathArgument.getType())){
231 Set<QName> qNameSet = new HashSet<>();
233 for(NormalizedNodeMessages.Attribute attribute : pathArgument.getAttributesList()){
234 qNameSet.add(QName.create(attribute.getValue()));
237 return new YangInstanceIdentifier.AugmentationIdentifier(qNameSet);
240 return NodeIdentifierFactory.getArgument(pathArgument.getValue());
243 private static Map<QName, Object> toAttributesMap(
244 List<NormalizedNodeMessages.Attribute> attributesList) {
246 Map<QName, Object> map = new HashMap<>();
248 for(NormalizedNodeMessages.Attribute attribute : attributesList){
249 String name = attribute.getName();
250 Object value = parseAttribute(attribute);
252 map.put(QName.create(name), value);
259 * FIXME: This method only covers a subset of values that may go in an InstanceIdentifier
264 private static Object parseAttribute(NormalizedNodeMessages.Attribute attribute){
265 if(Short.class.getSimpleName().equals(attribute.getType())) {
266 return Short.parseShort(attribute.getValue());
267 } else if(Long.class.getSimpleName().equals(attribute.getType())){
268 return Long.parseLong(attribute.getValue());
269 } else if(Boolean.class.getSimpleName().equals(attribute.getType())){
270 return Boolean.parseBoolean(attribute.getValue());
271 } else if(Integer.class.getSimpleName().equals(attribute.getType())){
272 return Integer.parseInt(attribute.getValue());
275 return attribute.getValue();