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 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 iMdsalApiManager) {
104 this.dataBroker = dataBroker;
105 this.idManagerService = idManagerService;
106 this.mdsalManager = iMdsalApiManager;
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())
132 InternalTunnel tunnel = tnl.get();
133 GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ;
134 List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
135 if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
136 output.setInterfaceName(tunnelInterfaces.get(0));
137 resultBld = RpcResultBuilder.success();
138 resultBld.withResult(output.build());
140 resultBld = RpcResultBuilder.failed();
144 resultBld = RpcResultBuilder.failed();
147 return Futures.immediateFuture(resultBld.build());
152 public Future<RpcResult<Void>> removeExternalTunnelEndpoint(
153 RemoveExternalTunnelEndpointInput input) {
154 //Ignore the Futures for now
155 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
156 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
157 ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService,meshedDpnList , input.getDestinationIp(), input.getTunnelType());
158 InstanceIdentifier<DcGatewayIp> extPath= InstanceIdentifier.builder(DcGatewayIpList.class).child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
159 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
160 t.delete(LogicalDatastoreType.CONFIGURATION, extPath);
161 ListenableFuture<Void> futureCheck = t.submit();
162 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
164 @Override public void onSuccess(Void aVoid) {
165 result.set(RpcResultBuilder.<Void>success().build());
168 @Override public void onFailure(Throwable error) {
170 "Unable to delete DcGatewayIp " + input.getDestinationIp() + " 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, input.getDestinationIp(), input.getTunnelType());
186 result.set(RpcResultBuilder.<Void>success().build());
191 public Future<RpcResult<Void>> buildExternalTunnelFromDpns(
192 BuildExternalTunnelFromDpnsInput input) {
193 //Ignore the Futures for now
194 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
195 List<ListenableFuture<Void>> extTunnelResultList = ItmExternalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, idManagerService,input.getDpnId(), input.getDestinationIp(), input.getTunnelType());
196 for (ListenableFuture<Void> extTunnelResult : extTunnelResultList) {
197 Futures.addCallback(extTunnelResult, new FutureCallback<Void>(){
200 public void onSuccess(Void aVoid) {
201 result.set(RpcResultBuilder.<Void>success().build());
205 public void onFailure(Throwable error) {
206 String msg = "Unable to create ext tunnel";
207 LOG.error("create ext tunnel failed. {}. {}", msg, error);
208 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
216 public Future<RpcResult<Void>> addExternalTunnelEndpoint(
217 AddExternalTunnelEndpointInput input) {
218 // TODO Auto-generated method stub
220 //Ignore the Futures for now
221 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
222 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
223 ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, idManagerService,meshedDpnList, input.getDestinationIp(), input.getTunnelType()) ;InstanceIdentifier<DcGatewayIp> extPath= InstanceIdentifier.builder(DcGatewayIpList.class).child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
224 DcGatewayIp dcGatewayIp = new DcGatewayIpBuilder().setIpAddress(input.getDestinationIp()).setTunnnelType(input.getTunnelType()).build();
225 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
226 t.put(LogicalDatastoreType.CONFIGURATION, extPath,dcGatewayIp, true);
227 ListenableFuture<Void> futureCheck = t.submit();
228 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
230 @Override public void onSuccess(Void aVoid) {
231 result.set(RpcResultBuilder.<Void>success().build());
234 @Override public void onFailure(Throwable error) {
236 "Unable to create DcGatewayIp {} in datastore for ip "+ input.getDestinationIp() + "and tunnel type " + input.getTunnelType();
238 result.set(RpcResultBuilder.<Void>failed()
239 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
246 public Future<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
247 GetExternalTunnelInterfaceNameInput input) {
248 SettableFuture.create();
249 RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
250 String sourceNode = input.getSourceNode();
251 String dstNode = input.getDestinationNode();
252 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
253 ExternalTunnelList.class)
254 .child(ExternalTunnel.class, new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType()));
256 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
258 if( ext != null && ext.isPresent())
260 ExternalTunnel exTunnel = ext.get();
261 GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ;
262 output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ;
263 resultBld = RpcResultBuilder.success();
264 resultBld.withResult(output.build()) ;
266 resultBld = RpcResultBuilder.failed();
269 return Futures.immediateFuture(resultBld.build());
273 public Future<RpcResult<java.lang.Void>> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
274 LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId() , input.getServiceId(), input.getInstruction());
275 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
276 int serviceId = input.getServiceId() ;
277 List<MatchInfo> mkMatches = getTunnelMatchesForServiceId(serviceId);
278 byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
280 byte Flags = (byte) 0x08;
281 vxLANHeader[0] = Flags;
283 // Extract the serviceId details and imprint on the VxLAN Header
284 vxLANHeader[4] = (byte) (serviceId >> 16);
285 vxLANHeader[5] = (byte) (serviceId >> 8);
286 vxLANHeader[6] = (byte) (serviceId >> 0);
289 // mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
290 // new BigInteger(1, vxLANHeader),
291 // MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID }));
293 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
294 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5, String.format("%s:%d","ITM Flow Entry ",serviceId),
295 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
297 ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
298 Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
301 public void onSuccess(Void aVoid) {
302 result.set(RpcResultBuilder.<Void>success().build());
306 public void onFailure(Throwable error) {
307 String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
308 LOG.error("create terminating service actions failed. {}. {}", msg, error);
309 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
312 // result.set(RpcResultBuilder.<Void>success().build());
317 public Future<RpcResult<java.lang.Void>> removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
318 LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}", input.getDpnId(), input.getServiceId());
319 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
320 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
321 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5, String.format("%s:%d","ITM Flow Entry ",input.getServiceId()),
322 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),getTunnelMatchesForServiceId(input.getServiceId()), null );
324 ListenableFuture<Void> installFlowResult = mdsalManager.removeFlow(input.getDpnId(), terminatingServiceTableFlow);
325 Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
328 public void onSuccess(Void aVoid) {
329 result.set(RpcResultBuilder.<Void>success().build());
333 public void onFailure(Throwable error) {
334 String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
335 LOG.error("remove terminating service actions failed. {}. {}", msg, error);
336 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
339 //result.set(RpcResultBuilder.<Void>success().build());
345 public List<MatchInfo> getTunnelMatchesForServiceId(int serviceId) {
346 List<MatchInfo> mkMatches = new ArrayList<>();
347 byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
350 byte Flags = (byte) 0x08;
351 vxLANHeader[0] = Flags;
353 // Extract the serviceId details and imprint on the VxLAN Header
354 vxLANHeader[4] = (byte) (serviceId >> 16);
355 vxLANHeader[5] = (byte) (serviceId >> 8);
356 vxLANHeader[6] = (byte) (serviceId >> 0);
359 mkMatches.add(new MatchTunnelId(BigInteger.valueOf(serviceId)));
364 private String getFlowRef(long termSvcTable, int svcId) {
365 return String.valueOf(termSvcTable) + svcId;
369 public Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
370 GetInternalOrExternalInterfaceNameInput input) {
371 RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = RpcResultBuilder.failed();
372 BigInteger srcDpn = input.getSourceDpid() ;
374 IpAddress dstIp = input.getDestinationIp() ;
375 InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(
376 ExternalTunnelList.class)
377 .child(ExternalTunnel.class, new ExternalTunnelKey(String.valueOf(dstIp), srcDpn.toString(), TunnelTypeMplsOverGre.class));
379 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
381 if( ext != null && ext.isPresent())
383 ExternalTunnel extTunnel = ext.get();
384 GetInternalOrExternalInterfaceNameOutputBuilder output = new GetInternalOrExternalInterfaceNameOutputBuilder().setInterfaceName(extTunnel.getTunnelInterfaceName() );
385 resultBld = RpcResultBuilder.success();
386 resultBld.withResult(output.build()) ;
388 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker);
389 if(meshedDpnList == null){
390 LOG.error("There are no tunnel mesh info in config DS");
391 return Futures.immediateFuture(resultBld.build());
393 // Look for external tunnels if not look for internal tunnel
394 for (DPNTEPsInfo teps : meshedDpnList) {
395 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
396 if (dstIp.equals(firstEndPt.getIpAddress())) {
397 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
399 .child(InternalTunnel.class, new InternalTunnelKey(teps.getDPNID(), srcDpn, input.getTunnelType()));
401 Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
402 if (tnl != null && tnl.isPresent()) {
403 InternalTunnel tunnel = tnl.get();
404 List<String> tunnelInterfaces = tunnel.getTunnelInterfaceNames();
405 if (tunnelInterfaces != null && !tunnelInterfaces.isEmpty()) {
406 GetInternalOrExternalInterfaceNameOutputBuilder
408 new GetInternalOrExternalInterfaceNameOutputBuilder()
409 .setInterfaceName(tunnelInterfaces.get(0));
410 resultBld = RpcResultBuilder.success();
411 resultBld.withResult(output.build());
413 LOG.error("No tunnel interface found between source DPN {} ans destination IP {}", srcDpn,
418 LOG.error("Tunnel not found for source DPN {} ans destination IP {}", srcDpn, dstIp);
423 return Futures.immediateFuture(resultBld.build());
427 public Future<RpcResult<java.lang.Void>> deleteL2GwDevice(DeleteL2GwDeviceInput input) {
428 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
429 boolean foundVxlanTzone = false;
431 final IpAddress hwIp = input.getIpAddress();
432 final String node_id = input.getNodeId();
433 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
434 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
435 if (tZonesOptional.isPresent()) {
436 TransportZones tZones = tZonesOptional.get();
437 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
438 LOG.error("No teps configured");
439 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
442 for (TransportZone tzone : tZones.getTransportZone()) {
443 if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class)))
445 foundVxlanTzone = true;
446 String transportZone = tzone.getZoneName();
447 if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
448 result.set(RpcResultBuilder.<Void>failed()
449 .withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
452 SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
453 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id);
454 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
455 .child(TransportZone.class, new TransportZoneKey(transportZone))
456 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
458 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
459 //TO DO: add retry if it fails
461 t.delete(LogicalDatastoreType.CONFIGURATION, path);
463 ListenableFuture<Void> futureCheck = t.submit();
464 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
466 @Override public void onSuccess(Void aVoid) {
467 result.set(RpcResultBuilder.<Void>success().build());
470 @Override public void onFailure(Throwable error) {
471 String msg = String.format("Unable to delete HwVtep {} from datastore", node_id);
472 LOG.error("Unable to delete HwVtep {}, {} from datastore", node_id, hwIp);
473 result.set(RpcResultBuilder.<Void>failed()
474 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
481 result.set(RpcResultBuilder.<Void>failed()
482 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
486 if (!foundVxlanTzone) {
487 result.set(RpcResultBuilder.<Void>failed()
488 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
493 } catch (Exception e) {
494 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
495 withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
496 return Futures.immediateFuture(resultBuilder.build());
501 public Future<RpcResult<java.lang.Void>> addL2GwDevice(AddL2GwDeviceInput input) {
503 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
504 boolean foundVxlanTzone = false;
506 final IpAddress hwIp = input.getIpAddress();
507 final String node_id = input.getNodeId();
508 //iterate through all transport zones and put TORs under vxlan
509 //if no vxlan tzone is cnfigured, return an error.
510 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
511 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath,
513 if (tZonesOptional.isPresent()) {
514 TransportZones tZones = tZonesOptional.get();
515 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
516 LOG.error("No transportZone configured");
517 result.set(RpcResultBuilder.<Void>failed()
518 .withError(RpcError.ErrorType.APPLICATION, "No transportZone Configured").build());
521 for (TransportZone tzone : tZones.getTransportZone()) {
522 if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class)))
524 String transportZone = tzone.getZoneName();
525 if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
528 foundVxlanTzone = true;
529 SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
530 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id);
531 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
532 .child(TransportZone.class, new TransportZoneKey(transportZone))
533 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
535 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp)
536 .setNodeId(node_id).setTopologyId(input.getTopologyId()).build();
537 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
538 //TO DO: add retry if it fails
539 t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
541 ListenableFuture<Void> futureCheck = t.submit();
542 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
544 @Override public void onSuccess(Void aVoid) {
545 result.set(RpcResultBuilder.<Void>success().build());
548 @Override public void onFailure(Throwable error) {
549 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
550 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id, hwIp);
551 result.set(RpcResultBuilder.<Void>failed()
552 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
559 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
563 if (!foundVxlanTzone) {
564 result.set(RpcResultBuilder.<Void>failed()
565 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
570 } catch (Exception e) {
571 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
572 withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
573 return Futures.immediateFuture(resultBuilder.build());
578 public Future<RpcResult<java.lang.Void>> addL2GwMlagDevice(AddL2GwMlagDeviceInput input)
581 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
583 final IpAddress hwIp = input.getIpAddress();
584 final List<String> node_id = input.getNodeId();
585 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
586 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
587 if (tZonesOptional.isPresent()) {
588 TransportZones tZones = tZonesOptional.get();
589 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
590 LOG.error("No teps configured");
591 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
594 String transportZone = tZones.getTransportZone().get(0).getZoneName();
595 if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) {
596 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
599 SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey();
600 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id.get(0));
601 InstanceIdentifier<DeviceVteps> path =
602 InstanceIdentifier.builder(TransportZones.class)
603 .child(TransportZone.class, new TransportZoneKey(transportZone))
604 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build();
605 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp).setNodeId(node_id.get(0)).setTopologyId(input.getTopologyId()).build();
606 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
607 //TO DO: add retry if it fails
608 LOG.trace("writing hWvtep{}",deviceVtep);
609 t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
611 if(node_id.size() == 2) {
612 LOG.trace("second node-id {}",node_id.get(1));
613 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, node_id.get(1));
614 InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier.builder(TransportZones.class)
615 .child(TransportZone.class, new TransportZoneKey(transportZone))
616 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey2).build();
617 DeviceVteps deviceVtep2 = new DeviceVtepsBuilder().setKey(deviceVtepKey2).setIpAddress(hwIp).setNodeId(node_id.get(1))
618 .setTopologyId(input.getTopologyId()).build();
619 //TO DO: add retry if it fails
620 LOG.trace("writing {}",deviceVtep2);
621 t.put(LogicalDatastoreType.CONFIGURATION, path2, deviceVtep2, true);
622 }ListenableFuture<Void> futureCheck = t.submit();
623 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
626 public void onSuccess(Void aVoid) {
627 result.set(RpcResultBuilder.<Void>success().build());
631 public void onFailure(Throwable error) {
632 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
633 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp);
634 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
639 } catch (Exception e) {
640 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
641 withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
642 return Futures.immediateFuture(resultBuilder.build());
646 public Future<RpcResult<Void>> deleteL2GwMlagDevice(DeleteL2GwMlagDeviceInput input) {
648 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
650 final IpAddress hwIp = input.getIpAddress();
651 final List<String> node_id = input.getNodeId();
652 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
653 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
654 if (tZonesOptional.isPresent()) {
655 TransportZones tZones = tZonesOptional.get();
656 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
657 LOG.error("No teps configured");
658 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
661 String transportZone = tZones.getTransportZone().get(0).getZoneName();
662 if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) {
663 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
666 SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey();
667 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id.get(0));
668 InstanceIdentifier<DeviceVteps> path =
669 InstanceIdentifier.builder(TransportZones.class)
670 .child(TransportZone.class, new TransportZoneKey(transportZone))
671 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
672 deviceVtepKey).build();
673 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
674 //TO DO: add retry if it fails
675 t.delete(LogicalDatastoreType.CONFIGURATION, path);
677 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, node_id.get(1));
678 InstanceIdentifier<DeviceVteps> path2 =
679 InstanceIdentifier.builder(TransportZones.class)
680 .child(TransportZone.class, new TransportZoneKey(transportZone))
681 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
682 deviceVtepKey2).build();
683 //TO DO: add retry if it fails
684 t.delete(LogicalDatastoreType.CONFIGURATION, path2);
686 ListenableFuture<Void> futureCheck = t.submit();
687 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
690 public void onSuccess(Void aVoid) {
691 result.set(RpcResultBuilder.<Void>success().build());
695 public void onFailure(Throwable error) {
696 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
697 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp);
698 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
703 } catch (Exception e) {
704 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
705 withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
706 return Futures.immediateFuture(resultBuilder.build());
711 public Future<RpcResult<IsTunnelInternalOrExternalOutput>> isTunnelInternalOrExternal(
712 IsTunnelInternalOrExternalInput input) {
713 RpcResultBuilder<IsTunnelInternalOrExternalOutput> resultBld;
714 String tunIfName = input.getTunnelInterfaceName();
716 IsTunnelInternalOrExternalOutputBuilder output = new IsTunnelInternalOrExternalOutputBuilder().setTunnelType(tunVal);
718 if(ItmUtils.itmCache.getInternalTunnel(tunIfName) != null) {
720 } else if (ItmUtils.itmCache.getExternalTunnel(tunIfName) != null) {
723 output.setTunnelType(tunVal);
724 resultBld = RpcResultBuilder.success();
725 resultBld.withResult(output.build());
726 return Futures.immediateFuture(resultBld.build());
730 public Future<RpcResult<IsDcgwPresentOutput>> isDcgwPresent(IsDcgwPresentInput input) {
731 RpcResultBuilder<IsDcgwPresentOutput> resultBld = RpcResultBuilder.success();
733 List<DcGatewayIp> dcGatewayIpList = ItmUtils.getDcGatewayIpList(dataBroker);
734 String dcgwIpStr = input.getDcgwIp();
735 IpAddress dcgwIpAddr = new IpAddress(dcgwIpStr.toCharArray());
738 if((dcGatewayIpList != null) &&
739 (!dcGatewayIpList.isEmpty()) &&
740 (dcGatewayIpList.contains(dcgwIpAddr))) {
743 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
744 resultBld.withResult(output.build());
748 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
749 resultBld.withResult(output.build());
751 return Futures.immediateFuture(resultBld.build());