ITM checkstyle enforcement
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / rpc / ItmManagerRpcService.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.rpc;
9
10 import com.google.common.base.Optional;
11 import com.google.common.util.concurrent.FutureCallback;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import com.google.common.util.concurrent.SettableFuture;
15 import java.math.BigInteger;
16 import java.util.ArrayList;
17 import java.util.List;
18 import java.util.concurrent.Future;
19 import javax.annotation.PostConstruct;
20 import javax.annotation.PreDestroy;
21 import javax.inject.Inject;
22 import javax.inject.Singleton;
23 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelAddWorker;
27 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelDeleteWorker;
28 import org.opendaylight.genius.itm.globals.ITMConstants;
29 import org.opendaylight.genius.itm.impl.ItmUtils;
30 import org.opendaylight.genius.mdsalutil.MDSALUtil;
31 import org.opendaylight.genius.mdsalutil.MatchInfo;
32 import org.opendaylight.genius.mdsalutil.NwConstants;
33 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
34 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVteps;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVtepsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVtepsKey;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwDeviceInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwMlagDeviceInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.BuildExternalTunnelFromDpnsInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.CreateTerminatingServiceActionsInput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwDeviceInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwMlagDeviceInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentInput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalInput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalOutputBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInput;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelFromDpnsInput;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveTerminatingServiceActionsInput;
86 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
87 import org.opendaylight.yangtools.yang.common.RpcError;
88 import org.opendaylight.yangtools.yang.common.RpcResult;
89 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
92
93 @Singleton
94 public class ItmManagerRpcService implements ItmRpcService {
95
96     private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class);
97     private final DataBroker dataBroker;
98     private final IMdsalApiManager mdsalManager;
99     private final IdManagerService idManagerService;
100
101     @Inject
102     public ItmManagerRpcService(final DataBroker dataBroker,final IdManagerService idManagerService,
103                                 final IMdsalApiManager mdsalManager) {
104         this.dataBroker = dataBroker;
105         this.idManagerService = idManagerService;
106         this.mdsalManager = mdsalManager;
107     }
108
109     @PostConstruct
110     public void start() {
111         LOG.info("ItmManagerRpcService Started");
112     }
113
114     @PreDestroy
115     public void close() {
116         LOG.info("ItmManagerRpcService Closed");
117     }
118
119     @Override
120     public Future<RpcResult<GetTunnelInterfaceNameOutput>> getTunnelInterfaceName(GetTunnelInterfaceNameInput input) {
121         RpcResultBuilder<GetTunnelInterfaceNameOutput> resultBld = null;
122         BigInteger sourceDpn = input.getSourceDpid() ;
123         BigInteger destinationDpn = input.getDestinationDpid() ;
124         InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
125                 TunnelList.class)
126                 .child(InternalTunnel.class, new InternalTunnelKey(destinationDpn, sourceDpn, input.getTunnelType()));
127
128         Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
129
130         if  (tnl != null && tnl.isPresent()) {
131             InternalTunnel tunnel = tnl.get();
132             GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ;
133             List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
134             if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
135                 output.setInterfaceName(tunnelInterfaces.get(0));
136                 resultBld = RpcResultBuilder.success();
137                 resultBld.withResult(output.build());
138             } else {
139                 resultBld = RpcResultBuilder.failed();
140             }
141
142         } else {
143             resultBld = RpcResultBuilder.failed();
144         }
145         return Futures.immediateFuture(resultBld.build());
146     }
147
148
149     @Override
150     public Future<RpcResult<Void>> removeExternalTunnelEndpoint(
151             RemoveExternalTunnelEndpointInput input) {
152         //Ignore the Futures for now
153         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
154         List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
155         ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService,meshedDpnList,
156                 input.getDestinationIp(), input.getTunnelType());
157         InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
158                 .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
159         WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
160         transaction.delete(LogicalDatastoreType.CONFIGURATION, extPath);
161         ListenableFuture<Void> futureCheck = transaction.submit();
162         Futures.addCallback(futureCheck, new FutureCallback<Void>() {
163
164             @Override public void onSuccess(Void voidInstance) {
165                 result.set(RpcResultBuilder.<Void>success().build());
166             }
167
168             @Override public void onFailure(Throwable error) {
169                 String msg = "Unable to delete DcGatewayIp " + input.getDestinationIp()
170                         + " in datastore and tunnel type " + input.getTunnelType();
171                 LOG.error(msg);
172                 result.set(RpcResultBuilder.<Void>failed()
173                         .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
174             }
175         });
176         return result;
177     }
178
179     @Override
180     public Future<RpcResult<Void>> removeExternalTunnelFromDpns(
181             RemoveExternalTunnelFromDpnsInput input) {
182         //Ignore the Futures for now
183         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
184         List<DPNTEPsInfo> cfgDpnList = ItmUtils.getDpnTepListFromDpnId(dataBroker, input.getDpnId()) ;
185         ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService, cfgDpnList,
186                 input.getDestinationIp(), input.getTunnelType());
187         result.set(RpcResultBuilder.<Void>success().build());
188         return result;
189     }
190
191     @Override
192     public Future<RpcResult<Void>> buildExternalTunnelFromDpns(
193             BuildExternalTunnelFromDpnsInput input) {
194         //Ignore the Futures for now
195         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
196         List<ListenableFuture<Void>> extTunnelResultList = ItmExternalTunnelAddWorker
197                 .buildTunnelsFromDpnToExternalEndPoint(dataBroker, idManagerService,input.getDpnId(),
198                         input.getDestinationIp(), input.getTunnelType());
199         for (ListenableFuture<Void> extTunnelResult : extTunnelResultList) {
200             Futures.addCallback(extTunnelResult, new FutureCallback<Void>() {
201
202                 @Override
203                 public void onSuccess(Void voidInstance) {
204                     result.set(RpcResultBuilder.<Void>success().build());
205                 }
206
207                 @Override
208                 public void onFailure(Throwable error) {
209                     String msg = "Unable to create ext tunnel";
210                     LOG.error("create ext tunnel failed. {}. {}", msg, error);
211                     result.set(RpcResultBuilder.<Void>failed()
212                             .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
213                 }
214             });
215         }
216         return result;
217     }
218
219     @Override
220     public Future<RpcResult<Void>> addExternalTunnelEndpoint(
221             AddExternalTunnelEndpointInput input) {
222         // TODO Auto-generated method stub
223
224         //Ignore the Futures for now
225         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
226         List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
227         ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, idManagerService,meshedDpnList,
228                 input.getDestinationIp(), input.getTunnelType()) ;
229         InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
230                 .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
231         DcGatewayIp dcGatewayIp =
232                 new DcGatewayIpBuilder().setIpAddress(input.getDestinationIp())
233                         .setTunnnelType(input.getTunnelType()).build();
234         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
235         writeTransaction.put(LogicalDatastoreType.CONFIGURATION, extPath,dcGatewayIp, true);
236         ListenableFuture<Void> futureCheck = writeTransaction.submit();
237         Futures.addCallback(futureCheck, new FutureCallback<Void>() {
238
239             @Override public void onSuccess(Void voidInstance) {
240                 result.set(RpcResultBuilder.<Void>success().build());
241             }
242
243             @Override public void onFailure(Throwable error) {
244                 String msg =
245                         "Unable to create DcGatewayIp {} in datastore for ip " + input.getDestinationIp() + "and "
246                                 + "tunnel type " + input.getTunnelType();
247                 LOG.error(msg);
248                 result.set(RpcResultBuilder.<Void>failed()
249                         .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
250             }
251         });
252         return result;
253     }
254
255     @Override
256     public Future<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
257             GetExternalTunnelInterfaceNameInput input) {
258         SettableFuture.create();
259         RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
260         String sourceNode = input.getSourceNode();
261         String dstNode = input.getDestinationNode();
262         InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
263                 ExternalTunnelList.class)
264                 .child(ExternalTunnel.class, new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType()));
265
266         Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
267
268         if (ext != null && ext.isPresent()) {
269             ExternalTunnel exTunnel = ext.get();
270             GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ;
271             output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ;
272             resultBld = RpcResultBuilder.success();
273             resultBld.withResult(output.build()) ;
274         } else {
275             resultBld = RpcResultBuilder.failed();
276         }
277
278         return Futures.immediateFuture(resultBld.build());
279     }
280
281     @Override
282     public Future<RpcResult<java.lang.Void>>
283         createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
284         LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}",
285                 input.getDpnId() , input.getServiceId(), input.getInstruction());
286         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
287         int serviceId = input.getServiceId() ;
288         final List<MatchInfo> mkMatches = getTunnelMatchesForServiceId(serviceId);
289         byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
290         // Flags Byte
291         byte flags = (byte) 0x08;
292         vxLANHeader[0] = flags;
293
294         // Extract the serviceId details and imprint on the VxLAN Header
295         vxLANHeader[4] = (byte) (serviceId >> 16);
296         vxLANHeader[5] = (byte) (serviceId >> 8);
297         vxLANHeader[6] = (byte) (serviceId >> 0);
298
299         Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
300                 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5,
301                 String.format("%s:%d","ITM Flow Entry ",serviceId), 0, 0,
302                 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
303
304         ListenableFuture<Void> installFlowResult =
305                 mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
306         Futures.addCallback(installFlowResult, new FutureCallback<Void>() {
307
308             @Override
309             public void onSuccess(Void voidInstance) {
310                 result.set(RpcResultBuilder.<Void>success().build());
311             }
312
313             @Override
314             public void onFailure(Throwable error) {
315                 String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
316                 LOG.error("create terminating service actions failed. {}. {}", msg, error);
317                 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error)
318                         .build());
319             }
320         });
321         // result.set(RpcResultBuilder.<Void>success().build());
322         return result;
323     }
324
325     @Override
326     public Future<RpcResult<java.lang.Void>>
327         removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
328         LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}",
329                 input.getDpnId(), input.getServiceId());
330         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
331         Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
332                 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5,
333                 String.format("%s:%d","ITM Flow Entry ",input.getServiceId()), 0, 0,
334                 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),
335                 getTunnelMatchesForServiceId(input.getServiceId()), null);
336
337         ListenableFuture<Void> installFlowResult =
338                 mdsalManager.removeFlow(input.getDpnId(), terminatingServiceTableFlow);
339         Futures.addCallback(installFlowResult, new FutureCallback<Void>() {
340
341             @Override
342             public void onSuccess(Void voidInstance) {
343                 result.set(RpcResultBuilder.<Void>success().build());
344             }
345
346             @Override
347             public void onFailure(Throwable error) {
348                 String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
349                 LOG.error("remove terminating service actions failed. {}. {}", msg, error);
350                 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error)
351                         .build());
352             }
353         });
354         //result.set(RpcResultBuilder.<Void>success().build());
355
356         return result ;
357     }
358
359
360     public List<MatchInfo> getTunnelMatchesForServiceId(int serviceId) {
361         final List<MatchInfo> mkMatches = new ArrayList<>();
362         byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
363
364         // Flags Byte
365         byte flag = (byte) 0x08;
366         vxLANHeader[0] = flag;
367
368         // Extract the serviceId details and imprint on the VxLAN Header
369         vxLANHeader[4] = (byte) (serviceId >> 16);
370         vxLANHeader[5] = (byte) (serviceId >> 8);
371         vxLANHeader[6] = (byte) (serviceId >> 0);
372
373         // Matching metadata
374         mkMatches.add(new MatchTunnelId(BigInteger.valueOf(serviceId)));
375
376         return mkMatches;
377     }
378
379     private String getFlowRef(long termSvcTable, int svcId) {
380         return String.valueOf(termSvcTable) + svcId;
381     }
382
383     @Override
384     public Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
385             GetInternalOrExternalInterfaceNameInput input) {
386         RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = RpcResultBuilder.failed();
387         BigInteger srcDpn = input.getSourceDpid() ;
388         srcDpn.toString();
389         IpAddress dstIp = input.getDestinationIp() ;
390         InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(ExternalTunnelList.class)
391                 .child(ExternalTunnel.class,
392                         new ExternalTunnelKey(String.valueOf(dstIp), srcDpn.toString(), TunnelTypeMplsOverGre.class));
393
394         Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
395
396         if (ext != null && ext.isPresent()) {
397             ExternalTunnel extTunnel = ext.get();
398             GetInternalOrExternalInterfaceNameOutputBuilder output =
399                     new GetInternalOrExternalInterfaceNameOutputBuilder()
400                             .setInterfaceName(extTunnel.getTunnelInterfaceName());
401             resultBld = RpcResultBuilder.success();
402             resultBld.withResult(output.build()) ;
403         } else {
404             List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker);
405             if (meshedDpnList == null) {
406                 LOG.error("There are no tunnel mesh info in config DS");
407                 return Futures.immediateFuture(resultBld.build());
408             }
409             // Look for external tunnels if not look for internal tunnel
410             for (DPNTEPsInfo teps : meshedDpnList) {
411                 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
412                 if (dstIp.equals(firstEndPt.getIpAddress())) {
413                     InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(TunnelList.class)
414                             .child(InternalTunnel.class,
415                                     new InternalTunnelKey(teps.getDPNID(), srcDpn, input.getTunnelType()));
416
417                     Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
418                     if (tnl != null && tnl.isPresent()) {
419                         InternalTunnel tunnel = tnl.get();
420                         List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
421                         if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
422                             GetInternalOrExternalInterfaceNameOutputBuilder
423                                     output =
424                                     new GetInternalOrExternalInterfaceNameOutputBuilder()
425                                             .setInterfaceName(tunnelInterfaces.get(0));
426                             resultBld = RpcResultBuilder.success();
427                             resultBld.withResult(output.build());
428                         } else {
429                             LOG.error("No tunnel interface found between source DPN {} ans destination IP {}", srcDpn,
430                                     dstIp);
431                         }
432                         break;
433                     } else {
434                         LOG.error("Tunnel not found for source DPN {} ans destination IP {}", srcDpn, dstIp);
435                     }
436                 }
437             }
438         }
439         return Futures.immediateFuture(resultBld.build());
440     }
441
442     @SuppressWarnings("checkstyle:IllegalCatch")
443     @Override
444     public Future<RpcResult<java.lang.Void>> deleteL2GwDevice(DeleteL2GwDeviceInput input) {
445         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
446         boolean foundVxlanTzone = false;
447         try {
448             final IpAddress hwIp = input.getIpAddress();
449             final String nodeId = input.getNodeId();
450             InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
451             Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
452                     containerPath, dataBroker);
453             if (transportZonesOptional.isPresent()) {
454                 TransportZones transportZones = transportZonesOptional.get();
455                 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
456                     LOG.error("No teps configured");
457                     result.set(RpcResultBuilder.<Void>failed()
458                             .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
459                     return result;
460                 }
461                 for (TransportZone tzone : transportZones.getTransportZone()) {
462                     if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class))) {
463                         continue;
464                     }
465                     foundVxlanTzone = true;
466                     String transportZone = tzone.getZoneName();
467                     if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
468                         result.set(RpcResultBuilder.<Void>failed()
469                                 .withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
470                         return result;
471                     }
472                     SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
473                     DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId);
474                     InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
475                             .child(TransportZone.class, new TransportZoneKey(transportZone))
476                             .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
477                             .build();
478                     WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
479                     //TO DO: add retry if it fails
480
481                     transaction.delete(LogicalDatastoreType.CONFIGURATION, path);
482
483                     ListenableFuture<Void> futureCheck = transaction.submit();
484                     Futures.addCallback(futureCheck, new FutureCallback<Void>() {
485
486                         @Override public void onSuccess(Void voidInstance) {
487                             result.set(RpcResultBuilder.<Void>success().build());
488                         }
489
490                         @Override public void onFailure(Throwable error) {
491                             String msg = String.format("Unable to delete HwVtep %s from datastore", nodeId);
492                             LOG.error("Unable to delete HwVtep {}, {} from datastore", nodeId, hwIp);
493                             result.set(RpcResultBuilder.<Void>failed()
494                                     .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
495                         }
496                     });
497
498                 }
499             } else {
500                 result.set(RpcResultBuilder.<Void>failed()
501                         .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
502                 return result;
503             }
504
505             if (!foundVxlanTzone) {
506                 result.set(RpcResultBuilder.<Void>failed()
507                         .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
508                         .build());
509             }
510
511             return result;
512         } catch (Exception e) {
513             RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed()
514                     .withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
515             return Futures.immediateFuture(resultBuilder.build());
516         }
517     }
518
519     @SuppressWarnings("checkstyle:IllegalCatch")
520     @Override
521     public Future<RpcResult<java.lang.Void>> addL2GwDevice(AddL2GwDeviceInput input) {
522
523         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
524         boolean foundVxlanTzone = false;
525         try {
526             final IpAddress hwIp = input.getIpAddress();
527             final String nodeId = input.getNodeId();
528             //iterate through all transport zones and put TORs under vxlan
529             //if no vxlan tzone is cnfigured, return an error.
530             InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
531             Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
532                     containerPath, dataBroker);
533             if (transportZonesOptional.isPresent()) {
534                 TransportZones transportZones = transportZonesOptional.get();
535                 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
536                     LOG.error("No transportZone configured");
537                     result.set(RpcResultBuilder.<Void>failed()
538                             .withError(RpcError.ErrorType.APPLICATION, "No transportZone Configured").build());
539                     return result;
540                 }
541                 for (TransportZone tzone : transportZones.getTransportZone()) {
542                     if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class))) {
543                         continue;
544                     }
545                     String transportZone = tzone.getZoneName();
546                     if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
547                         continue;
548                     }
549                     foundVxlanTzone = true;
550                     SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
551                     DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId);
552                     InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
553                             .child(TransportZone.class, new TransportZoneKey(transportZone))
554                             .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
555                             .build();
556                     DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp)
557                             .setNodeId(nodeId).setTopologyId(input.getTopologyId()).build();
558                     WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
559                     //TO DO: add retry if it fails
560                     transaction.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
561
562                     ListenableFuture<Void> futureCheck = transaction.submit();
563                     Futures.addCallback(futureCheck, new FutureCallback<Void>() {
564
565                         @Override public void onSuccess(Void voidInstance) {
566                             result.set(RpcResultBuilder.<Void>success().build());
567                         }
568
569                         @Override public void onFailure(Throwable error) {
570                             String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
571                             LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId, hwIp);
572                             result.set(RpcResultBuilder.<Void>failed()
573                                     .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
574                         }
575                     });
576
577                 }
578             } else {
579                 result.set(RpcResultBuilder.<Void>failed()
580                         .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
581                 return result;
582             }
583
584             if (!foundVxlanTzone) {
585                 result.set(RpcResultBuilder.<Void>failed()
586                         .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
587                         .build());
588             }
589
590             return result;
591         } catch (Exception e) {
592             RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed()
593                     .withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
594             return Futures.immediateFuture(resultBuilder.build());
595         }
596     }
597
598     @SuppressWarnings("checkstyle:IllegalCatch")
599     @Override
600     public Future<RpcResult<java.lang.Void>> addL2GwMlagDevice(AddL2GwMlagDeviceInput input) {
601
602         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
603         try {
604             final IpAddress hwIp = input.getIpAddress();
605             final List<String> nodeId = input.getNodeId();
606             InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
607             Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
608                     containerPath, dataBroker);
609             if (transportZonesOptional.isPresent()) {
610                 TransportZones transportZones = transportZonesOptional.get();
611                 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
612                     LOG.error("No teps configured");
613                     result.set(RpcResultBuilder.<Void>failed()
614                             .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
615                     return result;
616                 }
617                 String transportZone = transportZones.getTransportZone().get(0).getZoneName();
618                 if (transportZones.getTransportZone().get(0).getSubnets() == null
619                         || transportZones.getTransportZone().get(0).getSubnets().isEmpty()) {
620                     result.set(RpcResultBuilder.<Void>failed()
621                             .withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
622                     return result;
623                 }
624                 SubnetsKey subnetsKey = transportZones.getTransportZone().get(0).getSubnets().get(0).getKey();
625                 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
626                 InstanceIdentifier<DeviceVteps> path =
627                         InstanceIdentifier.builder(TransportZones.class)
628                                 .child(TransportZone.class, new TransportZoneKey(transportZone))
629                                 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build();
630                 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp)
631                         .setNodeId(nodeId.get(0)).setTopologyId(input.getTopologyId()).build();
632                 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
633                 //TO DO: add retry if it fails
634                 LOG.trace("writing hWvtep{}",deviceVtep);
635                 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
636
637                 if (nodeId.size() == 2) {
638                     LOG.trace("second node-id {}",nodeId.get(1));
639                     DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
640                     InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier.builder(TransportZones.class)
641                             .child(TransportZone.class, new TransportZoneKey(transportZone))
642                             .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey2).build();
643                     DeviceVteps deviceVtep2 = new DeviceVtepsBuilder().setKey(deviceVtepKey2).setIpAddress(hwIp)
644                             .setNodeId(nodeId.get(1))
645                             .setTopologyId(input.getTopologyId()).build();
646                     //TO DO: add retry if it fails
647                     LOG.trace("writing {}",deviceVtep2);
648                     writeTransaction.put(LogicalDatastoreType.CONFIGURATION, path2, deviceVtep2, true);
649                 }
650                 ListenableFuture<Void> futureCheck = writeTransaction.submit();
651                 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
652
653                     @Override
654                     public void onSuccess(Void voidInstance) {
655                         result.set(RpcResultBuilder.<Void>success().build());
656                     }
657
658                     @Override
659                     public void onFailure(Throwable error) {
660                         String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
661                         LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId , hwIp);
662                         result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error)
663                                 .build());
664                     }
665                 });
666             }
667             return result;
668         } catch (Exception e) {
669             RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed()
670                     .withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
671             return Futures.immediateFuture(resultBuilder.build());
672         }
673     }
674
675     @SuppressWarnings("checkstyle:IllegalCatch")
676     @Override
677     public Future<RpcResult<Void>> deleteL2GwMlagDevice(DeleteL2GwMlagDeviceInput input) {
678
679         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
680         try {
681             final IpAddress hwIp = input.getIpAddress();
682             final List<String> nodeId = input.getNodeId();
683             InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
684             Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
685                     containerPath, dataBroker);
686             if (transportZonesOptional.isPresent()) {
687                 TransportZones tzones = transportZonesOptional.get();
688                 if (tzones.getTransportZone() == null || tzones.getTransportZone().isEmpty()) {
689                     LOG.error("No teps configured");
690                     result.set(RpcResultBuilder.<Void>failed()
691                             .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
692                     return result;
693                 }
694                 String transportZone = tzones.getTransportZone().get(0).getZoneName();
695                 if (tzones.getTransportZone().get(0).getSubnets() == null || tzones.getTransportZone()
696                         .get(0).getSubnets().isEmpty()) {
697                     result.set(RpcResultBuilder.<Void>failed()
698                             .withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
699                     return result;
700                 }
701                 SubnetsKey subnetsKey = tzones.getTransportZone().get(0).getSubnets().get(0).getKey();
702                 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
703                 InstanceIdentifier<DeviceVteps> path =
704                         InstanceIdentifier.builder(TransportZones.class)
705                                 .child(TransportZone.class, new TransportZoneKey(transportZone))
706                                 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
707                                 deviceVtepKey).build();
708                 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
709                 //TO DO: add retry if it fails
710                 transaction.delete(LogicalDatastoreType.CONFIGURATION, path);
711
712                 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
713                 InstanceIdentifier<DeviceVteps> path2 =
714                         InstanceIdentifier.builder(TransportZones.class)
715                                 .child(TransportZone.class, new TransportZoneKey(transportZone))
716                                 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
717                                 deviceVtepKey2).build();
718                 //TO DO: add retry if it fails
719                 transaction.delete(LogicalDatastoreType.CONFIGURATION, path2);
720
721                 ListenableFuture<Void> futureCheck = transaction.submit();
722                 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
723
724                     @Override
725                     public void onSuccess(Void voidInstance) {
726                         result.set(RpcResultBuilder.<Void>success().build());
727                     }
728
729                     @Override
730                     public void onFailure(Throwable error) {
731                         String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
732                         LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId , hwIp);
733                         result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error)
734                                 .build());
735                     }
736                 });
737             }
738             return result;
739         } catch (Exception e) {
740             RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed()
741                     .withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
742             return Futures.immediateFuture(resultBuilder.build());
743         }
744     }
745
746     @Override
747     public Future<RpcResult<IsTunnelInternalOrExternalOutput>> isTunnelInternalOrExternal(
748             IsTunnelInternalOrExternalInput input) {
749         RpcResultBuilder<IsTunnelInternalOrExternalOutput> resultBld;
750         String tunIfName = input.getTunnelInterfaceName();
751         long tunVal = 0;
752         IsTunnelInternalOrExternalOutputBuilder output = new IsTunnelInternalOrExternalOutputBuilder()
753                         .setTunnelType(tunVal);
754
755         if (ItmUtils.itmCache.getInternalTunnel(tunIfName) != null) {
756             tunVal = 1;
757         } else if (ItmUtils.itmCache.getExternalTunnel(tunIfName) != null) {
758             tunVal = 2;
759         }
760         output.setTunnelType(tunVal);
761         resultBld = RpcResultBuilder.success();
762         resultBld.withResult(output.build());
763         return Futures.immediateFuture(resultBld.build());
764     }
765
766     @Override
767     public Future<RpcResult<IsDcgwPresentOutput>> isDcgwPresent(IsDcgwPresentInput input) {
768         RpcResultBuilder<IsDcgwPresentOutput> resultBld = RpcResultBuilder.success();
769
770         List<DcGatewayIp> dcGatewayIpList = ItmUtils.getDcGatewayIpList(dataBroker);
771         String dcgwIpStr = input.getDcgwIp();
772         IpAddress dcgwIpAddr = new IpAddress(dcgwIpStr.toCharArray());
773         long retVal;
774
775         if ((dcGatewayIpList != null)
776                 && (!dcGatewayIpList.isEmpty())
777                 && (dcGatewayIpList.contains(dcgwIpAddr))) {
778             //Match found
779             retVal = 1;
780             IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
781             resultBld.withResult(output.build());
782         } else {
783             //Match not found
784             retVal = 2;
785             IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
786             resultBld.withResult(output.build());
787         }
788         return Futures.immediateFuture(resultBld.build());
789     }
790
791 }