Merge "update IT for new SFC model changes for DPLs"
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transact / PhysicalPortUpdateCommand.java
1 /*
2  * Copyright (c) 2015 China Telecom Beijing Research Institute 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.transact;
10
11 import static org.opendaylight.ovsdb.lib.operations.Operations.op;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Map.Entry;
19
20 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
21 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
22 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
23 import org.opendaylight.ovsdb.lib.notation.Mutator;
24 import org.opendaylight.ovsdb.lib.notation.UUID;
25 import org.opendaylight.ovsdb.lib.operations.TransactionBuilder;
26 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
27 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalPort;
28 import org.opendaylight.ovsdb.schema.hardwarevtep.PhysicalSwitch;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.PhysicalSwitchAugmentation;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitchesKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 import com.google.common.base.Optional;
43 import com.google.common.collect.Sets;
44
45 public class PhysicalPortUpdateCommand extends AbstractTransactCommand {
46     private static final Logger LOG = LoggerFactory.getLogger(PhysicalPortUpdateCommand.class);
47
48     public PhysicalPortUpdateCommand(HwvtepOperationalState state,
49             Collection<DataTreeModification<Node>> changes) {
50         super(state, changes);
51     }
52
53     @Override
54     public void execute(TransactionBuilder transaction) {
55         Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> createds =
56                 extractCreated(getChanges(),HwvtepPhysicalPortAugmentation.class);
57         Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> createdPhysicalSwitches =
58                 extractCreatedPhyscialSwitch(getChanges(),PhysicalSwitchAugmentation.class);
59         if (!createds.isEmpty()) {
60             for (Entry<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> created:
61                 createds.entrySet()) {
62                 updatePhysicalPort(transaction,  created.getKey(), created.getValue(), createdPhysicalSwitches);
63             }
64         }
65         Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> updateds =
66                 extractUpdated(getChanges(),HwvtepPhysicalPortAugmentation.class);
67         if (!updateds.isEmpty()) {
68             for (Entry<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> updated:
69                 updateds.entrySet()) {
70                 updatePhysicalPort(transaction,  updated.getKey(), updated.getValue(), createdPhysicalSwitches);
71             }
72         }
73     }
74
75     private void updatePhysicalPort(TransactionBuilder transaction,
76             InstanceIdentifier<Node> psNodeiid,
77             List<HwvtepPhysicalPortAugmentation> listPort,
78             Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> createdPhysicalSwitches ) {
79         //Get physical switch which the port belong to: in operation DS or new created
80         PhysicalSwitchAugmentation physicalSwitchBelong = getPhysicalSwitchBelong(psNodeiid, createdPhysicalSwitches);
81         for (HwvtepPhysicalPortAugmentation port : listPort) {
82             LOG.debug("Creating a physical port named: {}", port.getHwvtepNodeName().getValue());
83             Optional<HwvtepPhysicalPortAugmentation> operationalPhysicalPortOptional =
84                     getOperationalState().getPhysicalPortAugmentation(psNodeiid, port.getHwvtepNodeName());
85             PhysicalPort physicalPort = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalPort.class);
86             //get managing global node of physicalSwitchBelong
87             InstanceIdentifier<?> globalNodeIid = physicalSwitchBelong.getManagedBy().getValue();
88             setVlanBindings(globalNodeIid, physicalPort, port);
89             setDescription(physicalPort, port);
90             if (!operationalPhysicalPortOptional.isPresent()) {
91                 //create a physical port
92                 setName(physicalPort, port, operationalPhysicalPortOptional);
93                 String portUuid = "PhysicalPort_" + HwvtepSouthboundMapper.getRandomUUID();
94                 transaction.add(op.insert(physicalPort).withId(portUuid));
95                 //update physical switch table
96                 PhysicalSwitch physicalSwitch = TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalSwitch.class);
97                 physicalSwitch.setName(physicalSwitchBelong.getHwvtepNodeName().getValue());
98                 physicalSwitch.setPorts(Sets.newHashSet(new UUID(portUuid)));
99                 LOG.info("execute: physical switch: {}", physicalSwitch);
100                 transaction.add(op.mutate(physicalSwitch)
101                         .addMutation(physicalSwitch.getPortsColumn().getSchema(), Mutator.INSERT,
102                                 physicalSwitch.getPortsColumn().getData())
103                         .where(physicalSwitch.getNameColumn().getSchema().opEqual(physicalSwitch.getNameColumn().getData()))
104                         .build());
105             } else {
106                 //updated physical port only
107                 HwvtepPhysicalPortAugmentation updatedPhysicalPort = operationalPhysicalPortOptional.get();
108                 String existingPhysicalPortName = updatedPhysicalPort.getHwvtepNodeName().getValue();
109                 PhysicalPort extraPhyscialPort =
110                         TyperUtils.getTypedRowWrapper(transaction.getDatabaseSchema(), PhysicalPort.class);
111                 extraPhyscialPort.setName("");
112                 transaction.add(op.update(physicalPort)
113                         .where(extraPhyscialPort.getNameColumn().getSchema().opEqual(existingPhysicalPortName))
114                         .build());
115             }
116         }
117     }
118
119     private PhysicalSwitchAugmentation getPhysicalSwitchBelong(InstanceIdentifier<Node> psNodeiid,
120             Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> createdPhysicalSwitches) {
121         Optional<PhysicalSwitchAugmentation> physicalSwitchOptional =
122                     getOperationalState().getPhysicalSwitchAugmentation(psNodeiid);
123         PhysicalSwitchAugmentation physicalSwitchAugmentation = null;
124         if (physicalSwitchOptional.isPresent()) {
125             physicalSwitchAugmentation = physicalSwitchOptional.get();
126         } else {
127             physicalSwitchAugmentation = createdPhysicalSwitches.get(psNodeiid);
128         }
129         return physicalSwitchAugmentation;
130     }
131
132     private void setName(PhysicalPort physicalPort, HwvtepPhysicalPortAugmentation inputPhysicalPort,
133             Optional<HwvtepPhysicalPortAugmentation> operationalLogicalSwitchOptional) {
134         if (inputPhysicalPort.getHwvtepNodeName() != null) {
135             physicalPort.setName(inputPhysicalPort.getHwvtepNodeName().getValue());
136         } else if (operationalLogicalSwitchOptional.isPresent()
137                 && operationalLogicalSwitchOptional.get().getHwvtepNodeName() != null) {
138             physicalPort.setName(operationalLogicalSwitchOptional.get().getHwvtepNodeName().getValue());
139         }
140     }
141
142     private void setDescription(PhysicalPort physicalPort, HwvtepPhysicalPortAugmentation inputPhysicalPort) {
143         if (inputPhysicalPort.getHwvtepNodeDescription() != null) {
144             physicalPort.setDescription(inputPhysicalPort.getHwvtepNodeDescription().toString());
145         }
146     }
147
148     private void setVlanBindings(InstanceIdentifier<?> globalNodeIid, PhysicalPort physicalPort,
149             HwvtepPhysicalPortAugmentation inputPhysicalPort) {
150         if (inputPhysicalPort.getVlanBindings() != null) {
151             //get UUID by LogicalSwitchRef
152             Map<Long, UUID> bindingMap = new HashMap<Long, UUID>();
153             for (VlanBindings vlanBinding: inputPhysicalPort.getVlanBindings()) {
154                 HwvtepNodeName lswitchName = new HwvtepNodeName(vlanBinding.getLogicalSwitchRef().getValue());
155                 Optional<LogicalSwitches> operationalSwitchOptional =
156                         getOperationalState().getLogicalSwitches(globalNodeIid, new LogicalSwitchesKey(lswitchName));
157                 if (operationalSwitchOptional.isPresent()) {
158                     Uuid logicalSwitchUuid = operationalSwitchOptional.get().getLogicalSwitchUuid();
159                     bindingMap.put(vlanBinding.getVlanIdKey().getValue().longValue(), new UUID(logicalSwitchUuid.getValue()));
160                 }
161             }
162             physicalPort.setVlanBindings(bindingMap);
163         }
164     }
165
166     private Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractCreated(
167             Collection<DataTreeModification<Node>> changes, Class<HwvtepPhysicalPortAugmentation> class1) {
168         Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> result
169             = new HashMap<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>>();
170         if (changes != null && !changes.isEmpty()) {
171             for (DataTreeModification<Node> change : changes) {
172                 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
173                 final DataObjectModification<Node> mod = change.getRootNode();
174                 Node created = TransactUtils.getCreated(mod);
175                 if (created != null) {
176                     List<HwvtepPhysicalPortAugmentation> portListUpdated = new ArrayList<HwvtepPhysicalPortAugmentation>();
177                     if (created.getTerminationPoint() != null) {
178                         for (TerminationPoint tp : created.getTerminationPoint()) {
179                             HwvtepPhysicalPortAugmentation hppAugmentation = tp.getAugmentation(HwvtepPhysicalPortAugmentation.class);
180                             if (hppAugmentation != null) {
181                                 portListUpdated.add(hppAugmentation);
182                             }
183                         }
184                     }
185                     result.put(key, portListUpdated);
186                 }
187             }
188         }
189         return result;
190     }
191
192     private Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> extractCreatedPhyscialSwitch(
193             Collection<DataTreeModification<Node>> changes, Class<PhysicalSwitchAugmentation> class1) {
194         Map<InstanceIdentifier<Node>, PhysicalSwitchAugmentation> result
195             = new HashMap<InstanceIdentifier<Node>, PhysicalSwitchAugmentation>();
196         if (changes != null && !changes.isEmpty()) {
197             for (DataTreeModification<Node> change : changes) {
198                 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
199                 final DataObjectModification<Node> mod = change.getRootNode();
200                 Node created = TransactUtils.getCreated(mod);
201                 if (created != null) {
202                     PhysicalSwitchAugmentation physicalSwitch = created.getAugmentation(PhysicalSwitchAugmentation.class);
203                     if (physicalSwitch != null) {
204                         result.put(key, physicalSwitch);
205                     }
206                 }
207             }
208         }
209         return result;
210     }
211
212     private Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> extractUpdated(
213             Collection<DataTreeModification<Node>> changes, Class<HwvtepPhysicalPortAugmentation> class1) {
214         Map<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>> result
215             = new HashMap<InstanceIdentifier<Node>, List<HwvtepPhysicalPortAugmentation>>();
216         if (changes != null && !changes.isEmpty()) {
217             for (DataTreeModification<Node> change : changes) {
218                 final InstanceIdentifier<Node> key = change.getRootPath().getRootIdentifier();
219                 final DataObjectModification<Node> mod = change.getRootNode();
220                 Node updated = TransactUtils.getUpdated(mod);
221                 Node before = mod.getDataBefore();
222                 if (updated != null && before != null) {
223                     List<HwvtepPhysicalPortAugmentation> portListUpdated = new ArrayList<HwvtepPhysicalPortAugmentation>();
224                     List<HwvtepPhysicalPortAugmentation> portListBefore = new ArrayList<HwvtepPhysicalPortAugmentation>();
225                     if (updated.getTerminationPoint() != null) {
226                         for (TerminationPoint tp : updated.getTerminationPoint()) {
227                             HwvtepPhysicalPortAugmentation hppAugmentation = tp.getAugmentation(HwvtepPhysicalPortAugmentation.class);
228                             if (hppAugmentation != null) {
229                                 portListUpdated.add(hppAugmentation);
230                             }
231                         }
232                     }
233                     if (before.getTerminationPoint() != null) {
234                         for (TerminationPoint tp : before.getTerminationPoint()) {
235                             HwvtepPhysicalPortAugmentation hppAugmentation = tp.getAugmentation(HwvtepPhysicalPortAugmentation.class);
236                             if (hppAugmentation != null) {
237                                 portListBefore.add(hppAugmentation);
238                             }
239                         }
240                     }
241                     portListUpdated.removeAll(portListBefore);
242                     result.put(key, portListUpdated);
243                 }
244             }
245         }
246         return result;
247     }
248 }