d938f09c261b7fb64c60ea5bd9ddcd65666f5878
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transactions / md / HwvtepPhysicalSwitchUpdateCommand.java
1 /*
2  * Copyright (c) 2015 - 2016 Ericsson India Global Services Pvt Ltd. 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.ovsdb.hwvtepsouthbound.transactions.md;
10
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.Map;
14
15 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
18 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
19 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
20 import org.opendaylight.ovsdb.lib.message.TableUpdates;
21 import org.opendaylight.ovsdb.lib.notation.UUID;
22 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
23 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
24 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
25 import org.opendaylight.ovsdb.schema.hardwarevtep.Tunnel;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalRef;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalSwitchRef;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentationBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Switches;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.SwitchesBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIps;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIpsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.ManagementIpsKey;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIps;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical._switch.attributes.TunnelIpsKey;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 import com.google.common.base.Optional;
52
53 public class HwvtepPhysicalSwitchUpdateCommand extends AbstractTransactionCommand {
54
55     private static final Logger LOG = LoggerFactory.getLogger(HwvtepPhysicalSwitchUpdateCommand.class);
56     private Map<UUID, PhysicalSwitch> updatedPSRows;
57     private Map<UUID, Tunnel> updatedTunnelRows;
58
59     public HwvtepPhysicalSwitchUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates, DatabaseSchema dbSchema) {
60         super(key, updates, dbSchema);
61         updatedPSRows = TyperUtils.extractRowsUpdated(PhysicalSwitch.class, getUpdates(), getDbSchema());
62         try {
63             updatedTunnelRows = TyperUtils.extractRowsUpdated(Tunnel.class, getUpdates(), getDbSchema());
64         } catch (IllegalArgumentException e) {
65             LOG.debug("Tunnel Table not supported on this HWVTEP device", e.getMessage());
66         }
67     }
68
69     @Override
70     public void execute(ReadWriteTransaction transaction) {
71         for (PhysicalSwitch physicalSwitch : updatedPSRows.values()) {
72             updatePhysicalSwitch(transaction, physicalSwitch);
73         }
74     }
75
76     private void updatePhysicalSwitch(ReadWriteTransaction transaction, PhysicalSwitch pSwitch) {
77         final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
78         Optional<Node> connection = HwvtepSouthboundUtil.readNode(transaction, connectionIId);
79         if (connection.isPresent()) {
80             LOG.debug("Connection {} is present", connection);
81             // Update the connection node to let it know it manages this
82             // Physical Switch
83             Node connectionNode = buildConnectionNode(pSwitch);
84             transaction.merge(LogicalDatastoreType.OPERATIONAL, connectionIId, connectionNode);
85
86             // Update the Physical Switch with whatever data we are getting
87             InstanceIdentifier<Node> psIid = getInstanceIdentifier(pSwitch);
88             Node psNode = buildPhysicalSwitchNode(connection.get(), pSwitch);
89             transaction.merge(LogicalDatastoreType.OPERATIONAL, psIid, psNode);
90             getOvsdbConnectionInstance().getDeviceInfo().putPhysicalSwitch(pSwitch.getUuid(), pSwitch);
91             // TODO: Delete entries that are no longer needed
92             // TODO: Deletion of tunnels
93             // TODO: Deletion of Tunnel BFD config and params
94         }
95     }
96
97     private Node buildPhysicalSwitchNode(Node node, PhysicalSwitch pSwitch) {
98         NodeBuilder psNodeBuilder = new NodeBuilder();
99         NodeId psNodeId = getNodeId(pSwitch);
100         psNodeBuilder.setNodeId(psNodeId);
101         PhysicalSwitchAugmentationBuilder psAugmentationBuilder = new PhysicalSwitchAugmentationBuilder();
102         psAugmentationBuilder.setPhysicalSwitchUuid(new Uuid(pSwitch.getUuid().toString()));
103         setManagedBy(psAugmentationBuilder);
104         setPhysicalSwitchId(psAugmentationBuilder, pSwitch);
105         setManagementIps(psAugmentationBuilder, pSwitch);
106         setTunnelIps(psAugmentationBuilder, pSwitch);
107         setTunnels(psAugmentationBuilder, pSwitch);
108
109         psNodeBuilder.addAugmentation(PhysicalSwitchAugmentation.class, psAugmentationBuilder.build());
110
111         LOG.trace("Built with the intent to store PhysicalSwitch data {}", psAugmentationBuilder.build());
112         return psNodeBuilder.build();
113     }
114
115     private void setTunnels(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
116         if (updatedTunnelRows != null && pSwitch.getTunnels() != null && pSwitch.getTunnels().getData() != null
117                 && !pSwitch.getTunnels().getData().isEmpty()) {
118             // Nothing to do but update deviceInfo cache
119             for(UUID uuid: pSwitch.getTunnels().getData()) {
120                 getOvsdbConnectionInstance().getDeviceInfo().putPhysicalSwitchForTunnel(uuid, pSwitch.getUuid());
121             }
122         }
123     }
124
125     private void setManagedBy(PhysicalSwitchAugmentationBuilder psAugmentationBuilder) {
126         InstanceIdentifier<Node> connectionNodePath = getOvsdbConnectionInstance().getInstanceIdentifier();
127         psAugmentationBuilder.setManagedBy(new HwvtepGlobalRef(connectionNodePath));
128     }
129
130     private void setPhysicalSwitchId(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
131         if (pSwitch.getName() != null) {
132             psAugmentationBuilder.setHwvtepNodeName(new HwvtepNodeName(pSwitch.getName()));
133         }
134         if (pSwitch.getDescription() != null) {
135             psAugmentationBuilder.setHwvtepNodeDescription(pSwitch.getDescription());
136         }
137     }
138
139     private void setManagementIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
140         if (pSwitch.getManagementIpsColumn() != null && pSwitch.getManagementIpsColumn().getData() != null
141                 && !pSwitch.getManagementIpsColumn().getData().isEmpty()) {
142             List<ManagementIps> mgmtIps = new ArrayList<>();
143             for (String mgmtIp : pSwitch.getManagementIpsColumn().getData()) {
144                 IpAddress ip = new IpAddress(mgmtIp.toCharArray());
145                 mgmtIps.add(
146                         new ManagementIpsBuilder().setKey(new ManagementIpsKey(ip)).setManagementIpsKey(ip).build());
147             }
148             psAugmentationBuilder.setManagementIps(mgmtIps);
149         }
150     }
151
152     private void setTunnelIps(PhysicalSwitchAugmentationBuilder psAugmentationBuilder, PhysicalSwitch pSwitch) {
153         if (pSwitch.getTunnelIpsColumn() != null && pSwitch.getTunnelIpsColumn().getData() != null
154                 && !pSwitch.getTunnelIpsColumn().getData().isEmpty()) {
155             List<TunnelIps> tunnelIps = new ArrayList<>();
156             for (String tunnelIp : pSwitch.getTunnelIpsColumn().getData()) {
157                 IpAddress ip = new IpAddress(tunnelIp.toCharArray());
158                 tunnelIps.add(new TunnelIpsBuilder().setKey(new TunnelIpsKey(ip)).setTunnelIpsKey(ip).build());
159             }
160             psAugmentationBuilder.setTunnelIps(tunnelIps);
161         }
162     }
163
164     private Node buildConnectionNode(PhysicalSwitch pSwitch) {
165         // Update node with PhysicalSwitch reference
166         NodeBuilder connectionNode = new NodeBuilder();
167         connectionNode.setNodeId(getOvsdbConnectionInstance().getNodeId());
168
169         HwvtepGlobalAugmentationBuilder hgAugmentationBuilder = new HwvtepGlobalAugmentationBuilder();
170         List<Switches> switches = new ArrayList<>();
171         InstanceIdentifier<Node> switchIid =
172                 HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), pSwitch);
173         hgAugmentationBuilder.setSwitches(switches);
174         Switches physicalSwitch = new SwitchesBuilder().setSwitchRef(new HwvtepPhysicalSwitchRef(switchIid)).build();
175         switches.add(physicalSwitch);
176
177         connectionNode.addAugmentation(HwvtepGlobalAugmentation.class, hgAugmentationBuilder.build());
178
179         LOG.debug("Update node with physicalswitch ref {}", hgAugmentationBuilder.getSwitches().iterator().next());
180         return connectionNode.build();
181     }
182
183     private InstanceIdentifier<Node> getInstanceIdentifier(PhysicalSwitch pSwitch) {
184         return HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), pSwitch);
185     }
186
187     private NodeId getNodeId(PhysicalSwitch pSwitch) {
188         NodeKey nodeKey = getInstanceIdentifier(pSwitch).firstKeyOf(Node.class);
189         return nodeKey.getNodeId();
190     }
191
192 }