Merge "Bug 5916: He plugin: Wake up statistics collector thread if RPC fails."
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / util / InventoryDataServiceUtil.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 package org.opendaylight.openflowplugin.openflow.md.util;
9
10 import com.google.common.base.Optional;
11 import java.math.BigInteger;
12 import java.util.List;
13 import java.util.concurrent.ExecutionException;
14
15 import com.google.common.base.Splitter;
16 import org.apache.commons.lang3.StringUtils;
17 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
21 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdatedBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeUpdatedBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
34 import org.opendaylight.yangtools.yang.binding.DataObject;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 public abstract class InventoryDataServiceUtil {
41     public static final  String OF_URI_PREFIX = "openflow:";
42     private static final Splitter COLON_SPLITTER = Splitter.on(":");
43     private static final Logger LOG = LoggerFactory.getLogger(InventoryDataServiceUtil.class);
44
45     /*
46      * Get an InstanceIdentifier for the Nodes class that is the root of the
47      * inventory tree We use this alot, so its worth keeping around
48      */
49     private static final InstanceIdentifier<Nodes> NODES_IDENTIFIER = InstanceIdentifier.create(Nodes.class);
50
51     public static Nodes checkForNodes() {
52         Nodes nodes = null;
53         LOG.error("Before Nodes - nodes: " + nodes);
54         try {
55             nodes = getDataObject(OFSessionUtil.getSessionManager().getDataBroker().newReadOnlyTransaction(), NODES_IDENTIFIER);
56         } catch (Exception e) {
57             LOG.error(
58                     "Caught exception from OFSessionUtil.getSessionManager().getDataBroker().newReadWriteTransaction()",
59                     e);
60         }
61         LOG.error("After Nodes- nodes: " + nodes);
62         return nodes;
63     }
64
65     public static List<Node> readAllNodes() {
66         Nodes nodes = getDataObject(OFSessionUtil.getSessionManager().getDataBroker().newReadOnlyTransaction(), NODES_IDENTIFIER);
67         return nodes.getNode();
68     }
69
70     public static Node readNode(final InstanceIdentifier<Node> instance) {
71         return getDataObject(OFSessionUtil.getSessionManager().getDataBroker().newReadOnlyTransaction(), instance);
72     }
73
74     public static void putNodeConnector(final InstanceIdentifier<Node> instance, final NodeConnector nodeConnector) {
75         WriteTransaction transaction = OFSessionUtil.getSessionManager().getDataBroker().newWriteOnlyTransaction();
76         InstanceIdentifier<NodeConnector> nodeConnectorID = instance.child(NodeConnector.class, nodeConnector.getKey());
77         transaction.merge(LogicalDatastoreType.OPERATIONAL, nodeConnectorID, nodeConnector);
78         transaction.submit();
79     }
80
81     public static void putNodeConnector(final NodeKey nodeKey, final NodeConnector nodeConnector) {
82         InstanceIdentifier<Node> instance = nodeKeyToInstanceIdentifier(nodeKey);
83         putNodeConnector(instance, nodeConnector);
84     }
85
86     public static void putNodeConnector(final NodeId nodeId, final NodeConnector nodeConnector) {
87         putNodeConnector(new NodeKey(nodeId), nodeConnector);
88     }
89
90     public static InstanceIdentifier<Node> identifierFromDatapathId(final BigInteger datapathId) {
91         NodeKey nodeKey = nodeKeyFromDatapathId(datapathId);
92         return NODES_IDENTIFIER.child(Node.class, nodeKey);
93     }
94
95     public static NodeKey nodeKeyFromDatapathId(final BigInteger datapathId) {
96         return new NodeKey(nodeIdFromDatapathId(datapathId));
97     }
98
99     public static NodeUpdatedBuilder nodeUpdatedBuilderFromDataPathId(final BigInteger datapathId) {
100         NodeUpdatedBuilder builder = new NodeUpdatedBuilder();
101         builder.setId(nodeIdFromDatapathId(datapathId));
102         builder.setNodeRef(nodeRefFromNodeKey(new NodeKey(builder.getId())));
103         return builder;
104     }
105
106     public static NodeId nodeIdFromDatapathId(final BigInteger datapathId) {
107         // FIXME: Convert to textual representation of datapathID
108         String current = datapathId.toString();
109         return new NodeId(OF_URI_PREFIX + current);
110     }
111
112     public static BigInteger dataPathIdFromNodeId(final NodeId nodeId) {
113         String dpids = nodeId.getValue().replace(OF_URI_PREFIX, "");
114         BigInteger dpid = new BigInteger(dpids);
115         return dpid;
116     }
117
118
119     public static NodeRef nodeRefFromNodeKey(final NodeKey nodeKey) {
120         return new NodeRef(nodeKeyToInstanceIdentifier(nodeKey));
121     }
122
123     public static InstanceIdentifier<Node> nodeKeyToInstanceIdentifier(final NodeKey nodeKey) {
124         return NODES_IDENTIFIER.child(Node.class, nodeKey);
125     }
126
127     public static NodeConnectorId nodeConnectorIdfromDatapathPortNo(final BigInteger datapathid, final Long portNo,
128                                                                     final OpenflowVersion ofVersion) {
129         String logicalName = OpenflowPortsUtil.getPortLogicalName(ofVersion, portNo);
130         return new NodeConnectorId(OF_URI_PREFIX + datapathid + ":" + (logicalName == null ? portNo : logicalName));
131     }
132
133     public static Long portNumberfromNodeConnectorId(final OpenflowVersion ofVersion, final NodeConnectorId ncId) {
134         return portNumberfromNodeConnectorId(ofVersion, ncId.getValue());
135     }
136
137     public static String portNoStringfromNodeConnectorID(final String ncID) {
138
139         List<String> splitStringList = COLON_SPLITTER.splitToList(ncID);
140
141         // It can happen that token length will be just 1 i.e 2 or CONTROLLER
142         // If the length is just one then this cannot be the new MD-SAL style node connector Id which
143         // is of the form openflow:1:3.
144
145         return splitStringList.get(splitStringList.size()-1);
146     }
147
148     public static Long portNumberfromNodeConnectorId(final OpenflowVersion ofVersion, final String ncId) {
149         String portNoString = portNoStringfromNodeConnectorID(ncId);
150         Long portNo = OpenflowPortsUtil.getPortFromLogicalName(ofVersion, portNoString);
151         return portNo;
152     }
153
154
155     public static NodeConnectorRef nodeConnectorRefFromDatapathIdPortno(final BigInteger datapathId, final Long portNo, final OpenflowVersion ofVersion) {
156         return new NodeConnectorRef(nodeConnectorInstanceIdentifierFromDatapathIdPortno(datapathId, portNo, ofVersion));
157     }
158
159     public static NodeConnectorRef nodeConnectorRefFromDatapathIdPortno(final BigInteger datapathId, final Long portNo,
160                                                                         final OpenflowVersion ofVersion,
161                                                                         final KeyedInstanceIdentifier<Node, NodeKey> nodePath) {
162         return new NodeConnectorRef(nodeConnectorInstanceIdentifierFromDatapathIdPortno(datapathId, portNo, ofVersion, nodePath));
163     }
164
165     public static InstanceIdentifier<NodeConnector> nodeConnectorInstanceIdentifierFromDatapathIdPortno(
166             final BigInteger datapathId, final Long portNo, final OpenflowVersion ofVersion) {
167         NodeId nodeId = nodeIdFromDatapathId(datapathId);
168         KeyedInstanceIdentifier<Node, NodeKey> nodePath = NODES_IDENTIFIER.child(Node.class, new NodeKey(nodeId));
169         return nodeConnectorInstanceIdentifierFromDatapathIdPortno(datapathId, portNo, ofVersion, nodePath);
170     }
171
172     public static InstanceIdentifier<NodeConnector> nodeConnectorInstanceIdentifierFromDatapathIdPortno(
173             final BigInteger datapathId, final Long portNo, final OpenflowVersion ofVersion, final KeyedInstanceIdentifier<Node, NodeKey> nodePath) {
174         NodeConnectorId nodeConnectorId = nodeConnectorIdfromDatapathPortNo(datapathId, portNo, ofVersion);
175         return nodePath.child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId));
176     }
177
178     public static NodeConnectorUpdatedBuilder nodeConnectorUpdatedBuilderFromDatapathIdPortNo(final BigInteger datapathId,
179                                                                                               final Long portNo, final OpenflowVersion ofVersion) {
180         NodeConnectorUpdatedBuilder builder = new NodeConnectorUpdatedBuilder();
181         builder.setId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId, portNo, ofVersion));
182         builder.setNodeConnectorRef(InventoryDataServiceUtil.nodeConnectorRefFromDatapathIdPortno(datapathId, portNo, ofVersion));
183         return builder;
184     }
185
186     public static NodeConnectorBuilder nodeConnectorBuilderFromDatapathIdPortNo(final BigInteger datapathId,
187                                                                                 final Long portNo, final OpenflowVersion ofVersion) {
188         NodeConnectorBuilder builder = new NodeConnectorBuilder();
189         builder.setId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId, portNo, ofVersion));
190         return builder;
191     }
192
193     /**
194      * @param dataPathId datapath id in big interger value
195      * @return string of size 16, padded with '0'
196      */
197     public static String bigIntegerToPaddedHex(final BigInteger dataPathId) {
198         return StringUtils.leftPad(dataPathId.toString(16), 16, "0");
199     }
200
201     //TODO : create new module openflowplugin-util, move there this method along with TestProviderTransactionUtil#getDataObject
202     private static <T extends DataObject> T getDataObject(final ReadTransaction readOnlyTransaction, final InstanceIdentifier<T> identifier) {
203         Optional<T> optionalData = null;
204         try {
205             optionalData = readOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, identifier).get();
206             if (optionalData.isPresent()) {
207                 return optionalData.get();
208             }
209         } catch (ExecutionException | InterruptedException e) {
210             LOG.error("Read transaction for identifier {} failed.", identifier, e);
211         }
212         return null;
213     }
214
215 }