Fixed for VXLAN networks in Neutron-Vpp-Mapper
[groupbasedpolicy.git] / neutron-vpp-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / vpp / mapper / processors / NetworkAware.java
1 /*\r
2  * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 \r
9 package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;\r
10 \r
11 import java.util.ArrayList;\r
12 import java.util.List;\r
13 \r
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
15 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
16 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;\r
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;\r
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
19 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.FlatNetwork;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.NetworkTypeBase;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.VlanNetwork;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomain;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomainBuilder;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomainKey;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.bridge.domain.PhysicalLocationRef;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.bridge.domain.PhysicalLocationRefBuilder;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeFlat;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVlan;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\r
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;\r
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;\r
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;\r
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;\r
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;\r
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;\r
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
43 import org.slf4j.Logger;\r
44 import org.slf4j.LoggerFactory;\r
45 \r
46 import com.google.common.annotations.VisibleForTesting;\r
47 import com.google.common.base.Function;\r
48 import com.google.common.base.Optional;\r
49 import com.google.common.collect.Lists;\r
50 \r
51 public class NetworkAware implements MappingProvider<Network> {\r
52 \r
53     private static final Logger LOG = LoggerFactory.getLogger(NetworkAware.class);\r
54 \r
55     private final DataBroker dataBroker;\r
56 \r
57     public NetworkAware(DataBroker dataBroker) {\r
58         this.dataBroker = dataBroker;\r
59     }\r
60 \r
61     @Override\r
62     public InstanceIdentifier<Network> getNeutronDtoIid() {\r
63         return InstanceIdentifier.builder(Neutron.class).child(Networks.class).child(Network.class).build();\r
64     }\r
65 \r
66     @Override\r
67     public void processCreatedNeutronDto(Network network) {\r
68         BridgeDomain bridgeDomain = createBridgeDomain(network);\r
69         if (bridgeDomain != null) {\r
70             ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();\r
71             rwTx.put(LogicalDatastoreType.CONFIGURATION, getBridgeDomainIid(bridgeDomain.getId()), bridgeDomain);\r
72             DataStoreHelper.submitToDs(rwTx);\r
73         }\r
74     }\r
75 \r
76     @VisibleForTesting\r
77     BridgeDomain createBridgeDomain(Network network) {\r
78         BridgeDomainBuilder bridgeDomainBuilder = new BridgeDomainBuilder();\r
79         String description = (network.getName() != null) ? network.getName() : "Neutron network";\r
80         bridgeDomainBuilder.setDescription(description);\r
81         bridgeDomainBuilder.setId(network.getUuid().getValue());\r
82         NetworkProviderExtension providerAug = network.getAugmentation(NetworkProviderExtension.class);\r
83         if (providerAug == null || providerAug.getNetworkType() == null) {\r
84             LOG.error("Cannot create VPP bridge domain. Network type not specified in neutron network: {}", network);\r
85             return null;\r
86         }\r
87         Class<? extends NetworkTypeBase> netType = convertNetworkType(providerAug.getNetworkType());\r
88         if (netType == null) {\r
89             return null;\r
90         }\r
91         bridgeDomainBuilder.setPhysicalLocationRef(resolveDomainLocations(providerAug));\r
92         bridgeDomainBuilder.setType(netType);\r
93         if (providerAug.getNetworkType().isAssignableFrom(NetworkTypeVlan.class)\r
94                 && providerAug.getSegmentationId() != null) {\r
95             try {\r
96                 bridgeDomainBuilder.setVlan(new VlanId(Integer.valueOf(providerAug.getSegmentationId())));\r
97             } catch (NumberFormatException e) {\r
98                 LOG.error("Neutron network {}. Cannot create VLAN ID from segmentation-id: {}. {}",\r
99                         providerAug.getSegmentationId(), network.getUuid(), e);\r
100                 return null;\r
101             }\r
102         }\r
103         return bridgeDomainBuilder.build();\r
104     }\r
105 \r
106     @VisibleForTesting\r
107     List<PhysicalLocationRef> resolveDomainLocations(NetworkProviderExtension providerAug) {\r
108         List<PhysicalLocationRef> locationRefs = new ArrayList<>();\r
109         ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();\r
110         if (providerAug.getPhysicalNetwork() == null) {\r
111             return null;\r
112         }\r
113         Optional<Topology> readTopology = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
114                 getTopologyIid(new TopologyId(providerAug.getPhysicalNetwork())), rTx);\r
115         if (readTopology.isPresent()) {\r
116             Topology topology = readTopology.get();\r
117             for (Node node : topology.getNode()) {\r
118                 PhysicalLocationRefBuilder location = new PhysicalLocationRefBuilder();\r
119                 location.setNodeId(node.getNodeId());\r
120                 location.setInterface(Lists.transform(node.getTerminationPoint(),\r
121                         new Function<TerminationPoint, String>() {\r
122 \r
123                             @Override\r
124                             public String apply(TerminationPoint input) {\r
125                                 return input.getTpId().getValue();\r
126                             }\r
127                         }));\r
128                 locationRefs.add(location.build());\r
129             }\r
130         }\r
131         return locationRefs;\r
132     }\r
133 \r
134     public static Class<? extends NetworkTypeBase> convertNetworkType(\r
135             Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeBase> base) {\r
136         if (base.isAssignableFrom(NetworkTypeFlat.class)) {\r
137             return FlatNetwork.class;\r
138         }\r
139         if (base.isAssignableFrom(NetworkTypeVlan.class)) {\r
140             return VlanNetwork.class;\r
141         }\r
142         return null;\r
143     }\r
144 \r
145     InstanceIdentifier<Topology> getTopologyIid(TopologyId topologyId) {\r
146         return InstanceIdentifier.builder(NetworkTopology.class)\r
147             .child(Topology.class, new TopologyKey(topologyId))\r
148             .build();\r
149     }\r
150 \r
151     InstanceIdentifier<BridgeDomain> getBridgeDomainIid(String id) {\r
152         return InstanceIdentifier.builder(Config.class).child(BridgeDomain.class, new BridgeDomainKey(id)).build();\r
153     }\r
154 \r
155     @Override\r
156     public void processUpdatedNeutronDto(Network originalNetwork, Network updatedNetwork) {\r
157         InstanceIdentifier<BridgeDomain> bdId = getBridgeDomainIid(originalNetwork.getUuid().getValue());\r
158         WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();\r
159         wTx.delete(LogicalDatastoreType.CONFIGURATION, bdId);\r
160         BridgeDomain updatedBridgeDomain = createBridgeDomain(updatedNetwork);\r
161         if (updatedBridgeDomain != null) {\r
162             wTx.put(LogicalDatastoreType.CONFIGURATION, bdId, updatedBridgeDomain);\r
163         }\r
164         DataStoreHelper.submitToDs(wTx);\r
165     }\r
166 \r
167     @Override\r
168     public void processDeletedNeutronDto(Network network) {\r
169         InstanceIdentifier<BridgeDomain> bdId = getBridgeDomainIid(network.getUuid().getValue());\r
170         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();\r
171         rwTx.delete(LogicalDatastoreType.CONFIGURATION, bdId);\r
172         DataStoreHelper.submitToDs(rwTx);\r
173     }\r
174 }\r