Merge "Introducing Bridge Operational State"
[ovsdb.git] / southbound / southbound-impl / src / main / java / org / opendaylight / ovsdb / southbound / SouthboundMapper.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 package org.opendaylight.ovsdb.southbound;
9
10 import java.net.Inet4Address;
11 import java.net.Inet6Address;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20
21 import org.opendaylight.ovsdb.lib.OvsdbClient;
22 import org.opendaylight.ovsdb.lib.OvsdbConnectionInfo;
23 import org.opendaylight.ovsdb.lib.notation.UUID;
24 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
25 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
26 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
27 import org.opendaylight.ovsdb.schema.openvswitch.Controller;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeSystem;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57 import com.google.common.base.Joiner;
58 import com.google.common.base.Preconditions;
59 import com.google.common.base.Splitter;
60 import com.google.common.collect.ImmutableBiMap;
61
62 public class SouthboundMapper {
63     private static final Logger LOG = LoggerFactory.getLogger(SouthboundMapper.class);
64
65     public static Node createNode(OvsdbClient client) {
66         NodeBuilder nodeBuilder = new NodeBuilder();
67         nodeBuilder.setNodeId(createNodeId(client.getConnectionInfo()));
68         nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(client));
69         return nodeBuilder.build();
70     }
71     public static Node createNode(OvsdbClientKey key) {
72         NodeBuilder nodeBuilder = new NodeBuilder();
73         nodeBuilder.setNodeId(createNodeId(key.getIp(),key.getPort()));
74         nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
75         return nodeBuilder.build();
76     }
77
78     public static OvsdbNodeAugmentation createOvsdbAugmentation(OvsdbClient client) {
79         return createOvsdbAugmentation(new OvsdbClientKey(client));
80     }
81
82     public static OvsdbNodeAugmentation createOvsdbAugmentation(OvsdbClientKey key) {
83         OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
84         ovsdbNodeBuilder.setIp(key.getIp());
85         ovsdbNodeBuilder.setPort(key.getPort());
86         return ovsdbNodeBuilder.build();
87     }
88
89     public static IpAddress createIpAddress(InetAddress address) {
90         IpAddress ip = null;
91         if (address instanceof Inet4Address) {
92             ip = createIpAddress((Inet4Address)address);
93         } else if (address instanceof Inet6Address) {
94             ip = createIpAddress((Inet6Address)address);
95         }
96         return ip;
97     }
98
99     public static IpAddress createIpAddress(Inet4Address address) {
100         Ipv4Address ipv4 = new Ipv4Address(address.getHostAddress());
101         return new IpAddress(ipv4);
102     }
103
104     public static IpAddress createIpAddress(Inet6Address address) {
105         Ipv6Address ipv6 = new Ipv6Address(address.getHostAddress());
106         return new IpAddress(ipv6);
107     }
108
109     public static InstanceIdentifier<Node> createInstanceIdentifier(OvsdbClient client) {
110         return createInstanceIdentifier(createIpAddress(client.getConnectionInfo().getRemoteAddress()),
111                 new PortNumber(client.getConnectionInfo().getRemotePort()));
112     }
113
114     public static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
115         InstanceIdentifier<Node> nodePath = InstanceIdentifier
116                 .create(NetworkTopology.class)
117                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
118                 .child(Node.class,new NodeKey(nodeId));
119         return nodePath;
120     }
121
122     public static InstanceIdentifier<Node> createInstanceIdentifier(OvsdbClientKey key,OvsdbBridgeName bridgeName) {
123         return createInstanceIdentifier(createManagedNodeId(key, bridgeName));
124     }
125
126     public static InstanceIdentifier<Node> createInstanceIdentifier(OvsdbClientKey key,Bridge bridge) {
127         String managedNodePathString = bridge
128                 .getExternalIdsColumn()
129                 .getData()
130                 .get(SouthboundConstants.IID_EXTERNAL_ID_KEY);
131         InstanceIdentifier<Node> managedNodePath = null;
132         if (managedNodePathString != null) {
133             managedNodePath = (InstanceIdentifier<Node>) SouthboundUtil
134                     .deserializeInstanceIdentifier(managedNodePathString);
135         }
136         if (managedNodePath == null) {
137             managedNodePath = SouthboundMapper.createInstanceIdentifier(key,new OvsdbBridgeName(bridge.getName()));
138         }
139         return managedNodePath;
140     }
141
142     public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
143         NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
144         return nodeKey.getNodeId();
145     }
146
147     public static InstanceIdentifier<Node> createInstanceIdentifier(OvsdbClientKey key) {
148         return createInstanceIdentifier(key.getIp(), key.getPort());
149     }
150
151     public static InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
152         InstanceIdentifier<Node> path = InstanceIdentifier
153                 .create(NetworkTopology.class)
154                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
155                 .child(Node.class,createNodeKey(ip,port));
156         LOG.debug("Created ovsdb path: {}",path);
157         return path;
158     }
159
160     public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
161         return new NodeKey(createNodeId(ip,port));
162     }
163
164     public static NodeId createNodeId(OvsdbConnectionInfo connectionInfo) {
165         return createNodeId(createIpAddress(connectionInfo.getRemoteAddress()),
166                 new PortNumber(connectionInfo.getRemotePort()));
167     }
168
169     public static NodeId createManagedNodeId(OvsdbConnectionInfo connectionInfo, OvsdbBridgeName bridgeName) {
170         return createManagedNodeId(createIpAddress(connectionInfo.getRemoteAddress()),
171                 new PortNumber(connectionInfo.getRemotePort()),
172                 bridgeName);
173     }
174
175     public static NodeId createManagedNodeId(OvsdbClientKey key, OvsdbBridgeName bridgeName) {
176         return createManagedNodeId(key.getIp(),key.getPort(),bridgeName);
177     }
178
179     public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
180         return new NodeId(createNodeId(ip,port).getValue()
181                 + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
182     }
183
184     public static NodeId createNodeId(IpAddress ip, PortNumber port) {
185         String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
186                 + new String(ip.getValue()) + ":" + port.getValue();
187         Uri uri = new Uri(uriString);
188         NodeId nodeId = new NodeId(uri);
189         return nodeId;
190     }
191
192     public static InetAddress createInetAddress(IpAddress ip) throws UnknownHostException {
193         if (ip.getIpv4Address() != null) {
194             return InetAddress.getByName(ip.getIpv4Address().getValue());
195         } else if (ip.getIpv6Address() != null) {
196             return InetAddress.getByName(ip.getIpv6Address().getValue());
197         } else {
198             throw new UnknownHostException("IP Address has no value");
199         }
200     }
201
202     public static DatapathId createDatapathId(Bridge bridge) {
203         Preconditions.checkNotNull(bridge);
204         if (bridge.getDatapathIdColumn() == null) {
205             return null;
206         } else {
207             return createDatapathId(bridge.getDatapathIdColumn().getData());
208         }
209     }
210
211     public static DatapathId createDatapathId(Set<String> dpids) {
212         Preconditions.checkNotNull(dpids);
213         if (dpids.isEmpty()) {
214             return null;
215         } else {
216             String[] dpidArray = new String[dpids.size()];
217             dpids.toArray(dpidArray);
218             return createDatapathId(dpidArray[0]);
219         }
220     }
221
222     public static String createDatapathType(OvsdbBridgeAugmentation mdsalbridge) {
223         String datapathtype = new String(SouthboundConstants.DATAPATH_TYPE_MAP.get(DatapathTypeSystem.class));
224
225         if (mdsalbridge.getDatapathType() != null) {
226             if (SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType()) != null) {
227                 datapathtype = SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType());
228             } else {
229                 throw new IllegalArgumentException("Unknown datapath type "
230                         + SouthboundConstants.DATAPATH_TYPE_MAP.get(mdsalbridge.getDatapathType()));
231             }
232         }
233         return datapathtype;
234     }
235
236     public static  Class<? extends DatapathTypeBase> createDatapathType(String type) {
237         Preconditions.checkNotNull(type);
238         if (type.isEmpty()) {
239             return DatapathTypeSystem.class;
240         } else {
241             ImmutableBiMap<String, Class<? extends DatapathTypeBase>> mapper =
242                     SouthboundConstants.DATAPATH_TYPE_MAP.inverse();
243             return mapper.get(type);
244         }
245     }
246
247     public static DatapathId createDatapathId(String dpid) {
248         Preconditions.checkNotNull(dpid);
249         DatapathId datapath;
250         if (dpid.matches("^[0-9a-fA-F]{16}")) {
251             Splitter splitter = Splitter.fixedLength(2);
252             Joiner joiner = Joiner.on(":");
253             datapath = new DatapathId(joiner.join(splitter.split(dpid)));
254         } else {
255             datapath = new DatapathId(dpid);
256         }
257         return datapath;
258     }
259
260     public static Set<String> createOvsdbBridgeProtocols(OvsdbBridgeAugmentation ovsdbBridgeNode) {
261         Set<String> protocols = new HashSet<String>();
262         if (ovsdbBridgeNode.getProtocolEntry() != null && ovsdbBridgeNode.getProtocolEntry().size() > 0) {
263             for (ProtocolEntry protocol : ovsdbBridgeNode.getProtocolEntry()) {
264                 if (SouthboundConstants.OVSDB_PROTOCOL_MAP.get(protocol.getProtocol()) != null) {
265                     protocols.add(SouthboundConstants.OVSDB_PROTOCOL_MAP.get(protocol.getProtocol()));
266                 } else {
267                     throw new IllegalArgumentException("Unknown protocol " + protocol.getProtocol());
268                 }
269             }
270         }
271         return protocols;
272     }
273
274     public static  Class<? extends InterfaceTypeBase> createInterfaceType(String type) {
275         Preconditions.checkNotNull(type);
276         return SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(type);
277     }
278
279     public static String createOvsdbInterfaceType(Class<? extends InterfaceTypeBase> mdsaltype) {
280         Preconditions.checkNotNull(mdsaltype);
281         ImmutableBiMap<Class<? extends InterfaceTypeBase>, String> mapper =
282                 SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.inverse();
283         return mapper.get(mdsaltype);
284     }
285
286     public static List<ProtocolEntry> createMdsalProtocols(Bridge bridge) {
287         Set<String> protocols = bridge.getProtocolsColumn().getData();
288         List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
289         if (protocols != null && protocols.size() > 0) {
290             ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
291                     SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
292             for (String protocol : protocols) {
293                 if (protocol != null && mapper.get(protocol) != null) {
294                     protocolList.add(new ProtocolEntryBuilder().
295                             setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get(protocol)).build());
296                 }
297             }
298         }
299         return protocolList;
300     }
301
302     public static List<ControllerEntry> createControllerEntries(Bridge bridge,Map<UUID,
303             Controller> updatedControllerRows) {
304         LOG.debug("Bridge: {}, updatedControllerRows: {}",bridge,updatedControllerRows);
305         Set<UUID> controllerUUIDs = bridge.getControllerColumn().getData();
306         List<ControllerEntry> controllerEntries = new ArrayList<ControllerEntry>();
307         for (UUID controllerUUID : controllerUUIDs ) {
308             Controller controller = updatedControllerRows.get(controllerUUID);
309             if (controller != null && controller.getTargetColumn() != null
310                     && controller.getTargetColumn() != null) {
311                 String targetString = controller.getTargetColumn().getData();
312                 controllerEntries.add(new ControllerEntryBuilder().setTarget(new Uri(targetString)).build());
313             }
314         }
315         return controllerEntries;
316     }
317
318     public static Map<UUID, Controller> createOvsdbController(OvsdbBridgeAugmentation omn,DatabaseSchema dbSchema) {
319         List<ControllerEntry> controllerEntries = omn.getControllerEntry();
320         Map<UUID,Controller> controllerMap = new HashMap<UUID,Controller>();
321         if (controllerEntries != null && !controllerEntries.isEmpty()) {
322             int index = 0;
323             for (ControllerEntry controllerEntry : controllerEntries) {
324                 String controllerNamedUUID = "Controller_" + getRandomUUID();
325                 Controller controller = TyperUtils.getTypedRowWrapper(dbSchema, Controller.class);
326                 controller.setTarget(controllerEntry.getTarget().getValue());
327                 controllerMap.put(new UUID(controllerNamedUUID), controller);
328             }
329         }
330         return controllerMap;
331     }
332
333     public static String getRandomUUID() {
334         return java.util.UUID.randomUUID().toString().replace("-", "");
335     }
336 }