apply checkstyle check during build for neutron-ovsdb
[groupbasedpolicy.git] / neutron-ovsdb / src / main / java / org / opendaylight / groupbasedpolicy / neutron / ovsdb / util / OvsdbHelper.java
1 /*
2  * Copyright (c) 2015 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
9 package org.opendaylight.groupbasedpolicy.neutron.ovsdb.util;
10
11 import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.readFromDs;
12 import static org.opendaylight.groupbasedpolicy.util.DataStoreHelper.submitToDs;
13
14 import com.google.common.base.Optional;
15
16 import java.util.ArrayList;
17 import java.util.List;
18
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
21 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.groupbasedpolicy.neutron.ovsdb.AbstractTunnelType;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlan;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
43 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 public class OvsdbHelper {
48     private static final Logger LOG = LoggerFactory.getLogger(OvsdbHelper.class);
49     private static final String OF_PORT = "6653";
50
51     /**
52      * Look up the {@link OvsdbBridgeAugmentation} from the data store
53      * given a child {@link InstanceIdentifier} of {@link OvsdbTerminationPointAugmentation}.
54      *
55      * @param tpIid The InstanceIdentifier for a child TerminationPoint augmentation
56      * @param dataBroker the {@link DataBroker}
57      * @return the {@link OvsdbBridgeAugmentation}, null if the augmentation isn't present
58      */
59     public static OvsdbBridgeAugmentation getOvsdbBridgeFromTerminationPoint(
60             InstanceIdentifier<OvsdbTerminationPointAugmentation> tpIid, DataBroker dataBroker) {
61         InstanceIdentifier<Node> nodeIid = tpIid.firstIdentifierOf(Node.class);
62         if (nodeIid != null) {
63             InstanceIdentifier<OvsdbBridgeAugmentation>
64                 ovsdbBridgeIid = nodeIid.augmentation(OvsdbBridgeAugmentation.class);
65             if (ovsdbBridgeIid != null) {
66                 ReadTransaction transaction = dataBroker.newReadOnlyTransaction();
67                 Optional<OvsdbBridgeAugmentation> ovsdbBridge =
68                     readFromDs(LogicalDatastoreType.OPERATIONAL, ovsdbBridgeIid, transaction);
69                 if (ovsdbBridge.isPresent()) {
70                     return ovsdbBridge.get();
71                 }
72             }
73         }
74         return null;
75     }
76
77     public static Node getNodeFromBridgeRef(OvsdbBridgeRef bridgeRef, DataBroker dataBroker) {
78         InstanceIdentifier<Node> nodeIid = bridgeRef.getValue().firstIdentifierOf(Node.class);
79         ReadTransaction transaction = dataBroker.newReadOnlyTransaction();
80         Optional<?> node = readFromDs(LogicalDatastoreType.OPERATIONAL, nodeIid, transaction);
81         if (node.isPresent()) {
82             if (node.get() instanceof Node) {
83                 return (Node) node.get();
84             }
85         }
86         return null;
87     }
88
89     public static OvsdbTerminationPointAugmentation getOvsdbTerminationPoint(
90             InstanceIdentifier<OvsdbTerminationPointAugmentation> tpIid, DataBroker dataBroker) {
91         ReadTransaction transaction = dataBroker.newReadOnlyTransaction();
92         Optional<OvsdbTerminationPointAugmentation>
93             ovsdbTp = readFromDs(LogicalDatastoreType.OPERATIONAL, tpIid, transaction);
94         if (ovsdbTp.isPresent()) {
95             return ovsdbTp.get();
96         }
97         return null;
98     }
99
100     public static Node getNode(Node node, List<TerminationPoint> tps,
101             OvsdbBridgeAugmentation ovsdbBridgeAugmentation) {
102         NodeBuilder nodeBuilder = new NodeBuilder();
103         nodeBuilder.setKey(node.getKey());
104
105         nodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
106                 ovsdbBridgeAugmentation);
107
108         nodeBuilder.setTerminationPoint(tps);
109         return nodeBuilder.build();
110     }
111
112     public static OvsdbBridgeAugmentation buildOvsdbBridgeAugmentation(OvsdbBridgeAugmentation bridge,
113             OvsdbNodeAugmentation ovsdbNode) {
114         OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentation = new OvsdbBridgeAugmentationBuilder();
115         IpAddress managerIp = getManagerIp(ovsdbNode);
116         if (managerIp != null) {
117             List<ControllerEntry> controllerEntries = buildControllerEntries(managerIp);
118             ovsdbBridgeAugmentation.setControllerEntry(controllerEntries);
119         }
120         ovsdbBridgeAugmentation.setBridgeName(bridge.getBridgeName());
121         ovsdbBridgeAugmentation.setManagedBy(bridge.getManagedBy());
122         return ovsdbBridgeAugmentation.build();
123     }
124
125     public static List<TerminationPoint> buildTerminationPoints(OvsdbBridgeAugmentation bridge,
126             OvsdbTerminationPointAugmentation ovsdbTp, AbstractTunnelType tunnelType) {
127         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
128         tpBuilder.setTpId(new TpId(new Uri(generateTpName(bridge, tunnelType))));
129         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, ovsdbTp);
130
131         List<TerminationPoint> tps = new ArrayList<TerminationPoint>();
132         tps.add(tpBuilder.build());
133         return tps;
134     }
135
136     public static String generateTpName(OvsdbBridgeAugmentation bridge, AbstractTunnelType tunnelType) {
137         return tunnelType.getTunnelPrefix() + bridge.getBridgeName().getValue();
138     }
139
140     public static OvsdbTerminationPointAugmentation buildOvsdbTerminationPointAugmentation(
141             OvsdbBridgeAugmentation bridge, List<Options> options, AbstractTunnelType tunnelType) {
142         OvsdbTerminationPointAugmentationBuilder ovsdbTpBuilder = new OvsdbTerminationPointAugmentationBuilder();
143         ovsdbTpBuilder.setName(generateTpName(bridge, tunnelType));
144         ovsdbTpBuilder.setOptions(options);
145         ovsdbTpBuilder.setInterfaceType(InterfaceTypeVxlan.class);
146         return ovsdbTpBuilder.build();
147     }
148
149     public static void setOption(List<Options> options, String key, String value) {
150         OptionsBuilder option = new OptionsBuilder();
151         option.setOption(key);
152         option.setValue(value);
153         options.add(option.build());
154     }
155
156     public static IpAddress getManagerIp(OvsdbNodeAugmentation ovsdbNode) {
157         if (ovsdbNode.getConnectionInfo() != null) {
158             return ovsdbNode.getConnectionInfo().getLocalIp();
159         }
160         return null;
161     }
162
163     public static IpAddress getNodeIp(OvsdbNodeAugmentation ovsdbNode) {
164         if (ovsdbNode.getConnectionInfo() != null) {
165             return ovsdbNode.getConnectionInfo().getRemoteIp();
166         }
167         return null;
168     }
169
170     public static List<ControllerEntry> buildControllerEntries(IpAddress ip) {
171         List<ControllerEntry> result = new ArrayList<ControllerEntry>();
172
173         if (ip != null) {
174             ControllerEntryBuilder controllerBuilder = new ControllerEntryBuilder();
175             String localIp = String.valueOf(ip.getValue());
176             String targetString = "tcp:" + localIp + ":" + OF_PORT;
177             controllerBuilder.setTarget(new Uri(targetString));
178             result.add(controllerBuilder.build());
179         }
180
181         return result;
182     }
183
184     /**
185      * Get the manager node for this bridge node.
186      *
187      * @param bridge the bridge node
188      * @param dataBroker the {@link DataBroker}
189      * @return The {@link OvsdbBridgeAugmentation} for the manager node, null
190      *         if not found or if it already is the manager node
191      */
192     public static OvsdbNodeAugmentation getManagerNode(OvsdbBridgeAugmentation bridge, DataBroker dataBroker) {
193         OvsdbNodeRef bareIId = bridge.getManagedBy();
194         if (bareIId != null) {
195             if (bareIId.getValue().getTargetType().equals(Node.class)) {
196                 ReadWriteTransaction transaction = dataBroker.newReadWriteTransaction();
197                 InstanceIdentifier<Node> iid = (InstanceIdentifier<Node>) bareIId.getValue();
198                 Optional<Node> nodeOptional = readFromDs(LogicalDatastoreType.OPERATIONAL, iid, transaction);
199                 if (nodeOptional.isPresent()
200                     && nodeOptional.get().getAugmentation(OvsdbNodeAugmentation.class) != null) {
201                     return nodeOptional.get().getAugmentation(OvsdbNodeAugmentation.class);
202                 } else {
203                     LOG.warn("Could not find ovsdb-node for connection for {}", bridge);
204                 }
205             } else {
206                 LOG.warn("Bridge 'managedBy' non-ovsdb-node.  bridge {} getManagedBy() {}", bridge, bareIId.getValue());
207             }
208         } else {
209             LOG.debug("Bridge 'managedBy' is null.  bridge {}",bridge);
210         }
211         return null;
212     }
213
214     public static Node getTopologyNode(InstanceIdentifier<Node> nodeIid, DataBroker dataBroker) {
215         ReadTransaction transaction = dataBroker.newReadOnlyTransaction();
216         Optional<Node> nodeOptional = readFromDs(LogicalDatastoreType.OPERATIONAL, nodeIid, transaction);
217         if (nodeOptional.isPresent()) {
218             return nodeOptional.get();
219         }
220         return null;
221     }
222
223     /**
224      * Use OVSDB CRUD to create any missing tunnels on a given
225      * Inventory Node.
226      *
227      * @param nodeIid the node instance identifier
228      * @param node the inventory node
229      * @param tunnelType the tunnel type
230      * @param dataBroker the {@link DataBroker}
231      */
232     public static void createTunnelPort(InstanceIdentifier<Node> nodeIid,
233             Node node, AbstractTunnelType tunnelType, DataBroker dataBroker) {
234         OvsdbBridgeAugmentation bridge = node.getAugmentation(OvsdbBridgeAugmentation.class);
235         if (bridge == null) {
236             LOG.warn("No OvsdbBridgeAugmentationfor Node {}", node);
237             return;
238         }
239
240         OvsdbNodeAugmentation managerNode = getManagerNode(bridge, dataBroker);
241         if (managerNode == null) {
242             LOG.warn("Couldn't create tunnel port for Node {}, no manager", node);
243             return;
244         }
245         List<Options> options = tunnelType.getOptions();
246         OvsdbTerminationPointAugmentation ovsdbTp = buildOvsdbTerminationPointAugmentation(bridge, options, tunnelType);
247         List<TerminationPoint> tps = buildTerminationPoints(bridge,ovsdbTp, tunnelType);
248         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = buildOvsdbBridgeAugmentation(bridge,managerNode);
249         Node configNode = getNode(node, tps,ovsdbBridgeAugmentation);
250         LOG.info("About to write nodeId {} node {}",nodeIid,configNode);
251         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
252         rwTx.merge(LogicalDatastoreType.CONFIGURATION, nodeIid, configNode);
253         submitToDs(rwTx);
254     }
255
256
257 }