migrate TepShowState from deprecated OsgiCommandSupport to Action
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / impl / ItmProvider.java
1 /*
2  * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. 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.genius.itm.impl;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.ListenableFuture;
12 import java.math.BigInteger;
13 import java.util.Collection;
14 import java.util.List;
15 import java.util.concurrent.ExecutionException;
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
18 import javax.annotation.PostConstruct;
19 import javax.annotation.PreDestroy;
20 import javax.inject.Inject;
21 import javax.inject.Singleton;
22
23 import org.apache.felix.service.command.CommandSession;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
27 import org.opendaylight.genius.itm.api.IITMProvider;
28 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
29 import org.opendaylight.genius.itm.cli.TepCommandHelper;
30 import org.opendaylight.genius.itm.cli.TepException;
31 import org.opendaylight.genius.itm.globals.ITMConstants;
32 import org.opendaylight.genius.itm.listeners.InterfaceStateListener;
33 import org.opendaylight.genius.itm.listeners.OvsdbNodeListener;
34 import org.opendaylight.genius.itm.listeners.TransportZoneListener;
35 import org.opendaylight.genius.itm.listeners.TunnelMonitorChangeListener;
36 import org.opendaylight.genius.itm.listeners.TunnelMonitorIntervalListener;
37 import org.opendaylight.genius.itm.listeners.VtepConfigSchemaListener;
38 import org.opendaylight.genius.itm.monitoring.ItmTunnelEventListener;
39 import org.opendaylight.genius.itm.rpc.ItmManagerRpcService;
40 import org.opendaylight.genius.mdsalutil.MDSALUtil;
41 import org.opendaylight.infrautils.utils.concurrent.JdkFutures;
42 import org.opendaylight.mdsal.eos.binding.api.Entity;
43 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
44 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
45 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolOutput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepConfigSchemas;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchema;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInputBuilder;
61 import org.opendaylight.yangtools.yang.common.RpcResult;
62 import org.ops4j.pax.cdi.api.OsgiServiceProvider;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
65
66 @Singleton
67 @OsgiServiceProvider
68 public class ItmProvider implements AutoCloseable, IITMProvider /*,ItmStateService */ {
69
70     private static final Logger LOG = LoggerFactory.getLogger(ItmProvider.class);
71
72     private final DataBroker dataBroker;
73     private final ItmManagerRpcService itmRpcService ;
74     private final IdManagerService idManager;
75     private final TepCommandHelper tepCommandHelper;
76     private final TransportZoneListener tzChangeListener;
77     private final TunnelMonitorChangeListener tnlToggleListener;
78     private final TunnelMonitorIntervalListener tnlIntervalListener;
79     private final VtepConfigSchemaListener vtepConfigSchemaListener;
80     private final InterfaceStateListener ifStateListener;
81     private final EntityOwnershipService entityOwnershipService;
82     private RpcProviderRegistry rpcProviderRegistry;
83     private final ItmTunnelEventListener itmStateListener;
84     private final OvsdbNodeListener ovsdbChangeListener;
85     static short flag = 0;
86     private final TunnelMonitoringConfig tunnelMonitoringConfig;
87     private EntityOwnershipCandidateRegistration registryCandidate;
88     private final DpnTepStateCache dpnTepStateCache;
89
90     @Inject
91     public ItmProvider(DataBroker dataBroker,
92                        IdManagerService idManagerService,
93                        InterfaceStateListener interfaceStateListener,
94                        ItmManagerRpcService itmManagerRpcService,
95                        ItmTunnelEventListener itmTunnelEventListener,
96                        TepCommandHelper tepCommandHelper,
97                        TunnelMonitorChangeListener tunnelMonitorChangeListener,
98                        TunnelMonitorIntervalListener tunnelMonitorIntervalListener,
99                        TransportZoneListener transportZoneListener,
100                        VtepConfigSchemaListener vtepConfigSchemaListener,
101                        OvsdbNodeListener ovsdbNodeListener,
102                        TunnelMonitoringConfig tunnelMonitoringConfig,
103                        EntityOwnershipService entityOwnershipService,
104                        DpnTepStateCache dpnTepStateCache) {
105         LOG.info("ItmProvider Before register MBean");
106         this.dataBroker = dataBroker;
107         this.idManager = idManagerService;
108         this.ifStateListener = interfaceStateListener;
109         this.itmRpcService = itmManagerRpcService;
110         this.itmStateListener = itmTunnelEventListener;
111         this.tepCommandHelper = tepCommandHelper;
112         this.tnlToggleListener = tunnelMonitorChangeListener;
113         this.tnlIntervalListener = tunnelMonitorIntervalListener;
114         this.tzChangeListener = transportZoneListener;
115         this.vtepConfigSchemaListener = vtepConfigSchemaListener;
116         this.ovsdbChangeListener = ovsdbNodeListener;
117         this.tunnelMonitoringConfig = tunnelMonitoringConfig;
118         this.entityOwnershipService = entityOwnershipService;
119         this.dpnTepStateCache = dpnTepStateCache;
120         ITMBatchingUtils.registerWithBatchManager(this.dataBroker);
121     }
122
123     @PostConstruct
124     @SuppressWarnings("checkstyle:IllegalCatch")
125     public void start() {
126         try {
127             createIdPool();
128             registerEntityForOwnership();
129             LOG.info("ItmProvider Started");
130         } catch (Exception ex) {
131             LOG.info("ItmProvider failed to start");
132         }
133     }
134
135     private void registerEntityForOwnership() {
136         try {
137             this.registryCandidate = entityOwnershipService
138                     .registerCandidate(new Entity(ITMConstants.ITM_CONFIG_ENTITY, ITMConstants.ITM_CONFIG_ENTITY));
139         } catch (CandidateAlreadyRegisteredException e) {
140             LOG.error("failed to register entity {} for entity-ownership-service", e.getEntity());
141         }
142     }
143
144     @Override
145     @PreDestroy
146     public void close() {
147         if (tzChangeListener != null) {
148             tzChangeListener.close();
149         }
150         if (tnlIntervalListener != null) {
151             tnlIntervalListener.close();
152         }
153         if (tnlToggleListener != null) {
154             tnlToggleListener.close();
155         }
156         if (ovsdbChangeListener != null) {
157             ovsdbChangeListener.close();
158         }
159         if (registryCandidate != null) {
160             registryCandidate.close();
161         }
162         LOG.info("ItmProvider Closed");
163     }
164
165     private void createIdPool() {
166         CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
167                 .setPoolName(ITMConstants.ITM_IDPOOL_NAME)
168                 .setLow(ITMConstants.ITM_IDPOOL_START)
169                 .setHigh(new BigInteger(ITMConstants.ITM_IDPOOL_SIZE).longValue())
170                 .build();
171         try {
172             ListenableFuture<RpcResult<CreateIdPoolOutput>> result = idManager.createIdPool(createPool);
173             if (result != null && result.get().isSuccessful()) {
174                 LOG.debug("Created IdPool for ITM Service");
175             }
176         } catch (InterruptedException | ExecutionException e) {
177             LOG.error("Failed to create idPool for ITM Service ", e);
178         }
179     }
180
181     @Override
182     public DataBroker getDataBroker() {
183         return dataBroker;
184     }
185
186     @Override
187     public void addExternalEndpoint(Class<? extends TunnelTypeBase> tunnelType, IpAddress dcgwIP) {
188         AddExternalTunnelEndpointInput addExternalTunnelEndpointInput =
189                 new AddExternalTunnelEndpointInputBuilder().setTunnelType(tunnelType)
190                         .setDestinationIp(dcgwIP).build();
191         JdkFutures.addErrorLogging(itmRpcService.addExternalTunnelEndpoint(addExternalTunnelEndpointInput),
192                 LOG, "addExternalTunnelEndpoint");
193     }
194
195     @Override
196     public void remExternalEndpoint(Class<? extends TunnelTypeBase> tunnelType, IpAddress dcgwIP) {
197         RemoveExternalTunnelEndpointInput removeExternalTunnelEndpointInput =
198                 new RemoveExternalTunnelEndpointInputBuilder().setTunnelType(tunnelType)
199                         .setDestinationIp(dcgwIP).build();
200         JdkFutures.addErrorLogging(itmRpcService.removeExternalTunnelEndpoint(removeExternalTunnelEndpointInput),
201                 LOG, "removeExternalTunnelEndpoint");
202     }
203
204     @Override
205     public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
206                                  String gatewayIp, String transportZone, CommandSession session) {
207         if (tepCommandHelper != null) {
208             try {
209                 tepCommandHelper.createLocalCache(dpnId, portName, vlanId, ipAddress, subnetMask,
210                         gatewayIp, transportZone, session);
211             } catch (TepException e) {
212                 LOG.error("Create Local Cache failed", e);
213             }
214         } else {
215             LOG.trace("tepCommandHelper doesnt exist");
216         }
217     }
218
219     @Override
220     public void commitTeps() {
221         tepCommandHelper.deleteOnCommit();
222         tepCommandHelper.buildTeps();
223     }
224
225     @Override
226     public void showTeps(CommandSession session) {
227         try {
228             tepCommandHelper.showTeps(tunnelMonitoringConfig.isTunnelMonitoringEnabled(),
229                     tunnelMonitoringConfig.getMonitorInterval(), session);
230         } catch (TepException e) {
231             LOG.error("show teps failed", e);
232         }
233     }
234
235     @Override
236     public void showState(Collection<StateTunnelList> tunnels) {
237         if (tunnels != null) {
238             try {
239                 tepCommandHelper.showState(tunnels, tunnelMonitoringConfig.isTunnelMonitoringEnabled());
240             } catch (TepException e) {
241                 LOG.error("show state failed", e);
242             }
243         } else {
244             LOG.debug("No tunnels available");
245         }
246     }
247
248     @Override
249     public void showCache(String cacheName) {
250         tepCommandHelper.showCache(cacheName);
251     }
252
253     @Override
254     public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
255                            String gatewayIp, String transportZone, CommandSession session) {
256         try {
257             tepCommandHelper.deleteVtep(dpnId,  portName, vlanId, ipAddress,
258                     subnetMask, gatewayIp, transportZone, session);
259         } catch (TepException e) {
260             LOG.error("Delete Vteps Failed", e);
261         }
262     }
263
264     @Override
265     public void configureTunnelType(String transportZone, String tunnelType) {
266         LOG .debug("ItmProvider: configureTunnelType {} for transportZone {}", tunnelType, transportZone);
267         tepCommandHelper.configureTunnelType(transportZone,tunnelType);
268     }
269
270     @Override
271     public void addVtepConfigSchema(VtepConfigSchema vtepConfigSchema) {
272         VtepConfigSchema validatedSchema = ItmUtils.validateForAddVtepConfigSchema(vtepConfigSchema,
273                 getAllVtepConfigSchemas());
274
275         String schemaName = validatedSchema.getSchemaName();
276         VtepConfigSchema existingSchema = getVtepConfigSchema(schemaName);
277         if (existingSchema != null) {
278             Preconditions.checkArgument(false, String.format("VtepConfigSchema [%s] already exists!", schemaName));
279         }
280         MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
281                 ItmUtils.getVtepConfigSchemaIdentifier(schemaName), validatedSchema);
282         LOG.debug("Vtep config schema {} added to config DS", schemaName);
283     }
284
285     @Override
286     public VtepConfigSchema getVtepConfigSchema(String schemaName) {
287         return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, ItmUtils.getVtepConfigSchemaIdentifier(schemaName),
288                 this.dataBroker).orNull();
289     }
290
291     @Override
292     public List<VtepConfigSchema> getAllVtepConfigSchemas() {
293         return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, ItmUtils.getVtepConfigSchemasIdentifier(),
294                 this.dataBroker).toJavaUtil().map(VtepConfigSchemas::getVtepConfigSchema).orElse(null);
295     }
296
297     @Override
298     public void updateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd, List<BigInteger> lstDpnsForDelete) {
299         LOG.trace("Updating VTEP schema {} by adding DPN's {} and deleting DPN's {}.", schemaName, lstDpnsForAdd,
300                 lstDpnsForDelete);
301
302         VtepConfigSchema schema = ItmUtils.validateForUpdateVtepSchema(schemaName, lstDpnsForAdd, lstDpnsForDelete,
303                 this);
304         VtepConfigSchemaBuilder builder = new VtepConfigSchemaBuilder(schema);
305        /* if (ItmUtils.getDpnIdList(schema.getDpnIds()).isEmpty()) {
306             builder.setDpnIds(schema.getDpnIds());
307         } else {*/
308         if (lstDpnsForAdd != null && !lstDpnsForAdd.isEmpty()) {
309             List<BigInteger> originalDpnList = ItmUtils.getDpnIdList(schema.getDpnIds());
310             originalDpnList.addAll(lstDpnsForAdd) ;
311             builder.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(originalDpnList));
312         }
313         if (lstDpnsForDelete != null && !lstDpnsForDelete.isEmpty()) {
314             List<BigInteger> originalDpnList = ItmUtils.getDpnIdList(schema.getDpnIds());
315             originalDpnList.removeAll(lstDpnsForDelete) ;
316             builder.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(originalDpnList));
317             // schema.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(ItmUtils.getDpnIdList(schema.getDpnIds())
318             // .removeAll(lstDpnsForAdd)));
319         }
320         // }
321         schema = builder.build();
322         MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
323                 ItmUtils.getVtepConfigSchemaIdentifier(schemaName), schema);
324         LOG.debug("Vtep config schema {} updated to config DS with DPN's {}",
325                 schemaName, ItmUtils.getDpnIdList(schema.getDpnIds()));
326     }
327
328     @Override
329     public void deleteAllVtepSchemas() {
330         List<VtepConfigSchema> lstSchemas = getAllVtepConfigSchemas();
331         if (lstSchemas != null && !lstSchemas.isEmpty()) {
332             for (VtepConfigSchema schema : lstSchemas) {
333                 MDSALUtil.syncDelete(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
334                         ItmUtils.getVtepConfigSchemaIdentifier(schema.getSchemaName()));
335             }
336         }
337         LOG.debug("Deleted all Vtep schemas from config DS");
338     }
339
340     @Override
341     public void configureTunnelMonitorParams(boolean monitorEnabled, String monitorProtocol) {
342         tepCommandHelper.configureTunnelMonitorParams(monitorEnabled, monitorProtocol);
343     }
344
345     @Override
346     public void configureTunnelMonitorInterval(int interval) {
347         tepCommandHelper.configureTunnelMonitorInterval(interval);
348     }
349
350     @Override
351     public boolean validateIP(final String ip) {
352         if (ip == null || ip.isEmpty() || "null".equals(ip) || "0.0.0.0".equals(ip)) {
353             return false;
354         }
355         final String PTRN =
356                 "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
357         Pattern pattern = Pattern.compile(PTRN);
358         Matcher matcher = pattern.matcher(ip);
359         return matcher.matches();
360     }
361
362     @Override
363     public Interface getInterface(String tunnelName) {
364         return dpnTepStateCache.getInterfaceFromCache(tunnelName);
365     }
366 }