Merge "Updated TestIMdsalApiManager.java to support installFlow() with CheckedFuture...
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / impl / ItmProvider.java
1 /*
2  * Copyright (c) 2016 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 itmStatusMonitor = 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         itmStatusMonitor.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             itmStatusMonitor.reportStatus("STARTING");
127             createIdPool();
128             LOG.info("ItmProvider Started");
129             itmStatusMonitor.reportStatus("OPERATIONAL");
130         }catch (Exception ex) {
131             itmStatusMonitor.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     @Override
197     public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
198                                  String gatewayIp, String transportZone, CommandSession session) {
199         if (tepCommandHelper != null) {
200             try {
201                 tepCommandHelper.createLocalCache(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone, session);
202             } catch (TepException e) {
203                 LOG.error(e.getMessage());
204             }
205         } else {
206             LOG.trace("tepCommandHelper doesnt exist");
207         }
208     }
209
210     @Override
211     public void commitTeps() {
212         try {
213             tepCommandHelper.deleteOnCommit();
214             tepCommandHelper.buildTeps();
215         } catch (Exception e) {
216             LOG.debug("unable to configure teps" + e.toString());
217         }
218     }
219
220     @Override
221     public void showTeps(CommandSession session) {
222         try {
223             tepCommandHelper.showTeps(itmManager.getTunnelMonitorEnabledFromConfigDS(), ItmUtils.determineMonitorInterval(this.dataBroker), session);
224         } catch (TepException e) {
225             LOG.error(e.getMessage());
226         }
227     }
228
229     public void showState(List<StateTunnelList> tunnels,CommandSession session) {
230         if (tunnels != null) {
231             try {
232                 tepCommandHelper.showState(tunnels, itmManager.getTunnelMonitorEnabledFromConfigDS(), session);
233             }catch(TepException e) {
234                 LOG.error(e.getMessage());
235             }
236         }else
237             LOG.debug("No tunnels available");
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, subnetMask, gatewayIp, transportZone, session);
249         } catch (Exception e) {
250             LOG.error(e.getMessage());
251         }
252     }
253
254     @Override
255     public void configureTunnelType(String transportZone, String tunnelType) {
256         LOG .debug("ItmProvider: configureTunnelType {} for transportZone {}", tunnelType, transportZone);
257         tepCommandHelper.configureTunnelType(transportZone,tunnelType);
258     }
259
260     @Override
261     public void addVtepConfigSchema(VtepConfigSchema vtepConfigSchema) {
262         VtepConfigSchema validatedSchema = ItmUtils.validateForAddVtepConfigSchema(vtepConfigSchema,
263                 getAllVtepConfigSchemas());
264
265         String schemaName = validatedSchema.getSchemaName();
266         VtepConfigSchema existingSchema = getVtepConfigSchema(schemaName);
267         if (existingSchema != null) {
268             Preconditions.checkArgument(false, String.format("VtepConfigSchema [%s] already exists!", schemaName));
269         }
270         MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
271                 ItmUtils.getVtepConfigSchemaIdentifier(schemaName), validatedSchema);
272         LOG.debug("Vtep config schema {} added to config DS", schemaName);
273     }
274
275     @Override
276     public VtepConfigSchema getVtepConfigSchema(String schemaName) {
277         return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, ItmUtils.getVtepConfigSchemaIdentifier(schemaName),
278                 this.dataBroker).orNull();
279     }
280
281     @Override
282     public List<VtepConfigSchema> getAllVtepConfigSchemas() {
283         return ItmUtils.read(LogicalDatastoreType.CONFIGURATION, ItmUtils.getVtepConfigSchemasIdentifier(),
284                 this.dataBroker).transform(VtepConfigSchemas::getVtepConfigSchema).orNull();
285     }
286
287     @Override
288     public void updateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd, List<BigInteger> lstDpnsForDelete) {
289         LOG.trace("Updating VTEP schema {} by adding DPN's {} and deleting DPN's {}.", schemaName, lstDpnsForAdd,
290                 lstDpnsForDelete);
291
292         VtepConfigSchema schema = ItmUtils.validateForUpdateVtepSchema(schemaName, lstDpnsForAdd, lstDpnsForDelete,
293                 this);
294         VtepConfigSchemaBuilder builder = new VtepConfigSchemaBuilder(schema);
295        /* if (ItmUtils.getDpnIdList(schema.getDpnIds()).isEmpty()) {
296             builder.setDpnIds(schema.getDpnIds());
297         } else {*/
298             if (lstDpnsForAdd != null && !lstDpnsForAdd.isEmpty()) {
299                 List<BigInteger> originalDpnList = ItmUtils.getDpnIdList(schema.getDpnIds()) ;
300                 originalDpnList.addAll(lstDpnsForAdd) ;
301                 builder.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(originalDpnList));
302             }
303             if (lstDpnsForDelete != null && !lstDpnsForDelete.isEmpty()) {
304                 List<BigInteger> originalDpnList = ItmUtils.getDpnIdList(schema.getDpnIds()) ;
305                 originalDpnList.removeAll(lstDpnsForDelete) ;
306                 builder.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(originalDpnList)) ;
307                 // schema.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(ItmUtils.getDpnIdList(schema.getDpnIds()).removeAll(lstDpnsForAdd)));
308             }
309        // }
310         schema = builder.build();
311         MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
312                 ItmUtils.getVtepConfigSchemaIdentifier(schemaName), schema);
313         LOG.debug("Vtep config schema {} updated to config DS with DPN's {}", schemaName, ItmUtils.getDpnIdList(schema.getDpnIds()));
314     }
315
316     @Override
317     public void deleteAllVtepSchemas() {
318         List<VtepConfigSchema> lstSchemas = getAllVtepConfigSchemas();
319         if (lstSchemas != null && !lstSchemas.isEmpty()) {
320             for (VtepConfigSchema schema : lstSchemas) {
321                 MDSALUtil.syncDelete(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
322                         ItmUtils.getVtepConfigSchemaIdentifier(schema.getSchemaName()));
323             }
324         }
325         LOG.debug("Deleted all Vtep schemas from config DS");
326     }
327
328     public void configureTunnelMonitorParams(boolean monitorEnabled, String monitorProtocol) {
329         tepCommandHelper.configureTunnelMonitorParams(monitorEnabled, monitorProtocol);
330     }
331
332     public void configureTunnelMonitorInterval(int interval) {
333         tepCommandHelper.configureTunnelMonitorInterval(interval);
334     }
335     
336     public boolean validateIP (final String ip){
337         if (ip == null || ip.equals("")) {
338             return false;
339         }
340         final String PATTERN =
341                 "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
342         Pattern pattern = Pattern.compile(PATTERN);
343         Matcher matcher = pattern.matcher(ip);
344         return matcher.matches();
345     }
346 }