switch all UpgradeState users
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / SnatExternalRoutersListener.java
1 /*
2  * Copyright (c) 2018 Red Hat, 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.List;
11 import java.util.Objects;
12 import javax.annotation.PostConstruct;
13 import javax.inject.Inject;
14 import javax.inject.Singleton;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
18 import org.opendaylight.netvirt.natservice.api.CentralizedSwitchScheduler;
19 import org.opendaylight.netvirt.natservice.api.SnatServiceManager;
20 import org.opendaylight.serviceutils.upgrade.UpgradeState;
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.genius.idmanager.rev160406.IdManagerService;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig.NatMode;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 @Singleton
33 public class SnatExternalRoutersListener extends AsyncDataTreeChangeListenerBase<Routers, SnatExternalRoutersListener> {
34     private static final Logger LOG = LoggerFactory.getLogger(SnatExternalRoutersListener.class);
35
36     private final DataBroker dataBroker;
37     private final IdManagerService idManager;
38     private final CentralizedSwitchScheduler  centralizedSwitchScheduler;
39     private final NatMode natMode;
40     private final UpgradeState upgradeState;
41     private final SnatServiceManager natServiceManager;
42
43     @Inject
44     public SnatExternalRoutersListener(final DataBroker dataBroker,
45                                        final IdManagerService idManager,
46                                        final CentralizedSwitchScheduler centralizedSwitchScheduler,
47                                        final NatserviceConfig config,
48                                        final SnatServiceManager natServiceManager,
49                                        final UpgradeState upgradeState) {
50         super(Routers.class, SnatExternalRoutersListener.class);
51         this.dataBroker = dataBroker;
52         this.idManager = idManager;
53         this.centralizedSwitchScheduler = centralizedSwitchScheduler;
54         this.upgradeState = upgradeState;
55         this.natServiceManager = natServiceManager;
56         if (config != null) {
57             this.natMode = config.getNatMode();
58         } else {
59             this.natMode = NatMode.Conntrack;
60         }
61     }
62
63     @Override
64     @PostConstruct
65     public void init() {
66         LOG.info("{} init", getClass().getSimpleName());
67         // This class handles ExternalRouters for Conntrack SNAT mode.
68         // For Controller SNAT mode, its handled in ExternalRoutersListeners.java
69         if (natMode == NatMode.Conntrack) {
70             registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
71             NatUtil.createGroupIdPool(idManager);
72         }
73     }
74
75     @Override
76     protected InstanceIdentifier<Routers> getWildCardPath() {
77         return InstanceIdentifier.create(ExtRouters.class).child(Routers.class);
78     }
79
80     @Override
81     @SuppressWarnings("checkstyle:IllegalCatch")
82     protected void add(InstanceIdentifier<Routers> identifier, Routers routers) {
83         String routerName = routers.getRouterName();
84         if (upgradeState.isUpgradeInProgress()) {
85             LOG.warn("add event for ext-router {}, but upgrade is in progress.", routerName);
86             return;
87         }
88
89         LOG.info("add : external router event for {}", routerName);
90         long routerId = NatUtil.getVpnId(dataBroker, routerName);
91         NatUtil.createRouterIdsConfigDS(dataBroker, routerId, routerName);
92         Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
93         if (bgpVpnUuid != null) {
94             // Router associated to BGPVPN, ignoring it.
95             return;
96         }
97
98         List<ExternalIps> externalIps = routers.getExternalIps();
99         // Allocate Primary NAPTSwitch for this router
100         if (routers.isEnableSnat() && externalIps != null && !externalIps.isEmpty()) {
101             centralizedSwitchScheduler.scheduleCentralizedSwitch(routers);
102         }
103     }
104
105     @Override
106     protected void update(InstanceIdentifier<Routers> identifier, Routers original, Routers update) {
107         String routerName = original.getRouterName();
108         Long routerId = NatUtil.getVpnId(dataBroker, routerName);
109         if (routerId == NatConstants.INVALID_ID) {
110             LOG.error("update : external router event - Invalid routerId for routerName {}", routerName);
111             return;
112         }
113
114         // Check if its update on SNAT flag
115         boolean originalSNATEnabled = original.isEnableSnat();
116         boolean updatedSNATEnabled = update.isEnableSnat();
117         LOG.info("update :called for router {} with originalSNATStatus {} and updatedSNATStatus {}",
118                 routerName, originalSNATEnabled, updatedSNATEnabled);
119         if (!upgradeState.isUpgradeInProgress()) {
120             if (originalSNATEnabled != updatedSNATEnabled) {
121                 if (originalSNATEnabled) {
122                     //SNAT is disabled for the router
123                     LOG.debug("update : SNAT disabled on router {}, release NAPT Switch", routerName);
124                     centralizedSwitchScheduler.releaseCentralizedSwitch(update);
125                 } else {
126                     LOG.debug("update : SNAT enabled on router {}, schedule NAPT Switch", routerName);
127                     centralizedSwitchScheduler.scheduleCentralizedSwitch(update);
128                 }
129             } else if (updatedSNATEnabled) {
130                 centralizedSwitchScheduler.updateCentralizedSwitch(original, update);
131             }
132
133             List<ExternalIps> originalExternalIps = original.getExternalIps();
134             List<ExternalIps> updateExternalIps = update.getExternalIps();
135             if (!Objects.equals(originalExternalIps, updateExternalIps)) {
136                 if (originalExternalIps == null || originalExternalIps.isEmpty()) {
137                     centralizedSwitchScheduler.scheduleCentralizedSwitch(update);
138                 }
139             }
140         }
141     }
142
143     @Override
144     protected void remove(InstanceIdentifier<Routers> identifier, Routers router) {
145         if (identifier == null || router == null) {
146             LOG.error("remove : returning without processing since ext-router is null");
147             return;
148         }
149
150         LOG.info("remove : external router event for {}", router.getRouterName());
151         if (router.isEnableSnat()) {
152             centralizedSwitchScheduler.releaseCentralizedSwitch(router);
153         }
154     }
155
156     @Override
157     protected SnatExternalRoutersListener getDataTreeChangeListener() {
158         return SnatExternalRoutersListener.this;
159     }
160 }