Merge "Adds abstract base for Jobs that must be validated"
[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.Optional;
11 import com.google.common.base.Preconditions;
12 import java.math.BigInteger;
13 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import java.util.concurrent.Future;
16
17 import org.apache.felix.service.command.CommandSession;
18 import java.util.regex.Matcher;
19 import java.util.regex.Pattern;
20
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
23 import org.opendaylight.controller.md.sal.binding.api.NotificationService;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
26 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
27 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
28 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
29 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
30 import org.opendaylight.genius.itm.api.IITMProvider;
31 import org.opendaylight.genius.itm.cli.TepCommandHelper;
32 import org.opendaylight.genius.itm.cli.TepException;
33 import org.opendaylight.genius.itm.globals.ITMConstants;
34 import org.opendaylight.genius.itm.listeners.InterfaceStateListener;
35 import org.opendaylight.genius.itm.listeners.TransportZoneListener;
36 import org.opendaylight.genius.itm.listeners.TunnelMonitorChangeListener;
37 import org.opendaylight.genius.itm.listeners.TunnelMonitorIntervalListener;
38 import org.opendaylight.genius.itm.listeners.VtepConfigSchemaListener;
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.genius.mdsalutil.interfaces.IMdsalApiManager;
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.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeGre;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.VtepConfigSchemas;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchema;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.vtep.config.schemas.VtepConfigSchemaBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInputBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInputBuilder;
65 import org.opendaylight.yangtools.yang.common.RpcResult;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
68
69 public class ItmProvider implements BindingAwareProvider, AutoCloseable, IITMProvider /*,ItmStateService */{
70
71     private static final Logger LOG = LoggerFactory.getLogger(ItmProvider.class);
72     private IInterfaceManager interfaceManager;
73     private ITMManager itmManager;
74     private IMdsalApiManager mdsalManager;
75     private DataBroker dataBroker;
76     private NotificationPublishService notificationPublishService;
77     private ItmManagerRpcService itmRpcService ;
78     private IdManagerService idManager;
79     private NotificationService notificationService;
80     private TepCommandHelper tepCommandHelper;
81     private TransportZoneListener tzChangeListener;
82     private TunnelMonitorChangeListener tnlToggleListener;
83     private TunnelMonitorIntervalListener tnlIntervalListener;
84     private VtepConfigSchemaListener vtepConfigSchemaListener;
85     private InterfaceStateListener ifStateListener;
86     private RpcProviderRegistry rpcProviderRegistry;
87     private static final ITMStatusMonitor itmStatusMonitor = ITMStatusMonitor.getInstance();
88     private ItmTunnelEventListener itmStateListener;
89     static short flag = 0;
90
91     public ItmProvider() {
92         LOG.info("ItmProvider Before register MBean");
93         itmStatusMonitor.registerMbean();
94     }
95
96     public void setRpcProviderRegistry(RpcProviderRegistry rpcProviderRegistry) {
97         this.rpcProviderRegistry = rpcProviderRegistry;
98     }
99
100     public RpcProviderRegistry getRpcProviderRegistry() {
101         return this.rpcProviderRegistry;
102     }
103
104     @Override
105     public void onSessionInitiated(ProviderContext session) {
106         LOG.info("ItmProvider Session Initiated");
107         itmStatusMonitor.reportStatus("STARTING");
108         try {
109             dataBroker = session.getSALService(DataBroker.class);
110             idManager = getRpcProviderRegistry().getRpcService(IdManagerService.class);
111
112             itmManager = new ITMManager(dataBroker);
113             tzChangeListener = new TransportZoneListener(dataBroker, idManager) ;
114             itmRpcService = new ItmManagerRpcService(dataBroker, idManager);
115             vtepConfigSchemaListener = new VtepConfigSchemaListener(dataBroker);
116             this.ifStateListener = new InterfaceStateListener(dataBroker);
117             tnlToggleListener = new TunnelMonitorChangeListener(dataBroker);
118             tnlIntervalListener = new TunnelMonitorIntervalListener(dataBroker);
119             tepCommandHelper = new TepCommandHelper(dataBroker);
120             getRpcProviderRegistry().addRpcImplementation(ItmRpcService.class, itmRpcService);
121             itmRpcService.setMdsalManager(mdsalManager);
122             itmManager.setMdsalManager(mdsalManager);
123             itmManager.setNotificationPublishService(notificationPublishService);
124             itmManager.setMdsalManager(mdsalManager);
125             tzChangeListener.setMdsalManager(mdsalManager);
126             tzChangeListener.setItmManager(itmManager);
127             tzChangeListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
128             tnlIntervalListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
129             tnlToggleListener.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
130             tepCommandHelper = new TepCommandHelper(dataBroker);
131             tepCommandHelper.setInterfaceManager(interfaceManager);
132             tepCommandHelper.configureTunnelType(ITMConstants.DEFAULT_TRANSPORT_ZONE,ITMConstants.TUNNEL_TYPE_VXLAN);
133             tepCommandHelper.configureTunnelMonitorParams(ITMConstants.DEFAULT_MONITOR_ENABLED,ITMConstants.MONITOR_TYPE_BFD);
134             tepCommandHelper.configureTunnelMonitorInterval(ITMConstants.DEFAULT_MONITOR_INTERVAL);
135             itmStateListener =new ItmTunnelEventListener(dataBroker);
136             createIdPool();
137             itmStatusMonitor.reportStatus("OPERATIONAL");
138         } catch (Exception e) {
139             LOG.error("Error initializing services", e);
140             itmStatusMonitor.reportStatus("ERROR");
141         }
142     }
143
144     public void setInterfaceManager(IInterfaceManager interfaceManager) {
145         this.interfaceManager = interfaceManager;
146     }
147
148     public void setNotificationPublishService(NotificationPublishService notificationPublishService) {
149         this.notificationPublishService = notificationPublishService;
150     }
151
152     public void setMdsalApiManager(IMdsalApiManager mdsalMgr) {
153         this.mdsalManager = mdsalMgr;
154     }
155     public void setNotificationService(NotificationService notificationService) {
156         this.notificationService = notificationService;
157     }
158
159     @Override
160     public void close() throws Exception {
161         if (itmManager != null) {
162             itmManager.close();
163         }
164         if (tzChangeListener != null) {
165             tzChangeListener.close();
166         }
167         if (tnlIntervalListener != null) {
168             tnlIntervalListener.close();
169         }
170         if(tnlToggleListener!= null){
171             tnlToggleListener.close();
172         }
173         LOG.info("ItmProvider Closed");
174     }
175
176     private void createIdPool() {
177         CreateIdPoolInput createPool = new CreateIdPoolInputBuilder()
178                 .setPoolName(ITMConstants.ITM_IDPOOL_NAME)
179                 .setLow(ITMConstants.ITM_IDPOOL_START)
180                 .setHigh(new BigInteger(ITMConstants.ITM_IDPOOL_SIZE).longValue())
181                 .build();
182         try {
183             Future<RpcResult<Void>> result = idManager.createIdPool(createPool);
184             if ((result != null) && (result.get().isSuccessful())) {
185                 LOG.debug("Created IdPool for ITM Service");
186             }
187         } catch (InterruptedException | ExecutionException e) {
188             LOG.error("Failed to create idPool for ITM Service",e);
189         }
190     }
191
192     @Override
193     public DataBroker getDataBroker() {
194         return dataBroker;
195     }
196
197     public void addExternalEndpoint(Class<? extends TunnelTypeBase> tunnelType, IpAddress dcgwIP) {
198         AddExternalTunnelEndpointInput addExternalTunnelEndpointInput =
199                 new AddExternalTunnelEndpointInputBuilder().setTunnelType(tunnelType)
200                         .setDestinationIp(dcgwIP).build();
201         itmRpcService.addExternalTunnelEndpoint(addExternalTunnelEndpointInput);
202     }
203
204     public void remExternalEndpoint(Class<? extends TunnelTypeBase> tunnelType, IpAddress dcgwIP) {
205         RemoveExternalTunnelEndpointInput removeExternalTunnelEndpointInput =
206                 new RemoveExternalTunnelEndpointInputBuilder().setTunnelType(tunnelType)
207                         .setDestinationIp(dcgwIP).build();
208         itmRpcService.removeExternalTunnelEndpoint(removeExternalTunnelEndpointInput);
209     }
210     @Override
211     public void createLocalCache(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
212                                  String gatewayIp, String transportZone, CommandSession session) {
213         if (tepCommandHelper != null) {
214             try {
215                 tepCommandHelper.createLocalCache(dpnId, portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone, session);
216             } catch (TepException e) {
217                 LOG.error(e.getMessage());
218             }
219         } else {
220             LOG.trace("tepCommandHelper doesnt exist");
221         }
222     }
223
224     @Override
225     public void commitTeps() {
226         try {
227             tepCommandHelper.deleteOnCommit();
228             tepCommandHelper.buildTeps();
229         } catch (Exception e) {
230             LOG.debug("unable to configure teps" + e.toString());
231         }
232     }
233
234     @Override
235     public void showTeps(CommandSession session) {
236         try {
237             tepCommandHelper.showTeps(itmManager.getTunnelMonitorEnabledFromConfigDS(), ItmUtils.determineMonitorInterval(this.dataBroker), session);
238         } catch (TepException e) {
239             LOG.error(e.getMessage());
240         }
241     }
242
243     public void showState(TunnelList tunnels, CommandSession session) {
244         if (tunnels != null) {
245             try {
246                 tepCommandHelper.showState(tunnels, itmManager.getTunnelMonitorEnabledFromConfigDS(), session);
247             } catch (TepException e) {
248                 LOG.trace(e.getMessage());
249             }
250         }
251         else
252             LOG.debug("No tunnels available");
253     }
254
255     public void deleteVtep(BigInteger dpnId, String portName, Integer vlanId, String ipAddress, String subnetMask,
256                            String gatewayIp, String transportZone, CommandSession session) {
257         try {
258             tepCommandHelper.deleteVtep(dpnId,  portName, vlanId, ipAddress, subnetMask, gatewayIp, transportZone, session);
259         } catch (Exception e) {
260             LOG.error(e.getMessage());
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         Optional<VtepConfigSchema> schema = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
288                 ItmUtils.getVtepConfigSchemaIdentifier(schemaName), this.dataBroker);
289         if (schema.isPresent()) {
290             return schema.get();
291         }
292         return null;
293     }
294
295     @Override
296     public List<VtepConfigSchema> getAllVtepConfigSchemas() {
297         Optional<VtepConfigSchemas> schemas = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
298                 ItmUtils.getVtepConfigSchemasIdentifier(), this.dataBroker);
299         if (schemas.isPresent()) {
300             return schemas.get().getVtepConfigSchema();
301         }
302         return null;
303     }
304
305     @Override
306     public void updateVtepSchema(String schemaName, List<BigInteger> lstDpnsForAdd, List<BigInteger> lstDpnsForDelete) {
307         LOG.trace("Updating VTEP schema {} by adding DPN's {} and deleting DPN's {}.", schemaName, lstDpnsForAdd,
308                 lstDpnsForDelete);
309
310         VtepConfigSchema schema = ItmUtils.validateForUpdateVtepSchema(schemaName, lstDpnsForAdd, lstDpnsForDelete,
311                 this);
312         VtepConfigSchemaBuilder builder = new VtepConfigSchemaBuilder(schema);
313        /* if (ItmUtils.getDpnIdList(schema.getDpnIds()).isEmpty()) {
314             builder.setDpnIds(schema.getDpnIds());
315         } else {*/
316             if (lstDpnsForAdd != null && !lstDpnsForAdd.isEmpty()) {
317                 List<BigInteger> originalDpnList = ItmUtils.getDpnIdList(schema.getDpnIds()) ;
318                 originalDpnList.addAll(lstDpnsForAdd) ;
319                 builder.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(originalDpnList));
320             }
321             if (lstDpnsForDelete != null && !lstDpnsForDelete.isEmpty()) {
322                 List<BigInteger> originalDpnList = ItmUtils.getDpnIdList(schema.getDpnIds()) ;
323                 originalDpnList.removeAll(lstDpnsForDelete) ;
324                 builder.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(originalDpnList)) ;
325                 // schema.setDpnIds(ItmUtils.getDpnIdsListFromBigInt(ItmUtils.getDpnIdList(schema.getDpnIds()).removeAll(lstDpnsForAdd)));
326             }
327        // }
328         schema = builder.build();
329         MDSALUtil.syncWrite(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
330                 ItmUtils.getVtepConfigSchemaIdentifier(schemaName), schema);
331         LOG.debug("Vtep config schema {} updated to config DS with DPN's {}", schemaName, ItmUtils.getDpnIdList(schema.getDpnIds()));
332     }
333
334     @Override
335     public void deleteAllVtepSchemas() {
336         List<VtepConfigSchema> lstSchemas = getAllVtepConfigSchemas();
337         if (lstSchemas != null && !lstSchemas.isEmpty()) {
338             for (VtepConfigSchema schema : lstSchemas) {
339                 MDSALUtil.syncDelete(this.dataBroker, LogicalDatastoreType.CONFIGURATION,
340                         ItmUtils.getVtepConfigSchemaIdentifier(schema.getSchemaName()));
341             }
342         }
343         LOG.debug("Deleted all Vtep schemas from config DS");
344     }
345
346     public void configureTunnelMonitorParams(boolean monitorEnabled, String monitorProtocol) {
347         tepCommandHelper.configureTunnelMonitorParams(monitorEnabled, monitorProtocol);
348     }
349
350     public void configureTunnelMonitorInterval(int interval) {
351         tepCommandHelper.configureTunnelMonitorInterval(interval);
352     }
353
354     public boolean validateIP (final String ip){
355         if (ip == null || ip.equals("")) {
356             return false;
357         }
358         final String PATTERN =
359                 "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
360         Pattern pattern = Pattern.compile(PATTERN);
361         Matcher matcher = pattern.matcher(ip);
362         return matcher.matches();
363     }
364 }