Merge branch 'topic/master/neutron-yang-migration' to branch 'master'
[ovsdb.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / translator / iaware / impl / NeutronNetworkChangeListener.java
1 /*
2  * Copyright (c) 2015 Brocade Communications 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.openstack.netvirt.translator.iaware.impl;
9
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.Map.Entry;
13
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
16 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
19 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork;
20 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronNetwork_Segment;
21 import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronNetworkAware;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.ext.rev150712.NetworkL3Extension;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeBase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeFlat;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeGre;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVlan;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVxlan;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.neutron.networks.network.Segments;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
34 import org.opendaylight.yangtools.concepts.ListenerRegistration;
35 import org.opendaylight.yangtools.yang.binding.DataObject;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import com.google.common.collect.ImmutableBiMap;
41
42 public class NeutronNetworkChangeListener implements DataChangeListener, AutoCloseable {
43     private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkChangeListener.class);
44
45     private static final ImmutableBiMap<Class<? extends NetworkTypeBase>,String> NETWORK_MAP
46     = new ImmutableBiMap.Builder<Class<? extends NetworkTypeBase>,String>()
47     .put(NetworkTypeFlat.class,"flat")
48     .put(NetworkTypeGre.class,"gre")
49     .put(NetworkTypeVlan.class,"vlan")
50     .put(NetworkTypeVxlan.class,"vxlan")
51     .build();
52
53     private ListenerRegistration<DataChangeListener> registration;
54     private DataBroker db;
55
56     public NeutronNetworkChangeListener(DataBroker db){
57         this.db = db;
58         InstanceIdentifier<Network> path = InstanceIdentifier
59                 .create(Neutron.class)
60                 .child(Networks.class)
61                 .child(Network.class);
62         LOG.debug("Register listener for Neutron Network model data changes");
63         registration =
64                 this.db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, this, DataChangeScope.ONE);
65
66     }
67
68     @Override
69     public void onDataChanged(
70             AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
71         LOG.trace("Data changes : {}",changes);
72
73         Object[] subscribers = NeutronIAwareUtil.getInstances(INeutronNetworkAware.class, this);
74         createNetwork(changes, subscribers);
75         updateNetwork(changes, subscribers);
76         deleteNetwork(changes, subscribers);
77     }
78
79     private void createNetwork(
80             AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
81             Object[] subscribers) {
82         for (Entry<InstanceIdentifier<?>, DataObject> newNetwork : changes.getCreatedData().entrySet()) {
83                 if(newNetwork.getValue() instanceof Network){
84                 NeutronNetwork network = fromMd((Network)newNetwork.getValue());
85                 for(Object entry: subscribers){
86                     INeutronNetworkAware subscriber = (INeutronNetworkAware)entry;
87                     subscriber.neutronNetworkCreated(network);
88                 }
89                 }
90         }
91     }
92
93     private void updateNetwork(
94             AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
95             Object[] subscribers) {
96         for (Entry<InstanceIdentifier<?>, DataObject> updateNetwork : changes.getUpdatedData().entrySet()) {
97                 if(updateNetwork.getValue() instanceof Network){
98                 NeutronNetwork network = fromMd((Network)updateNetwork.getValue());
99                 for(Object entry: subscribers){
100                     INeutronNetworkAware subscriber = (INeutronNetworkAware)entry;
101                     subscriber.neutronNetworkUpdated(network);
102                 }
103                 }
104         }
105     }
106
107     private void deleteNetwork(
108             AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
109             Object[] subscribers) {
110         for (InstanceIdentifier<?> deletedNetworkPath : changes.getRemovedPaths()) {
111                 if(deletedNetworkPath.getTargetType().equals(Network.class)){
112                 NeutronNetwork network = fromMd((Network)changes.getOriginalData().get(deletedNetworkPath));
113                 for(Object entry: subscribers){
114                     INeutronNetworkAware subscriber = (INeutronNetworkAware)entry;
115                     subscriber.neutronNetworkDeleted(network);
116                 }
117                 }
118         }
119     }
120
121     /*
122      * This method is borrowed from NeutronNetworkInterface.java class of Neutron Northbound class.
123      * We will be utilizing similar code from other classes from the same package of neutron project.
124      */
125     private NeutronNetwork fromMd(Network network) {
126         NeutronNetwork result = new NeutronNetwork();
127         result.setAdminStateUp(network.isAdminStateUp());
128         result.setNetworkName(network.getName());
129         result.setShared(network.isShared());
130         result.setStatus(network.getStatus());
131         if (network.getSubnets() != null) {
132             List<String> neutronSubnets = new ArrayList<String>();
133             for( Uuid subnet : network.getSubnets()) {
134                neutronSubnets.add(subnet.getValue());
135             }
136             result.setSubnets(neutronSubnets);
137         }
138
139         // todo remove '-' chars as tenant id doesn't use them
140         result.setTenantID(network.getTenantId().getValue());
141         result.setID(network.getUuid().getValue());
142
143         NetworkL3Extension l3Extension = network.getAugmentation(NetworkL3Extension.class);
144         result.setRouterExternal(l3Extension.isExternal());
145
146         NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
147         result.setProviderPhysicalNetwork(providerExtension.getPhysicalNetwork());
148         result.setProviderSegmentationID(providerExtension.getSegmentationId());
149         result.setProviderNetworkType(NETWORK_MAP.get(providerExtension.getNetworkType()));
150         List<NeutronNetwork_Segment> segments = new ArrayList<NeutronNetwork_Segment>();
151         if (providerExtension.getSegments() != null) {
152             for (Segments segment: providerExtension.getSegments()) {
153                 NeutronNetwork_Segment neutronSegment = new NeutronNetwork_Segment();
154                 neutronSegment.setProviderPhysicalNetwork(segment.getPhysicalNetwork());
155                 neutronSegment.setProviderSegmentationID(segment.getSegmentationId());
156                 neutronSegment.setProviderNetworkType(NETWORK_MAP.get(segment.getNetworkType()));
157                 segments.add(neutronSegment);
158             }
159         }
160         result.setSegments(segments);
161         return result;
162     }
163
164     @Override
165     public void close() throws Exception {
166         registration.close();
167     }
168 }