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