NETVIRT-1630 migrate to md-sal APIs
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / ExternalSubnetVpnInstanceListener.java
1 /*
2  * Copyright (c) 2017 HPE, 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.netvirt.natservice.internal;
9
10 import java.util.Optional;
11 import javax.annotation.PreDestroy;
12 import javax.inject.Inject;
13 import javax.inject.Singleton;
14 import org.opendaylight.genius.mdsalutil.NwConstants;
15 import org.opendaylight.infrautils.utils.concurrent.Executors;
16 import org.opendaylight.mdsal.binding.api.DataBroker;
17 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
18 import org.opendaylight.netvirt.elanmanager.api.IElanService;
19 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
20 import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.VpnInstanceToVpnId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external.subnets.Subnets;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 @Singleton
32 public class ExternalSubnetVpnInstanceListener extends AbstractAsyncDataTreeChangeListener<VpnInstance> {
33     private static final Logger LOG = LoggerFactory.getLogger(ExternalSubnetVpnInstanceListener.class);
34     private final DataBroker dataBroker;
35     private final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer;
36     private final IElanService elanService;
37     private final IVpnManager vpnManager;
38
39     @Inject
40     public ExternalSubnetVpnInstanceListener(final DataBroker dataBroker,
41                      final SNATDefaultRouteProgrammer snatDefaultRouteProgrammer,
42                      final IElanService elanService, final IVpnManager vpnManager) {
43         super(dataBroker, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(VpnInstanceToVpnId.class)
44                 .child(VpnInstance.class),
45                 Executors.newListeningSingleThreadExecutor("ExternalSubnetVpnInstanceListener", LOG));
46         this.dataBroker = dataBroker;
47         this.snatDefaultRouteProgrammer = snatDefaultRouteProgrammer;
48         this.elanService = elanService;
49         this.vpnManager = vpnManager;
50     }
51
52     public void init() {
53         LOG.info("{} init", getClass().getSimpleName());
54     }
55
56     @Override
57     @PreDestroy
58     public void close() {
59         super.close();
60         Executors.shutdownAndAwaitTermination(getExecutorService());
61     }
62
63     @Override
64     public void remove(InstanceIdentifier<VpnInstance> key, VpnInstance vpnInstance) {
65         LOG.trace("remove : External Subnet VPN Instance remove mapping method - key:{}. value={}",
66                 vpnInstance.key(), vpnInstance);
67         String possibleExtSubnetUuid = vpnInstance.getVpnInstanceName();
68         Optional<Subnets> optionalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
69                 new Uuid(possibleExtSubnetUuid));
70         if (optionalSubnets.isPresent()) {
71             addOrDelDefaultFibRouteToSNATFlow(vpnInstance, optionalSubnets.get(), NwConstants.DEL_FLOW);
72             invokeSubnetDeletedFromVpn(possibleExtSubnetUuid);
73         }
74     }
75
76     @Override
77     public void update(InstanceIdentifier<VpnInstance> key, VpnInstance vpnInstanceOrig,
78             VpnInstance vpnInstanceNew) {
79         LOG.trace("update : External Subnet VPN Instance update mapping method - key:{} original:{} new:{}",
80                 vpnInstanceNew.key(), vpnInstanceOrig, vpnInstanceNew);
81     }
82
83     @Override
84     public void add(InstanceIdentifier<VpnInstance> key, VpnInstance vpnInstance) {
85         LOG.trace("add : External Subnet VPN Instance OP Data Entry add mapping method - key:{}. value={}",
86                 vpnInstance.key(), vpnInstance);
87         String possibleExtSubnetUuid = vpnInstance.getVpnInstanceName();
88         Optional<Subnets> optionalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
89                 new Uuid(possibleExtSubnetUuid));
90         if (optionalSubnets.isPresent()) {
91             LOG.debug("add : VpnInstance {} for external subnet {}.", possibleExtSubnetUuid,
92                     optionalSubnets.get());
93             addOrDelDefaultFibRouteToSNATFlow(vpnInstance, optionalSubnets.get(), NwConstants.ADD_FLOW);
94             invokeSubnetAddedToVpn(possibleExtSubnetUuid);
95         }
96     }
97
98     private void invokeSubnetAddedToVpn(String externalSubnetId) {
99         Uuid externalSubnetUuid = new Uuid(externalSubnetId);
100         Subnetmap subnetMap = NatUtil.getSubnetMap(dataBroker, externalSubnetUuid);
101         if (subnetMap == null) {
102             LOG.error("invokeSubnetAddedToVpn : Cannot invoke onSubnetAddedToVpn for subnet-id {} in vpn-id {}"
103                     + " due to this subnet missing in Subnetmap model", externalSubnetUuid, externalSubnetId);
104             return;
105         }
106         ElanInstance elanInstance = elanService.getElanInstance(subnetMap.getNetworkId().getValue());
107         vpnManager.onSubnetAddedToVpn(subnetMap, false, elanInstance.getElanTag().toJava());
108
109     }
110
111     private void invokeSubnetDeletedFromVpn(String externalSubnetId) {
112         Uuid externalSubnetUuid = new Uuid(externalSubnetId);
113         Subnetmap subnetMap = NatUtil.getSubnetMap(dataBroker, externalSubnetUuid);
114         if (subnetMap == null) {
115             LOG.error("invokeSubnetDeletedFromVpn : Cannot invoke invokeSubnetDeletedFromVpn for subnet-id {} in "
116                     + "vpn-id {} due to this subnet missing in Subnetmap model", externalSubnetUuid, externalSubnetId);
117             return;
118         }
119         vpnManager.onSubnetDeletedFromVpn(subnetMap, false);
120     }
121
122     private void addOrDelDefaultFibRouteToSNATFlow(VpnInstance vpnInstance, Subnets subnet, int flowAction) {
123         String vpnInstanceName = vpnInstance.getVpnInstanceName();
124         LOG.debug("addOrDelDefaultFibRouteToSNATFlow : VpnInstance {} for external subnet {}.",
125                 vpnInstanceName, subnet);
126         snatDefaultRouteProgrammer.addOrDelDefaultFibRouteToSNATForSubnet(subnet,
127                 subnet.getExternalNetworkId().getValue(), flowAction, vpnInstance.getVpnId());
128     }
129 }