2 * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.genius.itm.rpc;
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 org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelAddWorker;
23 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelDeleteWorker;
24 import org.opendaylight.genius.itm.globals.ITMConstants;
25 import org.opendaylight.genius.itm.impl.ItmUtils;
26 import org.opendaylight.genius.mdsalutil.MDSALUtil;
27 import org.opendaylight.genius.mdsalutil.MatchFieldType;
28 import org.opendaylight.genius.mdsalutil.MatchInfo;
29 import org.opendaylight.genius.mdsalutil.NwConstants;
30 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVteps;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVtepsBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVtepsKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwDeviceInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwMlagDeviceInput;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.BuildExternalTunnelFromDpnsInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.CreateTerminatingServiceActionsInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwDeviceInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwMlagDeviceInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutputBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInput;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentInput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutputBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalInput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalOutput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalOutputBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelFromDpnsInput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveTerminatingServiceActionsInput;
82 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
83 import org.opendaylight.yangtools.yang.common.RpcError;
84 import org.opendaylight.yangtools.yang.common.RpcResult;
85 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
86 import org.slf4j.Logger;
87 import org.slf4j.LoggerFactory;
89 public class ItmManagerRpcService implements ItmRpcService {
91 private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class);
92 DataBroker dataBroker;
93 private IMdsalApiManager mdsalManager;
96 public void setMdsalManager(IMdsalApiManager mdsalManager) {
97 this.mdsalManager = mdsalManager;
100 IdManagerService idManagerService;
102 public ItmManagerRpcService(DataBroker dataBroker, IdManagerService idManagerService) {
103 this.dataBroker = dataBroker;
104 this.idManagerService = idManagerService;
108 public Future<RpcResult<GetTunnelInterfaceNameOutput>> getTunnelInterfaceName(GetTunnelInterfaceNameInput input) {
109 RpcResultBuilder<GetTunnelInterfaceNameOutput> resultBld = null;
110 BigInteger sourceDpn = input.getSourceDpid() ;
111 BigInteger destinationDpn = input.getDestinationDpid() ;
112 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
114 .child(InternalTunnel.class, new InternalTunnelKey(destinationDpn, sourceDpn, input.getTunnelType()));
116 Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
118 if( tnl != null && tnl.isPresent())
120 InternalTunnel tunnel = tnl.get();
121 GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ;
122 output.setInterfaceName(tunnel.getTunnelInterfaceName()) ;
123 resultBld = RpcResultBuilder.success();
124 resultBld.withResult(output.build()) ;
126 resultBld = RpcResultBuilder.failed();
129 return Futures.immediateFuture(resultBld.build());
134 public Future<RpcResult<Void>> removeExternalTunnelEndpoint(
135 RemoveExternalTunnelEndpointInput input) {
136 //Ignore the Futures for now
137 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
138 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
139 ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService,meshedDpnList , input.getDestinationIp(), input.getTunnelType());
140 InstanceIdentifier<DcGatewayIp> extPath= InstanceIdentifier.builder(DcGatewayIpList.class).child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
141 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
142 t.delete(LogicalDatastoreType.CONFIGURATION, extPath);
143 ListenableFuture<Void> futureCheck = t.submit();
144 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
146 @Override public void onSuccess(Void aVoid) {
147 result.set(RpcResultBuilder.<Void>success().build());
150 @Override public void onFailure(Throwable error) {
152 "Unable to delete DcGatewayIp " + input.getDestinationIp() + " in datastore and tunnel type " + input.getTunnelType();
154 result.set(RpcResultBuilder.<Void>failed()
155 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
162 public Future<RpcResult<Void>> removeExternalTunnelFromDpns(
163 RemoveExternalTunnelFromDpnsInput input) {
164 //Ignore the Futures for now
165 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
166 List<DPNTEPsInfo> cfgDpnList = ItmUtils.getDPNTEPListFromDPNId(dataBroker, input.getDpnId()) ;
167 ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService, cfgDpnList, input.getDestinationIp(), input.getTunnelType());
168 result.set(RpcResultBuilder.<Void>success().build());
173 public Future<RpcResult<Void>> buildExternalTunnelFromDpns(
174 BuildExternalTunnelFromDpnsInput input) {
175 //Ignore the Futures for now
176 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
177 List<ListenableFuture<Void>> extTunnelResultList = ItmExternalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, idManagerService,input.getDpnId(), input.getDestinationIp(), input.getTunnelType());
178 for (ListenableFuture<Void> extTunnelResult : extTunnelResultList) {
179 Futures.addCallback(extTunnelResult, new FutureCallback<Void>(){
182 public void onSuccess(Void aVoid) {
183 result.set(RpcResultBuilder.<Void>success().build());
187 public void onFailure(Throwable error) {
188 String msg = "Unable to create ext tunnel";
189 LOG.error("create ext tunnel failed. {}. {}", msg, error);
190 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
194 result.set(RpcResultBuilder.<Void>success().build());
199 public Future<RpcResult<Void>> addExternalTunnelEndpoint(
200 AddExternalTunnelEndpointInput input) {
201 // TODO Auto-generated method stub
203 //Ignore the Futures for now
204 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
205 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
206 ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, idManagerService,meshedDpnList, input.getDestinationIp(), input.getTunnelType()) ;InstanceIdentifier<DcGatewayIp> extPath= InstanceIdentifier.builder(DcGatewayIpList.class).child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
207 DcGatewayIp dcGatewayIp = new DcGatewayIpBuilder().setIpAddress(input.getDestinationIp()).setTunnnelType(input.getTunnelType()).build();
208 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
209 t.put(LogicalDatastoreType.CONFIGURATION, extPath,dcGatewayIp, true);
210 ListenableFuture<Void> futureCheck = t.submit();
211 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
213 @Override public void onSuccess(Void aVoid) {
214 result.set(RpcResultBuilder.<Void>success().build());
217 @Override public void onFailure(Throwable error) {
219 "Unable to create DcGatewayIp {} in datastore for ip "+ input.getDestinationIp() + "and tunnel type " + input.getTunnelType();
221 result.set(RpcResultBuilder.<Void>failed()
222 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
229 public Future<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
230 GetExternalTunnelInterfaceNameInput input) {
231 SettableFuture.create();
232 RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
233 String sourceNode = input.getSourceNode();
234 String dstNode = input.getDestinationNode();
235 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
236 ExternalTunnelList.class)
237 .child(ExternalTunnel.class, new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType()));
239 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
241 if( ext != null && ext.isPresent())
243 ExternalTunnel exTunnel = ext.get();
244 GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ;
245 output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ;
246 resultBld = RpcResultBuilder.success();
247 resultBld.withResult(output.build()) ;
249 resultBld = RpcResultBuilder.failed();
252 return Futures.immediateFuture(resultBld.build());
256 public Future<RpcResult<java.lang.Void>> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
257 LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId() , input.getServiceId(), input.getInstruction());
258 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
259 int serviceId = input.getServiceId() ;
260 List<MatchInfo> mkMatches = getTunnelMatchesForServiceId(serviceId);
261 byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
263 byte Flags = (byte) 0x08;
264 vxLANHeader[0] = Flags;
266 // Extract the serviceId details and imprint on the VxLAN Header
267 vxLANHeader[4] = (byte) (serviceId >> 16);
268 vxLANHeader[5] = (byte) (serviceId >> 8);
269 vxLANHeader[6] = (byte) (serviceId >> 0);
272 // mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
273 // new BigInteger(1, vxLANHeader),
274 // MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID }));
276 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
277 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5, String.format("%s:%d","ITM Flow Entry ",serviceId),
278 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
280 ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
281 Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
284 public void onSuccess(Void aVoid) {
285 result.set(RpcResultBuilder.<Void>success().build());
289 public void onFailure(Throwable error) {
290 String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
291 LOG.error("create terminating service actions failed. {}. {}", msg, error);
292 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
295 // result.set(RpcResultBuilder.<Void>success().build());
300 public Future<RpcResult<java.lang.Void>> removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
301 LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}", input.getDpnId(), input.getServiceId());
302 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
303 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
304 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5, String.format("%s:%d","ITM Flow Entry ",input.getServiceId()),
305 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),getTunnelMatchesForServiceId(input.getServiceId()), null );
307 ListenableFuture<Void> installFlowResult = mdsalManager.removeFlow(input.getDpnId(), terminatingServiceTableFlow);
308 Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
311 public void onSuccess(Void aVoid) {
312 result.set(RpcResultBuilder.<Void>success().build());
316 public void onFailure(Throwable error) {
317 String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
318 LOG.error("remove terminating service actions failed. {}. {}", msg, error);
319 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
322 //result.set(RpcResultBuilder.<Void>success().build());
328 public List<MatchInfo> getTunnelMatchesForServiceId(int serviceId) {
329 List<MatchInfo> mkMatches = new ArrayList<>();
330 byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
333 byte Flags = (byte) 0x08;
334 vxLANHeader[0] = Flags;
336 // Extract the serviceId details and imprint on the VxLAN Header
337 vxLANHeader[4] = (byte) (serviceId >> 16);
338 vxLANHeader[5] = (byte) (serviceId >> 8);
339 vxLANHeader[6] = (byte) (serviceId >> 0);
342 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[]{
343 BigInteger.valueOf(serviceId)}));
348 private String getFlowRef(long termSvcTable, int svcId) {
349 return String.valueOf(termSvcTable) + svcId;
353 public Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
354 GetInternalOrExternalInterfaceNameInput input) {
355 RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = RpcResultBuilder.failed();
356 BigInteger srcDpn = input.getSourceDpid() ;
358 IpAddress dstIp = input.getDestinationIp() ;
359 InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(
360 ExternalTunnelList.class)
361 .child(ExternalTunnel.class, new ExternalTunnelKey(String.valueOf(dstIp), srcDpn.toString(), TunnelTypeMplsOverGre.class));
363 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
365 if( ext != null && ext.isPresent())
367 ExternalTunnel extTunnel = ext.get();
368 GetInternalOrExternalInterfaceNameOutputBuilder output = new GetInternalOrExternalInterfaceNameOutputBuilder().setInterfaceName(extTunnel.getTunnelInterfaceName() );
369 resultBld = RpcResultBuilder.success();
370 resultBld.withResult(output.build()) ;
372 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker);
373 if(meshedDpnList == null){
374 LOG.error("There are no tunnel mesh info in config DS");
375 return Futures.immediateFuture(resultBld.build());
377 // Look for external tunnels if not look for internal tunnel
378 for (DPNTEPsInfo teps : meshedDpnList) {
379 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
380 if (dstIp.equals(firstEndPt.getIpAddress())) {
381 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
383 .child(InternalTunnel.class, new InternalTunnelKey(teps.getDPNID(), srcDpn, input.getTunnelType()));
385 Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
386 if (tnl != null && tnl.isPresent()) {
387 InternalTunnel tunnel = tnl.get();
388 GetInternalOrExternalInterfaceNameOutputBuilder
390 new GetInternalOrExternalInterfaceNameOutputBuilder()
391 .setInterfaceName(tunnel.getTunnelInterfaceName());
392 resultBld = RpcResultBuilder.success();
393 resultBld.withResult(output.build());
396 LOG.error("Tunnel not found for source DPN {} ans destination IP {}", srcDpn, dstIp);
401 return Futures.immediateFuture(resultBld.build());
405 public Future<RpcResult<java.lang.Void>> deleteL2GwDevice(DeleteL2GwDeviceInput input) {
406 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
407 boolean foundVxlanTzone = false;
409 final IpAddress hwIp = input.getIpAddress();
410 final String node_id = input.getNodeId();
411 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
412 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
413 if (tZonesOptional.isPresent()) {
414 TransportZones tZones = tZonesOptional.get();
415 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
416 LOG.error("No teps configured");
417 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
420 for (TransportZone tzone : tZones.getTransportZone()) {
421 if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class)))
423 foundVxlanTzone = true;
424 String transportZone = tzone.getZoneName();
425 if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
426 result.set(RpcResultBuilder.<Void>failed()
427 .withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
430 SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
431 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id);
432 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
433 .child(TransportZone.class, new TransportZoneKey(transportZone))
434 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
436 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
437 //TO DO: add retry if it fails
439 t.delete(LogicalDatastoreType.CONFIGURATION, path);
441 ListenableFuture<Void> futureCheck = t.submit();
442 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
444 @Override public void onSuccess(Void aVoid) {
445 result.set(RpcResultBuilder.<Void>success().build());
448 @Override public void onFailure(Throwable error) {
449 String msg = String.format("Unable to delete HwVtep {} from datastore", node_id);
450 LOG.error("Unable to delete HwVtep {}, {} from datastore", node_id, hwIp);
451 result.set(RpcResultBuilder.<Void>failed()
452 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
459 result.set(RpcResultBuilder.<Void>failed()
460 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
464 if (!foundVxlanTzone) {
465 result.set(RpcResultBuilder.<Void>failed()
466 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
471 } catch (Exception e) {
472 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
473 withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
474 return Futures.immediateFuture(resultBuilder.build());
479 public Future<RpcResult<java.lang.Void>> addL2GwDevice(AddL2GwDeviceInput input) {
481 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
482 boolean foundVxlanTzone = false;
484 final IpAddress hwIp = input.getIpAddress();
485 final String node_id = input.getNodeId();
486 //iterate through all transport zones and put TORs under vxlan
487 //if no vxlan tzone is cnfigured, return an error.
488 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
489 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath,
491 if (tZonesOptional.isPresent()) {
492 TransportZones tZones = tZonesOptional.get();
493 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
494 LOG.error("No transportZone configured");
495 result.set(RpcResultBuilder.<Void>failed()
496 .withError(RpcError.ErrorType.APPLICATION, "No transportZone Configured").build());
499 for (TransportZone tzone : tZones.getTransportZone()) {
500 if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class)))
502 String transportZone = tzone.getZoneName();
503 if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
506 foundVxlanTzone = true;
507 SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
508 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id);
509 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
510 .child(TransportZone.class, new TransportZoneKey(transportZone))
511 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
513 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp)
514 .setNodeId(node_id).setTopologyId(input.getTopologyId()).build();
515 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
516 //TO DO: add retry if it fails
517 t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
519 ListenableFuture<Void> futureCheck = t.submit();
520 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
522 @Override public void onSuccess(Void aVoid) {
523 result.set(RpcResultBuilder.<Void>success().build());
526 @Override public void onFailure(Throwable error) {
527 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
528 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id, hwIp);
529 result.set(RpcResultBuilder.<Void>failed()
530 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
537 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
541 if (!foundVxlanTzone) {
542 result.set(RpcResultBuilder.<Void>failed()
543 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
548 } catch (Exception e) {
549 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
550 withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
551 return Futures.immediateFuture(resultBuilder.build());
556 public Future<RpcResult<java.lang.Void>> addL2GwMlagDevice(AddL2GwMlagDeviceInput input)
559 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
561 final IpAddress hwIp = input.getIpAddress();
562 final List<String> node_id = input.getNodeId();
563 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
564 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
565 if (tZonesOptional.isPresent()) {
566 TransportZones tZones = tZonesOptional.get();
567 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
568 LOG.error("No teps configured");
569 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
572 String transportZone = tZones.getTransportZone().get(0).getZoneName();
573 if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) {
574 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
577 SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey();
578 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id.get(0));
579 InstanceIdentifier<DeviceVteps> path =
580 InstanceIdentifier.builder(TransportZones.class)
581 .child(TransportZone.class, new TransportZoneKey(transportZone))
582 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build();
583 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp).setNodeId(node_id.get(0)).setTopologyId(input.getTopologyId()).build();
584 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
585 //TO DO: add retry if it fails
586 LOG.trace("writing hWvtep{}",deviceVtep);
587 t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
589 if(node_id.size() == 2) {
590 LOG.trace("second node-id {}",node_id.get(1));
591 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, node_id.get(1));
592 InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier.builder(TransportZones.class)
593 .child(TransportZone.class, new TransportZoneKey(transportZone))
594 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey2).build();
595 DeviceVteps deviceVtep2 = new DeviceVtepsBuilder().setKey(deviceVtepKey2).setIpAddress(hwIp).setNodeId(node_id.get(1))
596 .setTopologyId(input.getTopologyId()).build();
597 //TO DO: add retry if it fails
598 LOG.trace("writing {}",deviceVtep2);
599 t.put(LogicalDatastoreType.CONFIGURATION, path2, deviceVtep2, true);
600 }ListenableFuture<Void> futureCheck = t.submit();
601 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
604 public void onSuccess(Void aVoid) {
605 result.set(RpcResultBuilder.<Void>success().build());
609 public void onFailure(Throwable error) {
610 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
611 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp);
612 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
617 } catch (Exception e) {
618 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
619 withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
620 return Futures.immediateFuture(resultBuilder.build());
624 public Future<RpcResult<Void>> deleteL2GwMlagDevice(DeleteL2GwMlagDeviceInput input) {
626 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
628 final IpAddress hwIp = input.getIpAddress();
629 final List<String> node_id = input.getNodeId();
630 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
631 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
632 if (tZonesOptional.isPresent()) {
633 TransportZones tZones = tZonesOptional.get();
634 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
635 LOG.error("No teps configured");
636 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
639 String transportZone = tZones.getTransportZone().get(0).getZoneName();
640 if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) {
641 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
644 SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey();
645 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id.get(0));
646 InstanceIdentifier<DeviceVteps> path =
647 InstanceIdentifier.builder(TransportZones.class)
648 .child(TransportZone.class, new TransportZoneKey(transportZone))
649 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
650 deviceVtepKey).build();
651 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
652 //TO DO: add retry if it fails
653 t.delete(LogicalDatastoreType.CONFIGURATION, path);
655 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, node_id.get(1));
656 InstanceIdentifier<DeviceVteps> path2 =
657 InstanceIdentifier.builder(TransportZones.class)
658 .child(TransportZone.class, new TransportZoneKey(transportZone))
659 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
660 deviceVtepKey2).build();
661 //TO DO: add retry if it fails
662 t.delete(LogicalDatastoreType.CONFIGURATION, path2);
664 ListenableFuture<Void> futureCheck = t.submit();
665 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
668 public void onSuccess(Void aVoid) {
669 result.set(RpcResultBuilder.<Void>success().build());
673 public void onFailure(Throwable error) {
674 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
675 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp);
676 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
681 } catch (Exception e) {
682 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
683 withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
684 return Futures.immediateFuture(resultBuilder.build());
689 public Future<RpcResult<IsTunnelInternalOrExternalOutput>> isTunnelInternalOrExternal(
690 IsTunnelInternalOrExternalInput input) {
691 RpcResultBuilder<IsTunnelInternalOrExternalOutput> resultBld;
692 String tunIfName = input.getTunnelInterfaceName();
694 IsTunnelInternalOrExternalOutputBuilder output = new IsTunnelInternalOrExternalOutputBuilder().setTunnelType(tunVal);
696 if(ItmUtils.itmCache.getInternalTunnel(tunIfName) != null) {
698 } else if (ItmUtils.itmCache.getExternalTunnel(tunIfName) != null) {
701 output.setTunnelType(tunVal);
702 resultBld = RpcResultBuilder.success();
703 resultBld.withResult(output.build());
704 return Futures.immediateFuture(resultBld.build());
708 public Future<RpcResult<IsDcgwPresentOutput>> isDcgwPresent(IsDcgwPresentInput input) {
709 RpcResultBuilder<IsDcgwPresentOutput> resultBld = RpcResultBuilder.success();
711 List<DcGatewayIp> dcGatewayIpList = ItmUtils.getDcGatewayIpList(dataBroker);
712 String dcgwIpStr = input.getDcgwIp();
713 IpAddress dcgwIpAddr = new IpAddress(dcgwIpStr.toCharArray());
716 if((dcGatewayIpList != null) &&
717 (!dcGatewayIpList.isEmpty()) &&
718 (dcGatewayIpList.contains(dcgwIpAddr))) {
721 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
722 resultBld.withResult(output.build());
726 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
727 resultBld.withResult(output.build());
729 return Futures.immediateFuture(resultBld.build());