/* * * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * */ package org.opendaylight.controller.cluster.datastore.util; import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory; import org.opendaylight.controller.cluster.datastore.node.utils.QNameFactory; import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * This class contains utility methods for converting an MD-SAL * YangInstanceIdentifier to and from other representations. *

* The representations convered for now are, * *

*/ public class InstanceIdentifierUtils { protected static final Logger logger = LoggerFactory .getLogger(InstanceIdentifierUtils.class); @Deprecated public static YangInstanceIdentifier from(String path) { String[] ids = path.split("/"); List pathArguments = new ArrayList<>(); for (String nodeId : ids) { if (!"".equals(nodeId)) { pathArguments .add(NodeIdentifierFactory.getArgument(nodeId)); } } final YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier.create(pathArguments); return instanceIdentifier; } /** * Convert an MD-SAL YangInstanceIdentifier into a protocol buffer version of it * * @param path an MD-SAL YangInstanceIdentifier * @return a protocol buffer version of the MD-SAL YangInstanceIdentifier */ public static NormalizedNodeMessages.InstanceIdentifier toSerializable(YangInstanceIdentifier path){ NormalizedNodeMessages.InstanceIdentifier.Builder builder = NormalizedNodeMessages.InstanceIdentifier.newBuilder(); try { for (org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument pathArgument : path .getPathArguments()) { String nodeType = ""; if(!(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier)){ nodeType = pathArgument.getNodeType().toString(); } NormalizedNodeMessages.PathArgument serializablePathArgument = NormalizedNodeMessages.PathArgument.newBuilder() .setValue(pathArgument.toString()) .setType(pathArgument.getClass().getSimpleName()) .setNodeType(NormalizedNodeMessages.QName.newBuilder() .setValue(nodeType)) .addAllAttributes(getPathArgumentAttributes( pathArgument)) .build(); builder.addArguments(serializablePathArgument); } } catch(Exception e){ logger.error("An exception occurred", e); } return builder.build(); } /** * Convert a protocol buffer version of the MD-SAL YangInstanceIdentifier into * the MD-SAL version of the YangInstanceIdentifier * * @param path a protocol buffer version of the MD-SAL YangInstanceIdentifier * @return an MD-SAL YangInstanceIdentifier */ public static YangInstanceIdentifier fromSerializable(NormalizedNodeMessages.InstanceIdentifier path){ List pathArguments = new ArrayList<>(); for(NormalizedNodeMessages.PathArgument pathArgument : path.getArgumentsList()){ pathArguments .add(parsePathArgument(pathArgument)); } final YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier.create(pathArguments); return instanceIdentifier; } /** * Take the various attributes of a PathArgument and package them up as * protocol buffer attributes. *

* * PathArguments have 4 subtypes and each of the various subtypes have * different attributes *

* @param pathArgument * @return */ private static Iterable getPathArgumentAttributes( YangInstanceIdentifier.PathArgument pathArgument) { List attributes = new ArrayList<>(); if (pathArgument instanceof YangInstanceIdentifier.NodeWithValue) { YangInstanceIdentifier.NodeWithValue identifier = (YangInstanceIdentifier.NodeWithValue) pathArgument; NormalizedNodeMessages.Attribute attribute = NormalizedNodeMessages.Attribute.newBuilder() .setName("name") .setValue(identifier.getValue().toString()) .setType(identifier.getValue().getClass().getSimpleName()) .build(); attributes.add(attribute); } else if (pathArgument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) { YangInstanceIdentifier.NodeIdentifierWithPredicates identifier = (YangInstanceIdentifier.NodeIdentifierWithPredicates) pathArgument; for (QName key : identifier.getKeyValues().keySet()) { Object value = identifier.getKeyValues().get(key); NormalizedNodeMessages.Attribute attribute = NormalizedNodeMessages.Attribute.newBuilder() .setName(key.toString()) .setValue(value.toString()) .setType(value.getClass().getSimpleName()) .build(); attributes.add(attribute); } } else if(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier) { YangInstanceIdentifier.AugmentationIdentifier identifier = (YangInstanceIdentifier.AugmentationIdentifier) pathArgument; for (QName key : identifier.getPossibleChildNames()) { Object value = key; NormalizedNodeMessages.Attribute attribute = NormalizedNodeMessages.Attribute.newBuilder() .setName(key.toString()) .setValue(value.toString()) .setType(value.getClass().getSimpleName()) .build(); attributes.add(attribute); } } return attributes; } /** * Parse a protocol buffer PathArgument and return an MD-SAL PathArgument * * @param pathArgument protocol buffer PathArgument * @return MD-SAL PathArgument */ private static YangInstanceIdentifier.PathArgument parsePathArgument(NormalizedNodeMessages.PathArgument pathArgument) { if (YangInstanceIdentifier.NodeWithValue.class.getSimpleName().equals(pathArgument.getType())) { YangInstanceIdentifier.NodeWithValue nodeWithValue = new YangInstanceIdentifier.NodeWithValue( QNameFactory.create(pathArgument.getNodeType().getValue()), parseAttribute(pathArgument.getAttributes(0))); return nodeWithValue; } else if(YangInstanceIdentifier.NodeIdentifierWithPredicates.class.getSimpleName().equals(pathArgument.getType())){ YangInstanceIdentifier.NodeIdentifierWithPredicates nodeIdentifierWithPredicates = new YangInstanceIdentifier.NodeIdentifierWithPredicates( QNameFactory.create(pathArgument.getNodeType().getValue()), toAttributesMap(pathArgument.getAttributesList())); return nodeIdentifierWithPredicates; } else if(YangInstanceIdentifier.AugmentationIdentifier.class.getSimpleName().equals(pathArgument.getType())){ Set qNameSet = new HashSet<>(); for(NormalizedNodeMessages.Attribute attribute : pathArgument.getAttributesList()){ qNameSet.add(QNameFactory.create(attribute.getValue())); } return new YangInstanceIdentifier.AugmentationIdentifier(qNameSet); } return NodeIdentifierFactory.getArgument(pathArgument.getValue()); } private static Map toAttributesMap( List attributesList) { Map map = new HashMap<>(); for(NormalizedNodeMessages.Attribute attribute : attributesList){ String name = attribute.getName(); Object value = parseAttribute(attribute); map.put(QNameFactory.create(name), value); } return map; } /** * FIXME: This method only covers a subset of values that may go in an InstanceIdentifier * * @param attribute * @return */ private static Object parseAttribute(NormalizedNodeMessages.Attribute attribute){ if(Short.class.getSimpleName().equals(attribute.getType())) { return Short.parseShort(attribute.getValue()); } else if(Long.class.getSimpleName().equals(attribute.getType())){ return Long.parseLong(attribute.getValue()); } else if(Boolean.class.getSimpleName().equals(attribute.getType())){ return Boolean.parseBoolean(attribute.getValue()); } else if(Integer.class.getSimpleName().equals(attribute.getType())){ return Integer.parseInt(attribute.getValue()); } return attribute.getValue(); } }