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