2 * Copyright (c) 2016, 2017 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 javax.annotation.PostConstruct;
20 import javax.annotation.PreDestroy;
21 import javax.inject.Inject;
22 import javax.inject.Singleton;
23 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelAddWorker;
27 import org.opendaylight.genius.itm.confighelpers.ItmExternalTunnelDeleteWorker;
28 import org.opendaylight.genius.itm.globals.ITMConstants;
29 import org.opendaylight.genius.itm.impl.ItmUtils;
30 import org.opendaylight.genius.mdsalutil.MDSALUtil;
31 import org.opendaylight.genius.mdsalutil.MatchInfo;
32 import org.opendaylight.genius.mdsalutil.NwConstants;
33 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
34 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeMplsOverGre;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnelKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIpKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Subnets;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.SubnetsKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVteps;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVtepsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.subnets.DeviceVtepsKey;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddExternalTunnelEndpointInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwDeviceInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.AddL2GwMlagDeviceInput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.BuildExternalTunnelFromDpnsInput;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.CreateTerminatingServiceActionsInput;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwDeviceInput;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.DeleteL2GwMlagDeviceInput;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameInput;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetExternalTunnelInterfaceNameOutputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameInput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutput;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetInternalOrExternalInterfaceNameOutputBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameInput;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutput;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.GetTunnelInterfaceNameOutputBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentInput;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsDcgwPresentOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalInput;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.IsTunnelInternalOrExternalOutputBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelEndpointInput;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveExternalTunnelFromDpnsInput;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.RemoveTerminatingServiceActionsInput;
86 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
87 import org.opendaylight.yangtools.yang.common.RpcError;
88 import org.opendaylight.yangtools.yang.common.RpcResult;
89 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
90 import org.slf4j.Logger;
91 import org.slf4j.LoggerFactory;
94 public class ItmManagerRpcService implements ItmRpcService {
96 private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class);
97 private final DataBroker dataBroker;
98 private final IMdsalApiManager mdsalManager;
99 private final IdManagerService idManagerService;
102 public ItmManagerRpcService(final DataBroker dataBroker,final IdManagerService idManagerService,
103 final IMdsalApiManager mdsalManager) {
104 this.dataBroker = dataBroker;
105 this.idManagerService = idManagerService;
106 this.mdsalManager = mdsalManager;
110 public void start() {
111 LOG.info("ItmManagerRpcService Started");
115 public void close() {
116 LOG.info("ItmManagerRpcService Closed");
120 public Future<RpcResult<GetTunnelInterfaceNameOutput>> getTunnelInterfaceName(GetTunnelInterfaceNameInput input) {
121 RpcResultBuilder<GetTunnelInterfaceNameOutput> resultBld = null;
122 BigInteger sourceDpn = input.getSourceDpid() ;
123 BigInteger destinationDpn = input.getDestinationDpid() ;
124 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
126 .child(InternalTunnel.class, new InternalTunnelKey(destinationDpn, sourceDpn, input.getTunnelType()));
128 Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
130 if (tnl != null && tnl.isPresent()) {
131 InternalTunnel tunnel = tnl.get();
132 GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ;
133 List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
134 if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
135 output.setInterfaceName(tunnelInterfaces.get(0));
136 resultBld = RpcResultBuilder.success();
137 resultBld.withResult(output.build());
139 resultBld = RpcResultBuilder.failed();
143 resultBld = RpcResultBuilder.failed();
145 return Futures.immediateFuture(resultBld.build());
150 public Future<RpcResult<Void>> removeExternalTunnelEndpoint(
151 RemoveExternalTunnelEndpointInput input) {
152 //Ignore the Futures for now
153 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
154 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
155 ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService,meshedDpnList,
156 input.getDestinationIp(), input.getTunnelType());
157 InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
158 .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
159 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
160 transaction.delete(LogicalDatastoreType.CONFIGURATION, extPath);
161 ListenableFuture<Void> futureCheck = transaction.submit();
162 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
164 @Override public void onSuccess(Void voidInstance) {
165 result.set(RpcResultBuilder.<Void>success().build());
168 @Override public void onFailure(Throwable error) {
169 String msg = "Unable to delete DcGatewayIp " + input.getDestinationIp()
170 + " in datastore and tunnel type " + input.getTunnelType();
172 result.set(RpcResultBuilder.<Void>failed()
173 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
180 public Future<RpcResult<Void>> removeExternalTunnelFromDpns(
181 RemoveExternalTunnelFromDpnsInput input) {
182 //Ignore the Futures for now
183 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
184 List<DPNTEPsInfo> cfgDpnList = ItmUtils.getDpnTepListFromDpnId(dataBroker, input.getDpnId()) ;
185 ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService, cfgDpnList,
186 input.getDestinationIp(), input.getTunnelType());
187 result.set(RpcResultBuilder.<Void>success().build());
192 public Future<RpcResult<Void>> buildExternalTunnelFromDpns(
193 BuildExternalTunnelFromDpnsInput input) {
194 //Ignore the Futures for now
195 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
196 List<ListenableFuture<Void>> extTunnelResultList = ItmExternalTunnelAddWorker
197 .buildTunnelsFromDpnToExternalEndPoint(dataBroker, idManagerService,input.getDpnId(),
198 input.getDestinationIp(), input.getTunnelType());
199 for (ListenableFuture<Void> extTunnelResult : extTunnelResultList) {
200 Futures.addCallback(extTunnelResult, new FutureCallback<Void>() {
203 public void onSuccess(Void voidInstance) {
204 result.set(RpcResultBuilder.<Void>success().build());
208 public void onFailure(Throwable error) {
209 String msg = "Unable to create ext tunnel";
210 LOG.error("create ext tunnel failed. {}. {}", msg, error);
211 result.set(RpcResultBuilder.<Void>failed()
212 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
220 public Future<RpcResult<Void>> addExternalTunnelEndpoint(
221 AddExternalTunnelEndpointInput input) {
222 // TODO Auto-generated method stub
224 //Ignore the Futures for now
225 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
226 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
227 ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, idManagerService,meshedDpnList,
228 input.getDestinationIp(), input.getTunnelType()) ;
229 InstanceIdentifier<DcGatewayIp> extPath = InstanceIdentifier.builder(DcGatewayIpList.class)
230 .child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
231 DcGatewayIp dcGatewayIp =
232 new DcGatewayIpBuilder().setIpAddress(input.getDestinationIp())
233 .setTunnnelType(input.getTunnelType()).build();
234 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
235 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, extPath,dcGatewayIp, true);
236 ListenableFuture<Void> futureCheck = writeTransaction.submit();
237 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
239 @Override public void onSuccess(Void voidInstance) {
240 result.set(RpcResultBuilder.<Void>success().build());
243 @Override public void onFailure(Throwable error) {
245 "Unable to create DcGatewayIp {} in datastore for ip " + input.getDestinationIp() + "and "
246 + "tunnel type " + input.getTunnelType();
248 result.set(RpcResultBuilder.<Void>failed()
249 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
256 public Future<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
257 GetExternalTunnelInterfaceNameInput input) {
258 SettableFuture.create();
259 RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
260 String sourceNode = input.getSourceNode();
261 String dstNode = input.getDestinationNode();
262 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
263 ExternalTunnelList.class)
264 .child(ExternalTunnel.class, new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType()));
266 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
268 if (ext != null && ext.isPresent()) {
269 ExternalTunnel exTunnel = ext.get();
270 GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ;
271 output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ;
272 resultBld = RpcResultBuilder.success();
273 resultBld.withResult(output.build()) ;
275 resultBld = RpcResultBuilder.failed();
278 return Futures.immediateFuture(resultBld.build());
282 public Future<RpcResult<java.lang.Void>>
283 createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
284 LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}",
285 input.getDpnId() , input.getServiceId(), input.getInstruction());
286 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
287 int serviceId = input.getServiceId() ;
288 final List<MatchInfo> mkMatches = getTunnelMatchesForServiceId(serviceId);
289 byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
291 byte flags = (byte) 0x08;
292 vxLANHeader[0] = flags;
294 // Extract the serviceId details and imprint on the VxLAN Header
295 vxLANHeader[4] = (byte) (serviceId >> 16);
296 vxLANHeader[5] = (byte) (serviceId >> 8);
297 vxLANHeader[6] = (byte) (serviceId >> 0);
299 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
300 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5,
301 String.format("%s:%d","ITM Flow Entry ",serviceId), 0, 0,
302 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
304 ListenableFuture<Void> installFlowResult =
305 mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
306 Futures.addCallback(installFlowResult, new FutureCallback<Void>() {
309 public void onSuccess(Void voidInstance) {
310 result.set(RpcResultBuilder.<Void>success().build());
314 public void onFailure(Throwable error) {
315 String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
316 LOG.error("create terminating service actions failed. {}. {}", msg, error);
317 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error)
321 // result.set(RpcResultBuilder.<Void>success().build());
326 public Future<RpcResult<java.lang.Void>>
327 removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
328 LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}",
329 input.getDpnId(), input.getServiceId());
330 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
331 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
332 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5,
333 String.format("%s:%d","ITM Flow Entry ",input.getServiceId()), 0, 0,
334 ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),
335 getTunnelMatchesForServiceId(input.getServiceId()), null);
337 ListenableFuture<Void> installFlowResult =
338 mdsalManager.removeFlow(input.getDpnId(), terminatingServiceTableFlow);
339 Futures.addCallback(installFlowResult, new FutureCallback<Void>() {
342 public void onSuccess(Void voidInstance) {
343 result.set(RpcResultBuilder.<Void>success().build());
347 public void onFailure(Throwable error) {
348 String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
349 LOG.error("remove terminating service actions failed. {}. {}", msg, error);
350 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error)
354 //result.set(RpcResultBuilder.<Void>success().build());
360 public List<MatchInfo> getTunnelMatchesForServiceId(int serviceId) {
361 final List<MatchInfo> mkMatches = new ArrayList<>();
362 byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
365 byte flag = (byte) 0x08;
366 vxLANHeader[0] = flag;
368 // Extract the serviceId details and imprint on the VxLAN Header
369 vxLANHeader[4] = (byte) (serviceId >> 16);
370 vxLANHeader[5] = (byte) (serviceId >> 8);
371 vxLANHeader[6] = (byte) (serviceId >> 0);
374 mkMatches.add(new MatchTunnelId(BigInteger.valueOf(serviceId)));
379 private String getFlowRef(long termSvcTable, int svcId) {
380 return String.valueOf(termSvcTable) + svcId;
384 public Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
385 GetInternalOrExternalInterfaceNameInput input) {
386 RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = RpcResultBuilder.failed();
387 BigInteger srcDpn = input.getSourceDpid() ;
389 IpAddress dstIp = input.getDestinationIp() ;
390 InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(ExternalTunnelList.class)
391 .child(ExternalTunnel.class,
392 new ExternalTunnelKey(String.valueOf(dstIp), srcDpn.toString(), TunnelTypeMplsOverGre.class));
394 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
396 if (ext != null && ext.isPresent()) {
397 ExternalTunnel extTunnel = ext.get();
398 GetInternalOrExternalInterfaceNameOutputBuilder output =
399 new GetInternalOrExternalInterfaceNameOutputBuilder()
400 .setInterfaceName(extTunnel.getTunnelInterfaceName());
401 resultBld = RpcResultBuilder.success();
402 resultBld.withResult(output.build()) ;
404 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker);
405 if (meshedDpnList == null) {
406 LOG.error("There are no tunnel mesh info in config DS");
407 return Futures.immediateFuture(resultBld.build());
409 // Look for external tunnels if not look for internal tunnel
410 for (DPNTEPsInfo teps : meshedDpnList) {
411 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
412 if (dstIp.equals(firstEndPt.getIpAddress())) {
413 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(TunnelList.class)
414 .child(InternalTunnel.class,
415 new InternalTunnelKey(teps.getDPNID(), srcDpn, input.getTunnelType()));
417 Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
418 if (tnl != null && tnl.isPresent()) {
419 InternalTunnel tunnel = tnl.get();
420 List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
421 if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
422 GetInternalOrExternalInterfaceNameOutputBuilder
424 new GetInternalOrExternalInterfaceNameOutputBuilder()
425 .setInterfaceName(tunnelInterfaces.get(0));
426 resultBld = RpcResultBuilder.success();
427 resultBld.withResult(output.build());
429 LOG.error("No tunnel interface found between source DPN {} ans destination IP {}", srcDpn,
434 LOG.error("Tunnel not found for source DPN {} ans destination IP {}", srcDpn, dstIp);
439 return Futures.immediateFuture(resultBld.build());
442 @SuppressWarnings("checkstyle:IllegalCatch")
444 public Future<RpcResult<java.lang.Void>> deleteL2GwDevice(DeleteL2GwDeviceInput input) {
445 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
446 boolean foundVxlanTzone = false;
448 final IpAddress hwIp = input.getIpAddress();
449 final String nodeId = input.getNodeId();
450 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
451 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
452 containerPath, dataBroker);
453 if (transportZonesOptional.isPresent()) {
454 TransportZones transportZones = transportZonesOptional.get();
455 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
456 LOG.error("No teps configured");
457 result.set(RpcResultBuilder.<Void>failed()
458 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
461 for (TransportZone tzone : transportZones.getTransportZone()) {
462 if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class))) {
465 foundVxlanTzone = true;
466 String transportZone = tzone.getZoneName();
467 if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
468 result.set(RpcResultBuilder.<Void>failed()
469 .withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
472 SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
473 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId);
474 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
475 .child(TransportZone.class, new TransportZoneKey(transportZone))
476 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
478 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
479 //TO DO: add retry if it fails
481 transaction.delete(LogicalDatastoreType.CONFIGURATION, path);
483 ListenableFuture<Void> futureCheck = transaction.submit();
484 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
486 @Override public void onSuccess(Void voidInstance) {
487 result.set(RpcResultBuilder.<Void>success().build());
490 @Override public void onFailure(Throwable error) {
491 String msg = String.format("Unable to delete HwVtep %s from datastore", nodeId);
492 LOG.error("Unable to delete HwVtep {}, {} from datastore", nodeId, hwIp);
493 result.set(RpcResultBuilder.<Void>failed()
494 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
500 result.set(RpcResultBuilder.<Void>failed()
501 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
505 if (!foundVxlanTzone) {
506 result.set(RpcResultBuilder.<Void>failed()
507 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
512 } catch (Exception e) {
513 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed()
514 .withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
515 return Futures.immediateFuture(resultBuilder.build());
519 @SuppressWarnings("checkstyle:IllegalCatch")
521 public Future<RpcResult<java.lang.Void>> addL2GwDevice(AddL2GwDeviceInput input) {
523 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
524 boolean foundVxlanTzone = false;
526 final IpAddress hwIp = input.getIpAddress();
527 final String nodeId = input.getNodeId();
528 //iterate through all transport zones and put TORs under vxlan
529 //if no vxlan tzone is cnfigured, return an error.
530 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
531 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
532 containerPath, dataBroker);
533 if (transportZonesOptional.isPresent()) {
534 TransportZones transportZones = transportZonesOptional.get();
535 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
536 LOG.error("No transportZone configured");
537 result.set(RpcResultBuilder.<Void>failed()
538 .withError(RpcError.ErrorType.APPLICATION, "No transportZone Configured").build());
541 for (TransportZone tzone : transportZones.getTransportZone()) {
542 if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class))) {
545 String transportZone = tzone.getZoneName();
546 if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
549 foundVxlanTzone = true;
550 SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
551 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId);
552 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
553 .child(TransportZone.class, new TransportZoneKey(transportZone))
554 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
556 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp)
557 .setNodeId(nodeId).setTopologyId(input.getTopologyId()).build();
558 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
559 //TO DO: add retry if it fails
560 transaction.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
562 ListenableFuture<Void> futureCheck = transaction.submit();
563 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
565 @Override public void onSuccess(Void voidInstance) {
566 result.set(RpcResultBuilder.<Void>success().build());
569 @Override public void onFailure(Throwable error) {
570 String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
571 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId, hwIp);
572 result.set(RpcResultBuilder.<Void>failed()
573 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
579 result.set(RpcResultBuilder.<Void>failed()
580 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
584 if (!foundVxlanTzone) {
585 result.set(RpcResultBuilder.<Void>failed()
586 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
591 } catch (Exception e) {
592 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed()
593 .withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
594 return Futures.immediateFuture(resultBuilder.build());
598 @SuppressWarnings("checkstyle:IllegalCatch")
600 public Future<RpcResult<java.lang.Void>> addL2GwMlagDevice(AddL2GwMlagDeviceInput input) {
602 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
604 final IpAddress hwIp = input.getIpAddress();
605 final List<String> nodeId = input.getNodeId();
606 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
607 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
608 containerPath, dataBroker);
609 if (transportZonesOptional.isPresent()) {
610 TransportZones transportZones = transportZonesOptional.get();
611 if (transportZones.getTransportZone() == null || transportZones.getTransportZone().isEmpty()) {
612 LOG.error("No teps configured");
613 result.set(RpcResultBuilder.<Void>failed()
614 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
617 String transportZone = transportZones.getTransportZone().get(0).getZoneName();
618 if (transportZones.getTransportZone().get(0).getSubnets() == null
619 || transportZones.getTransportZone().get(0).getSubnets().isEmpty()) {
620 result.set(RpcResultBuilder.<Void>failed()
621 .withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
624 SubnetsKey subnetsKey = transportZones.getTransportZone().get(0).getSubnets().get(0).getKey();
625 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
626 InstanceIdentifier<DeviceVteps> path =
627 InstanceIdentifier.builder(TransportZones.class)
628 .child(TransportZone.class, new TransportZoneKey(transportZone))
629 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build();
630 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp)
631 .setNodeId(nodeId.get(0)).setTopologyId(input.getTopologyId()).build();
632 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
633 //TO DO: add retry if it fails
634 LOG.trace("writing hWvtep{}",deviceVtep);
635 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
637 if (nodeId.size() == 2) {
638 LOG.trace("second node-id {}",nodeId.get(1));
639 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
640 InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier.builder(TransportZones.class)
641 .child(TransportZone.class, new TransportZoneKey(transportZone))
642 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey2).build();
643 DeviceVteps deviceVtep2 = new DeviceVtepsBuilder().setKey(deviceVtepKey2).setIpAddress(hwIp)
644 .setNodeId(nodeId.get(1))
645 .setTopologyId(input.getTopologyId()).build();
646 //TO DO: add retry if it fails
647 LOG.trace("writing {}",deviceVtep2);
648 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, path2, deviceVtep2, true);
650 ListenableFuture<Void> futureCheck = writeTransaction.submit();
651 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
654 public void onSuccess(Void voidInstance) {
655 result.set(RpcResultBuilder.<Void>success().build());
659 public void onFailure(Throwable error) {
660 String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
661 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId , hwIp);
662 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error)
668 } catch (Exception e) {
669 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed()
670 .withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
671 return Futures.immediateFuture(resultBuilder.build());
675 @SuppressWarnings("checkstyle:IllegalCatch")
677 public Future<RpcResult<Void>> deleteL2GwMlagDevice(DeleteL2GwMlagDeviceInput input) {
679 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
681 final IpAddress hwIp = input.getIpAddress();
682 final List<String> nodeId = input.getNodeId();
683 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
684 Optional<TransportZones> transportZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
685 containerPath, dataBroker);
686 if (transportZonesOptional.isPresent()) {
687 TransportZones tzones = transportZonesOptional.get();
688 if (tzones.getTransportZone() == null || tzones.getTransportZone().isEmpty()) {
689 LOG.error("No teps configured");
690 result.set(RpcResultBuilder.<Void>failed()
691 .withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
694 String transportZone = tzones.getTransportZone().get(0).getZoneName();
695 if (tzones.getTransportZone().get(0).getSubnets() == null || tzones.getTransportZone()
696 .get(0).getSubnets().isEmpty()) {
697 result.set(RpcResultBuilder.<Void>failed()
698 .withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
701 SubnetsKey subnetsKey = tzones.getTransportZone().get(0).getSubnets().get(0).getKey();
702 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, nodeId.get(0));
703 InstanceIdentifier<DeviceVteps> path =
704 InstanceIdentifier.builder(TransportZones.class)
705 .child(TransportZone.class, new TransportZoneKey(transportZone))
706 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
707 deviceVtepKey).build();
708 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
709 //TO DO: add retry if it fails
710 transaction.delete(LogicalDatastoreType.CONFIGURATION, path);
712 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, nodeId.get(1));
713 InstanceIdentifier<DeviceVteps> path2 =
714 InstanceIdentifier.builder(TransportZones.class)
715 .child(TransportZone.class, new TransportZoneKey(transportZone))
716 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
717 deviceVtepKey2).build();
718 //TO DO: add retry if it fails
719 transaction.delete(LogicalDatastoreType.CONFIGURATION, path2);
721 ListenableFuture<Void> futureCheck = transaction.submit();
722 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
725 public void onSuccess(Void voidInstance) {
726 result.set(RpcResultBuilder.<Void>success().build());
730 public void onFailure(Throwable error) {
731 String msg = String.format("Unable to write HwVtep %s to datastore", nodeId);
732 LOG.error("Unable to write HwVtep {}, {} to datastore", nodeId , hwIp);
733 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error)
739 } catch (Exception e) {
740 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed()
741 .withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
742 return Futures.immediateFuture(resultBuilder.build());
747 public Future<RpcResult<IsTunnelInternalOrExternalOutput>> isTunnelInternalOrExternal(
748 IsTunnelInternalOrExternalInput input) {
749 RpcResultBuilder<IsTunnelInternalOrExternalOutput> resultBld;
750 String tunIfName = input.getTunnelInterfaceName();
752 IsTunnelInternalOrExternalOutputBuilder output = new IsTunnelInternalOrExternalOutputBuilder()
753 .setTunnelType(tunVal);
755 if (ItmUtils.itmCache.getInternalTunnel(tunIfName) != null) {
757 } else if (ItmUtils.itmCache.getExternalTunnel(tunIfName) != null) {
760 output.setTunnelType(tunVal);
761 resultBld = RpcResultBuilder.success();
762 resultBld.withResult(output.build());
763 return Futures.immediateFuture(resultBld.build());
767 public Future<RpcResult<IsDcgwPresentOutput>> isDcgwPresent(IsDcgwPresentInput input) {
768 RpcResultBuilder<IsDcgwPresentOutput> resultBld = RpcResultBuilder.success();
770 List<DcGatewayIp> dcGatewayIpList = ItmUtils.getDcGatewayIpList(dataBroker);
771 String dcgwIpStr = input.getDcgwIp();
772 IpAddress dcgwIpAddr = new IpAddress(dcgwIpStr.toCharArray());
775 if ((dcGatewayIpList != null)
776 && (!dcGatewayIpList.isEmpty())
777 && (dcGatewayIpList.contains(dcgwIpAddr))) {
780 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
781 resultBld.withResult(output.build());
785 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
786 resultBld.withResult(output.build());
788 return Futures.immediateFuture(resultBld.build());