46fcb5d0b1a2cbc6576f6673372c075852004472
[ovsdb.git] / hwvtepsouthbound / hwvtepsouthbound-impl / src / main / java / org / opendaylight / ovsdb / hwvtepsouthbound / transactions / md / HwvtepLogicalRouterUpdateCommand.java
1 /*
2  * Copyright © 2017 Hewlett Packard Enterprise, Co. 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 com.google.common.base.Optional;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Map.Entry;
16 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepConnectionInstance;
19 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundMapper;
20 import org.opendaylight.ovsdb.hwvtepsouthbound.HwvtepSouthboundUtil;
21 import org.opendaylight.ovsdb.lib.message.TableUpdates;
22 import org.opendaylight.ovsdb.lib.notation.UUID;
23 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
24 import org.opendaylight.ovsdb.lib.schema.typed.TyperUtils;
25 import org.opendaylight.ovsdb.schema.hardwarevtep.ACL;
26 import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalRouter;
27 import org.opendaylight.ovsdb.schema.hardwarevtep.LogicalSwitch;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepAclRef;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentationBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.Acls;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalRouters;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalRoutersBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalRoutersKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.logical.router.attributes.AclBindings;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.logical.router.attributes.AclBindingsBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.logical.router.attributes.StaticRoutes;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.logical.router.attributes.StaticRoutesBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.logical.router.attributes.SwitchBindings;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.logical.router.attributes.SwitchBindingsBuilder;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55
56 public class HwvtepLogicalRouterUpdateCommand extends AbstractTransactionCommand {
57     private static final Logger LOG = LoggerFactory.getLogger(HwvtepLogicalRouterUpdateCommand.class);
58     private final Map<UUID, LogicalRouter> updatedLRRows;
59
60     public HwvtepLogicalRouterUpdateCommand(HwvtepConnectionInstance key, TableUpdates updates,
61             DatabaseSchema dbSchema) {
62         super(key, updates, dbSchema);
63         updatedLRRows = TyperUtils.extractRowsUpdated(LogicalRouter.class, getUpdates(), getDbSchema());
64     }
65
66     @Override
67     public void execute(ReadWriteTransaction transaction) {
68         for (Entry<UUID, LogicalRouter> entry : updatedLRRows.entrySet()) {
69             LOG.trace("Updating logical router {} with {}", entry.getKey(), entry.getValue());
70             updateLogicalRouter(transaction, entry.getValue());
71         }
72     }
73
74     private void updateLogicalRouter(ReadWriteTransaction transaction, final LogicalRouter router) {
75         final InstanceIdentifier<Node> connectionIId = getOvsdbConnectionInstance().getInstanceIdentifier();
76         Optional<Node> connection = HwvtepSouthboundUtil.readNode(transaction, connectionIId);
77         if (connection.isPresent()) {
78             Node connectionNode = buildConnectionNode(router);
79             transaction.merge(LogicalDatastoreType.OPERATIONAL, connectionIId, connectionNode);
80             InstanceIdentifier<LogicalRouters> routerIid = getOvsdbConnectionInstance().getInstanceIdentifier()
81                     .augmentation(HwvtepGlobalAugmentation.class)
82                     .child(LogicalRouters.class, new LogicalRoutersKey(new HwvtepNodeName(router.getName())));
83             getOvsdbConnectionInstance().getDeviceInfo().updateDeviceOperData(LogicalRouters.class, routerIid,
84                     router.getUuid(), router);
85         }
86     }
87
88     private Node buildConnectionNode(final LogicalRouter router) {
89         //Update node with LogicalRouter reference
90         NodeBuilder connectionNode = new NodeBuilder();
91         connectionNode.setNodeId(getOvsdbConnectionInstance().getNodeId());
92         LogicalRoutersBuilder lrBuilder = new LogicalRoutersBuilder();
93         lrBuilder.setLogicalRouterUuid(new Uuid(router.getUuid().toString()));
94         lrBuilder.setHwvtepNodeDescription(router.getDescription());
95         HwvtepNodeName hwvtepName = new HwvtepNodeName(router.getName());
96         lrBuilder.setHwvtepNodeName(hwvtepName);
97         lrBuilder.withKey(new LogicalRoutersKey(hwvtepName));
98
99         setSwitchBindings(router, lrBuilder);
100         setStaticRoutes(router, lrBuilder);
101         setAclBindings(router, lrBuilder);
102
103         List<LogicalRouters> routers = new ArrayList<>();
104         routers.add(lrBuilder.build());
105         HwvtepGlobalAugmentationBuilder hgAugmentationBuilder = new HwvtepGlobalAugmentationBuilder();
106         hgAugmentationBuilder.setLogicalRouters(routers);
107         connectionNode.addAugmentation(HwvtepGlobalAugmentation.class, hgAugmentationBuilder.build());
108         return connectionNode.build();
109     }
110
111     private void setStaticRoutes(final LogicalRouter router, final LogicalRoutersBuilder lrBuilder) {
112         if (isRouterHasStaticRoutes(router)) {
113             List<StaticRoutes> routes = new ArrayList<>();
114             for (Entry<String, String> entry : router.getStaticRoutesColumn().getData().entrySet()) {
115                 StaticRoutesBuilder staticRouteBuilder = new StaticRoutesBuilder();
116                 staticRouteBuilder.setDestinationAddress(new IpPrefix(new Ipv4Prefix(entry.getKey())));
117                 staticRouteBuilder.setNexthopAddress(new IpAddress(new Ipv4Address(entry.getKey())));
118                 routes.add(staticRouteBuilder.build());
119             }
120             lrBuilder.setStaticRoutes(routes);
121         }
122     }
123
124     private boolean isRouterHasStaticRoutes(final LogicalRouter router) {
125         return router != null && router.getStaticRoutesColumn() != null
126                 && router.getStaticRoutesColumn().getData() != null
127                 && !router.getStaticRoutesColumn().getData().isEmpty();
128     }
129
130     private void setAclBindings(final LogicalRouter router, final LogicalRoutersBuilder builder) {
131         if (isRouterHasAcls(router)) {
132             List<AclBindings> bindings = new ArrayList<>();
133             for (Entry<String, UUID> entry : router.getAclBindingColumn().getData().entrySet()) {
134                 AclBindingsBuilder aclBindingBuiler = new AclBindingsBuilder();
135                 UUID aclUUID = entry.getValue();
136                 ACL acl = (ACL)getOvsdbConnectionInstance().getDeviceInfo().getDeviceOperData(Acls.class, aclUUID);
137                 if (acl != null) {
138                     InstanceIdentifier<Acls> aclIid =
139                             HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), acl);
140                     aclBindingBuiler.setAclRef(new HwvtepAclRef(aclIid));
141                     aclBindingBuiler.setRouterInterface(new IpPrefix(new Ipv4Prefix(entry.getKey())));
142                     bindings.add(aclBindingBuiler.build());
143                 }
144                 builder.setAclBindings(bindings);
145             }
146         }
147     }
148
149     private boolean isRouterHasAcls(final LogicalRouter router) {
150         return router != null && router.getAclBindingColumn() != null
151                 && router.getAclBindingColumn().getData() != null
152                 && !router.getAclBindingColumn().getData().isEmpty();
153     }
154
155     private void setSwitchBindings(final LogicalRouter router, final LogicalRoutersBuilder builder) {
156         if (isRouterHasSwitchBindings(router)) {
157             List<SwitchBindings> bindings = new ArrayList<>();
158             for (Entry<String, UUID> entry : router.getSwitchBindingColumn().getData().entrySet()) {
159                 SwitchBindingsBuilder switchBindingBuiler = new SwitchBindingsBuilder();
160                 UUID lsUUID = entry.getValue();
161                 LogicalSwitch logicalSwitch = getOvsdbConnectionInstance().getDeviceInfo().getLogicalSwitch(lsUUID);
162                 if (logicalSwitch != null) {
163                     switchBindingBuiler.setDestinationAddress(new IpPrefix(new Ipv4Prefix(entry.getKey())));
164                     InstanceIdentifier<LogicalSwitches> switchIid =
165                         HwvtepSouthboundMapper.createInstanceIdentifier(getOvsdbConnectionInstance(), logicalSwitch);
166                     switchBindingBuiler.setLogicalSwitchRef(new HwvtepLogicalSwitchRef(switchIid));
167                     bindings.add(switchBindingBuiler.build());
168                 }
169             }
170             builder.setSwitchBindings(bindings);
171         }
172     }
173
174     private boolean isRouterHasSwitchBindings(final LogicalRouter router) {
175         return router != null && router.getSwitchBindingColumn() != null
176                 && router.getSwitchBindingColumn().getData() != null
177                 && !router.getSwitchBindingColumn().getData().isEmpty();
178     }
179 }