Remove GENIUS UTIL references in NatService/Qos Modules
[netvirt.git] / natservice / impl / src / main / java / org / opendaylight / netvirt / natservice / internal / UpgradeStateListener.java
1 /*
2  * Copyright (c) 2017 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
9 package org.opendaylight.netvirt.natservice.internal;
10
11 import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
12
13 import java.util.Collections;
14 import java.util.Map;
15 import java.util.Optional;
16 import java.util.concurrent.ExecutionException;
17 import javax.inject.Inject;
18 import javax.inject.Singleton;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
21 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
22 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
25 import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
26 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
27 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
28 import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
29 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
30 import org.opendaylight.mdsal.common.api.ReadFailedException;
31 import org.opendaylight.netvirt.natservice.api.CentralizedSwitchScheduler;
32 import org.opendaylight.serviceutils.tools.listener.AbstractClusteredSyncDataTreeChangeListener;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.config.rev170206.NatserviceConfig;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ExtRouters;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.NaptSwitches;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ProviderTypes;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIpsKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.napt.switches.RouterToNaptSwitch;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.serviceutils.upgrade.rev180702.UpgradeConfig;
44 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45 import org.opendaylight.yangtools.yang.common.Uint32;
46 import org.opendaylight.yangtools.yang.common.Uint64;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50 @Singleton
51 public class UpgradeStateListener extends AbstractClusteredSyncDataTreeChangeListener<UpgradeConfig> {
52     private static final Logger LOG = LoggerFactory.getLogger(UpgradeStateListener.class);
53
54     private final DataBroker dataBroker;
55     private final CentralizedSwitchScheduler centralizedSwitchScheduler;
56     private final NatserviceConfig.NatMode natMode;
57     private final SNATDefaultRouteProgrammer defaultRouteProgrammer;
58     private IMdsalApiManager mdsalManager;
59     private IdManagerService idManager;
60     private final NaptSwitchHA naptSwitchHA;
61     private final JobCoordinator coordinator;
62     private final ManagedNewTransactionRunner txRunner;
63
64     @Inject
65     public UpgradeStateListener(final DataBroker dataBroker,
66                                 final CentralizedSwitchScheduler centralizedSwitchScheduler,
67                                 final SNATDefaultRouteProgrammer defaultRouteProgrammer,
68                                 final IMdsalApiManager mdsalManager,
69                                 final IdManagerService idManager,
70                                 final NaptSwitchHA naptSwitchHA,
71                                 final NatserviceConfig config, final JobCoordinator coordinator) {
72         super(dataBroker, DataTreeIdentifier.create(
73                 LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(UpgradeConfig.class)));
74         this.dataBroker = dataBroker;
75         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
76         this.centralizedSwitchScheduler = centralizedSwitchScheduler;
77         this.defaultRouteProgrammer = defaultRouteProgrammer;
78         this.mdsalManager = mdsalManager;
79         this.idManager = idManager;
80         this.coordinator = coordinator;
81         this.naptSwitchHA = naptSwitchHA;
82         if (config != null) {
83             this.natMode = config.getNatMode();
84         } else {
85             this.natMode = NatserviceConfig.NatMode.Controller;
86         }
87         LOG.trace("UpgradeStateListener (nat) initialized");
88     }
89
90     @Override
91     public void add(@NonNull UpgradeConfig newDataObject) {
92     }
93
94     @Override
95     public void remove(@NonNull UpgradeConfig removedDataObject) {
96         if (natMode == NatserviceConfig.NatMode.Conntrack) {
97             return;
98         }
99         LOG.debug("Verify is all Elected Napt Switch and connected back post upgrade");
100     }
101
102     @Override
103     public void update(@NonNull UpgradeConfig original, UpgradeConfig updated) {
104         if (natMode == NatserviceConfig.NatMode.Controller) {
105             if (original.isUpgradeInProgress() && !updated.isUpgradeInProgress()) {
106                 Optional<NaptSwitches> npatSwitches = NatUtil.getAllPrimaryNaptSwitches(dataBroker);
107                 if (npatSwitches.isPresent()) {
108                     for (RouterToNaptSwitch routerToNaptSwitch
109                             : npatSwitches.get().nonnullRouterToNaptSwitch().values()) {
110                         Uint64 primaryNaptDpnId = routerToNaptSwitch.getPrimarySwitchId();
111                         if (!NatUtil.getSwitchStatus(dataBroker, routerToNaptSwitch.getPrimarySwitchId())) {
112                             String routerUuid = routerToNaptSwitch.getRouterName();
113                             coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + routerUuid,
114                                 () -> Collections.singletonList(
115                                     txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
116                                         confTx -> reElectNewNaptSwitch(routerUuid, primaryNaptDpnId, confTx)
117                                 )), NatConstants.NAT_DJC_MAX_RETRIES);
118                         }
119                     }
120                 }
121             }
122             return;
123         }
124
125         LOG.info("UpgradeStateListener update from {} to {}", original, updated);
126         if (!(original.isUpgradeInProgress() && !updated.isUpgradeInProgress())) {
127             return;
128         }
129
130         SingleTransactionDataBroker reader = new SingleTransactionDataBroker(dataBroker);
131         ExtRouters routers;
132         try {
133             routers = reader.syncRead(LogicalDatastoreType.CONFIGURATION,
134                     InstanceIdentifier.create(ExtRouters.class));
135         } catch (ReadFailedException e) {
136             LOG.error("Error reading external routers", e);
137             return;
138         }
139
140         for (Routers router : routers.nonnullRouters().values()) {
141             Map<ExternalIpsKey, ExternalIps> keyExternalIpsMap = router.nonnullExternalIps();
142             if (router.isEnableSnat() && keyExternalIpsMap != null && !keyExternalIpsMap.isEmpty()) {
143                 centralizedSwitchScheduler.scheduleCentralizedSwitch(router);
144             }
145         }
146     }
147
148     private void reElectNewNaptSwitch(String routerName, Uint64 primaryNaptDpnId,
149             TypedReadWriteTransaction<Configuration> confTx) throws ExecutionException, InterruptedException {
150         // Check if this is externalRouter else ignore
151         InstanceIdentifier<Routers> extRoutersId = NatUtil.buildRouterIdentifier(routerName);
152         Optional<Routers> routerData =
153                 SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
154                         LogicalDatastoreType.CONFIGURATION, extRoutersId);
155         if (!routerData.isPresent()) {
156             LOG.debug("reElectNewNaptSwitch : SNAT->Ignoring Re-election for router {} since its not External Router",
157                     routerName);
158             return;
159         }
160         Routers extRouters = routerData.get();
161         Uuid networkId = extRouters.getNetworkId();
162         if (networkId == null) {
163             LOG.error("hndlTepDelForSnatInEachRtr : SNAT -> Ignoring Re-election  with Napt {} for router {}"
164                     + "as external network configuraton is missing", primaryNaptDpnId, routerName);
165             return;
166         }
167         Uint32 routerId = NatUtil.getVpnId(dataBroker, routerName);
168         LOG.debug("hndlTepDelForSnatInEachRtr : SNAT->Router {} is associated with ext nw {}", routerId, networkId);
169         Uuid bgpVpnUuid = NatUtil.getVpnForRouter(dataBroker, routerName);
170         Uint32 bgpVpnId;
171         if (bgpVpnUuid == null) {
172             LOG.debug("hndlTepDelForSnatInEachRtr : SNAT->Internal VPN-ID {} associated to router {}",
173                     routerId, routerName);
174             bgpVpnId = routerId;
175         } else {
176             bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
177             if (bgpVpnId == NatConstants.INVALID_ID) {
178                 LOG.error("hndlTepDelForSnatInEachRtr :SNAT->Invalid Private BGP VPN ID returned for routerName {}",
179                         routerName);
180                 return;
181             }
182         }
183         defaultRouteProgrammer.removeDefNATRouteInDPN(primaryNaptDpnId, bgpVpnId, confTx);
184         if (routerData.get().isEnableSnat()) {
185             LOG.info("hndlTepDelForSnatInEachRtr : SNAT enabled for router {}", routerId);
186
187             Uint32 routerVpnId = routerId;
188             if (bgpVpnId != NatConstants.INVALID_ID) {
189                 LOG.debug("hndlTepDelForSnatInEachRtr : SNAT -> Private BGP VPN ID (Internal BGP VPN ID) {} "
190                         + "associated to the router {}", bgpVpnId, routerName);
191                 routerVpnId = bgpVpnId;
192             } else {
193                 LOG.debug("hndlTepDelForSnatInEachRtr : SNAT -> Internal L3 VPN ID (Router ID) {} "
194                         + "associated to the router {}", routerVpnId, routerName);
195             }
196             //Re-elect the other available switch as the NAPT switch and program the NAT flows.
197             ProviderTypes extNwProvType = NatEvpnUtil.getExtNwProvTypeFromRouterName(dataBroker,
198                     routerName, networkId);
199             String externalVpnName = NatUtil.getAssociatedVPN(dataBroker,extRouters.getNetworkId());
200             if (extNwProvType == null) {
201                 return;
202             }
203             NatUtil.removeSNATFromDPN(dataBroker, mdsalManager, idManager, naptSwitchHA, primaryNaptDpnId, extRouters,
204                     routerId, routerVpnId, externalVpnName, extNwProvType, confTx);
205
206         } else {
207             LOG.info("hndlTepDelForSnatInEachRtr : SNAT is not enabled for router {} to handle addDPN event {}",
208                     routerId, primaryNaptDpnId);
209         }
210     }
211
212 }