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