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 output.setInterfaceName(tunnel.getTunnelInterfaceName()) ;
135 resultBld = RpcResultBuilder.success();
136 resultBld.withResult(output.build()) ;
138 resultBld = RpcResultBuilder.failed();
141 return Futures.immediateFuture(resultBld.build());
146 public Future<RpcResult<Void>> removeExternalTunnelEndpoint(
147 RemoveExternalTunnelEndpointInput input) {
148 //Ignore the Futures for now
149 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
150 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
151 ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService,meshedDpnList , input.getDestinationIp(), input.getTunnelType());
152 InstanceIdentifier<DcGatewayIp> extPath= InstanceIdentifier.builder(DcGatewayIpList.class).child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
153 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
154 t.delete(LogicalDatastoreType.CONFIGURATION, extPath);
155 ListenableFuture<Void> futureCheck = t.submit();
156 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
158 @Override public void onSuccess(Void aVoid) {
159 result.set(RpcResultBuilder.<Void>success().build());
162 @Override public void onFailure(Throwable error) {
164 "Unable to delete DcGatewayIp " + input.getDestinationIp() + " in datastore and tunnel type " + input.getTunnelType();
166 result.set(RpcResultBuilder.<Void>failed()
167 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
174 public Future<RpcResult<Void>> removeExternalTunnelFromDpns(
175 RemoveExternalTunnelFromDpnsInput input) {
176 //Ignore the Futures for now
177 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
178 List<DPNTEPsInfo> cfgDpnList = ItmUtils.getDPNTEPListFromDPNId(dataBroker, input.getDpnId()) ;
179 ItmExternalTunnelDeleteWorker.deleteTunnels(dataBroker, idManagerService, cfgDpnList, input.getDestinationIp(), input.getTunnelType());
180 result.set(RpcResultBuilder.<Void>success().build());
185 public Future<RpcResult<Void>> buildExternalTunnelFromDpns(
186 BuildExternalTunnelFromDpnsInput input) {
187 //Ignore the Futures for now
188 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
189 List<ListenableFuture<Void>> extTunnelResultList = ItmExternalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, idManagerService,input.getDpnId(), input.getDestinationIp(), input.getTunnelType());
190 for (ListenableFuture<Void> extTunnelResult : extTunnelResultList) {
191 Futures.addCallback(extTunnelResult, new FutureCallback<Void>(){
194 public void onSuccess(Void aVoid) {
195 result.set(RpcResultBuilder.<Void>success().build());
199 public void onFailure(Throwable error) {
200 String msg = "Unable to create ext tunnel";
201 LOG.error("create ext tunnel failed. {}. {}", msg, error);
202 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
210 public Future<RpcResult<Void>> addExternalTunnelEndpoint(
211 AddExternalTunnelEndpointInput input) {
212 // TODO Auto-generated method stub
214 //Ignore the Futures for now
215 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
216 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
217 ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, idManagerService,meshedDpnList, input.getDestinationIp(), input.getTunnelType()) ;InstanceIdentifier<DcGatewayIp> extPath= InstanceIdentifier.builder(DcGatewayIpList.class).child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
218 DcGatewayIp dcGatewayIp = new DcGatewayIpBuilder().setIpAddress(input.getDestinationIp()).setTunnnelType(input.getTunnelType()).build();
219 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
220 t.put(LogicalDatastoreType.CONFIGURATION, extPath,dcGatewayIp, true);
221 ListenableFuture<Void> futureCheck = t.submit();
222 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
224 @Override public void onSuccess(Void aVoid) {
225 result.set(RpcResultBuilder.<Void>success().build());
228 @Override public void onFailure(Throwable error) {
230 "Unable to create DcGatewayIp {} in datastore for ip "+ input.getDestinationIp() + "and tunnel type " + input.getTunnelType();
232 result.set(RpcResultBuilder.<Void>failed()
233 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
240 public Future<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
241 GetExternalTunnelInterfaceNameInput input) {
242 SettableFuture.create();
243 RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
244 String sourceNode = input.getSourceNode();
245 String dstNode = input.getDestinationNode();
246 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
247 ExternalTunnelList.class)
248 .child(ExternalTunnel.class, new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType()));
250 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
252 if( ext != null && ext.isPresent())
254 ExternalTunnel exTunnel = ext.get();
255 GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ;
256 output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ;
257 resultBld = RpcResultBuilder.success();
258 resultBld.withResult(output.build()) ;
260 resultBld = RpcResultBuilder.failed();
263 return Futures.immediateFuture(resultBld.build());
267 public Future<RpcResult<java.lang.Void>> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
268 LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId() , input.getServiceId(), input.getInstruction());
269 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
270 int serviceId = input.getServiceId() ;
271 List<MatchInfo> mkMatches = getTunnelMatchesForServiceId(serviceId);
272 byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
274 byte Flags = (byte) 0x08;
275 vxLANHeader[0] = Flags;
277 // Extract the serviceId details and imprint on the VxLAN Header
278 vxLANHeader[4] = (byte) (serviceId >> 16);
279 vxLANHeader[5] = (byte) (serviceId >> 8);
280 vxLANHeader[6] = (byte) (serviceId >> 0);
283 // mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
284 // new BigInteger(1, vxLANHeader),
285 // MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID }));
287 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
288 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5, String.format("%s:%d","ITM Flow Entry ",serviceId),
289 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
291 ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
292 Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
295 public void onSuccess(Void aVoid) {
296 result.set(RpcResultBuilder.<Void>success().build());
300 public void onFailure(Throwable error) {
301 String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
302 LOG.error("create terminating service actions failed. {}. {}", msg, error);
303 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
306 // result.set(RpcResultBuilder.<Void>success().build());
311 public Future<RpcResult<java.lang.Void>> removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
312 LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}", input.getDpnId(), input.getServiceId());
313 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
314 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
315 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5, String.format("%s:%d","ITM Flow Entry ",input.getServiceId()),
316 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),getTunnelMatchesForServiceId(input.getServiceId()), null );
318 ListenableFuture<Void> installFlowResult = mdsalManager.removeFlow(input.getDpnId(), terminatingServiceTableFlow);
319 Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
322 public void onSuccess(Void aVoid) {
323 result.set(RpcResultBuilder.<Void>success().build());
327 public void onFailure(Throwable error) {
328 String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
329 LOG.error("remove terminating service actions failed. {}. {}", msg, error);
330 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
333 //result.set(RpcResultBuilder.<Void>success().build());
339 public List<MatchInfo> getTunnelMatchesForServiceId(int serviceId) {
340 List<MatchInfo> mkMatches = new ArrayList<>();
341 byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
344 byte Flags = (byte) 0x08;
345 vxLANHeader[0] = Flags;
347 // Extract the serviceId details and imprint on the VxLAN Header
348 vxLANHeader[4] = (byte) (serviceId >> 16);
349 vxLANHeader[5] = (byte) (serviceId >> 8);
350 vxLANHeader[6] = (byte) (serviceId >> 0);
353 mkMatches.add(new MatchTunnelId(BigInteger.valueOf(serviceId)));
358 private String getFlowRef(long termSvcTable, int svcId) {
359 return String.valueOf(termSvcTable) + svcId;
363 public Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
364 GetInternalOrExternalInterfaceNameInput input) {
365 RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = RpcResultBuilder.failed();
366 BigInteger srcDpn = input.getSourceDpid() ;
368 IpAddress dstIp = input.getDestinationIp() ;
369 InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(
370 ExternalTunnelList.class)
371 .child(ExternalTunnel.class, new ExternalTunnelKey(String.valueOf(dstIp), srcDpn.toString(), TunnelTypeMplsOverGre.class));
373 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
375 if( ext != null && ext.isPresent())
377 ExternalTunnel extTunnel = ext.get();
378 GetInternalOrExternalInterfaceNameOutputBuilder output = new GetInternalOrExternalInterfaceNameOutputBuilder().setInterfaceName(extTunnel.getTunnelInterfaceName() );
379 resultBld = RpcResultBuilder.success();
380 resultBld.withResult(output.build()) ;
382 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker);
383 if(meshedDpnList == null){
384 LOG.error("There are no tunnel mesh info in config DS");
385 return Futures.immediateFuture(resultBld.build());
387 // Look for external tunnels if not look for internal tunnel
388 for (DPNTEPsInfo teps : meshedDpnList) {
389 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
390 if (dstIp.equals(firstEndPt.getIpAddress())) {
391 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
393 .child(InternalTunnel.class, new InternalTunnelKey(teps.getDPNID(), srcDpn, input.getTunnelType()));
395 Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
396 if (tnl != null && tnl.isPresent()) {
397 InternalTunnel tunnel = tnl.get();
398 GetInternalOrExternalInterfaceNameOutputBuilder
400 new GetInternalOrExternalInterfaceNameOutputBuilder()
401 .setInterfaceName(tunnel.getTunnelInterfaceName());
402 resultBld = RpcResultBuilder.success();
403 resultBld.withResult(output.build());
406 LOG.error("Tunnel not found for source DPN {} ans destination IP {}", srcDpn, dstIp);
411 return Futures.immediateFuture(resultBld.build());
415 public Future<RpcResult<java.lang.Void>> deleteL2GwDevice(DeleteL2GwDeviceInput input) {
416 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
417 boolean foundVxlanTzone = false;
419 final IpAddress hwIp = input.getIpAddress();
420 final String node_id = input.getNodeId();
421 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
422 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
423 if (tZonesOptional.isPresent()) {
424 TransportZones tZones = tZonesOptional.get();
425 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
426 LOG.error("No teps configured");
427 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
430 for (TransportZone tzone : tZones.getTransportZone()) {
431 if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class)))
433 foundVxlanTzone = true;
434 String transportZone = tzone.getZoneName();
435 if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
436 result.set(RpcResultBuilder.<Void>failed()
437 .withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
440 SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
441 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id);
442 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
443 .child(TransportZone.class, new TransportZoneKey(transportZone))
444 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
446 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
447 //TO DO: add retry if it fails
449 t.delete(LogicalDatastoreType.CONFIGURATION, path);
451 ListenableFuture<Void> futureCheck = t.submit();
452 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
454 @Override public void onSuccess(Void aVoid) {
455 result.set(RpcResultBuilder.<Void>success().build());
458 @Override public void onFailure(Throwable error) {
459 String msg = String.format("Unable to delete HwVtep {} from datastore", node_id);
460 LOG.error("Unable to delete HwVtep {}, {} from datastore", node_id, hwIp);
461 result.set(RpcResultBuilder.<Void>failed()
462 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
469 result.set(RpcResultBuilder.<Void>failed()
470 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
474 if (!foundVxlanTzone) {
475 result.set(RpcResultBuilder.<Void>failed()
476 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
481 } catch (Exception e) {
482 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
483 withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
484 return Futures.immediateFuture(resultBuilder.build());
489 public Future<RpcResult<java.lang.Void>> addL2GwDevice(AddL2GwDeviceInput input) {
491 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
492 boolean foundVxlanTzone = false;
494 final IpAddress hwIp = input.getIpAddress();
495 final String node_id = input.getNodeId();
496 //iterate through all transport zones and put TORs under vxlan
497 //if no vxlan tzone is cnfigured, return an error.
498 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
499 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath,
501 if (tZonesOptional.isPresent()) {
502 TransportZones tZones = tZonesOptional.get();
503 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
504 LOG.error("No transportZone configured");
505 result.set(RpcResultBuilder.<Void>failed()
506 .withError(RpcError.ErrorType.APPLICATION, "No transportZone Configured").build());
509 for (TransportZone tzone : tZones.getTransportZone()) {
510 if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class)))
512 String transportZone = tzone.getZoneName();
513 if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
516 foundVxlanTzone = true;
517 SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
518 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id);
519 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
520 .child(TransportZone.class, new TransportZoneKey(transportZone))
521 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
523 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp)
524 .setNodeId(node_id).setTopologyId(input.getTopologyId()).build();
525 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
526 //TO DO: add retry if it fails
527 t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
529 ListenableFuture<Void> futureCheck = t.submit();
530 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
532 @Override public void onSuccess(Void aVoid) {
533 result.set(RpcResultBuilder.<Void>success().build());
536 @Override public void onFailure(Throwable error) {
537 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
538 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id, hwIp);
539 result.set(RpcResultBuilder.<Void>failed()
540 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
547 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
551 if (!foundVxlanTzone) {
552 result.set(RpcResultBuilder.<Void>failed()
553 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
558 } catch (Exception e) {
559 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
560 withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
561 return Futures.immediateFuture(resultBuilder.build());
566 public Future<RpcResult<java.lang.Void>> addL2GwMlagDevice(AddL2GwMlagDeviceInput input)
569 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
571 final IpAddress hwIp = input.getIpAddress();
572 final List<String> node_id = input.getNodeId();
573 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
574 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
575 if (tZonesOptional.isPresent()) {
576 TransportZones tZones = tZonesOptional.get();
577 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
578 LOG.error("No teps configured");
579 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
582 String transportZone = tZones.getTransportZone().get(0).getZoneName();
583 if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) {
584 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
587 SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey();
588 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id.get(0));
589 InstanceIdentifier<DeviceVteps> path =
590 InstanceIdentifier.builder(TransportZones.class)
591 .child(TransportZone.class, new TransportZoneKey(transportZone))
592 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build();
593 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp).setNodeId(node_id.get(0)).setTopologyId(input.getTopologyId()).build();
594 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
595 //TO DO: add retry if it fails
596 LOG.trace("writing hWvtep{}",deviceVtep);
597 t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
599 if(node_id.size() == 2) {
600 LOG.trace("second node-id {}",node_id.get(1));
601 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, node_id.get(1));
602 InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier.builder(TransportZones.class)
603 .child(TransportZone.class, new TransportZoneKey(transportZone))
604 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey2).build();
605 DeviceVteps deviceVtep2 = new DeviceVtepsBuilder().setKey(deviceVtepKey2).setIpAddress(hwIp).setNodeId(node_id.get(1))
606 .setTopologyId(input.getTopologyId()).build();
607 //TO DO: add retry if it fails
608 LOG.trace("writing {}",deviceVtep2);
609 t.put(LogicalDatastoreType.CONFIGURATION, path2, deviceVtep2, true);
610 }ListenableFuture<Void> futureCheck = t.submit();
611 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
614 public void onSuccess(Void aVoid) {
615 result.set(RpcResultBuilder.<Void>success().build());
619 public void onFailure(Throwable error) {
620 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
621 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp);
622 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
627 } catch (Exception e) {
628 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
629 withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
630 return Futures.immediateFuture(resultBuilder.build());
634 public Future<RpcResult<Void>> deleteL2GwMlagDevice(DeleteL2GwMlagDeviceInput input) {
636 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
638 final IpAddress hwIp = input.getIpAddress();
639 final List<String> node_id = input.getNodeId();
640 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
641 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
642 if (tZonesOptional.isPresent()) {
643 TransportZones tZones = tZonesOptional.get();
644 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
645 LOG.error("No teps configured");
646 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
649 String transportZone = tZones.getTransportZone().get(0).getZoneName();
650 if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) {
651 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
654 SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey();
655 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id.get(0));
656 InstanceIdentifier<DeviceVteps> path =
657 InstanceIdentifier.builder(TransportZones.class)
658 .child(TransportZone.class, new TransportZoneKey(transportZone))
659 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
660 deviceVtepKey).build();
661 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
662 //TO DO: add retry if it fails
663 t.delete(LogicalDatastoreType.CONFIGURATION, path);
665 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, node_id.get(1));
666 InstanceIdentifier<DeviceVteps> path2 =
667 InstanceIdentifier.builder(TransportZones.class)
668 .child(TransportZone.class, new TransportZoneKey(transportZone))
669 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
670 deviceVtepKey2).build();
671 //TO DO: add retry if it fails
672 t.delete(LogicalDatastoreType.CONFIGURATION, path2);
674 ListenableFuture<Void> futureCheck = t.submit();
675 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
678 public void onSuccess(Void aVoid) {
679 result.set(RpcResultBuilder.<Void>success().build());
683 public void onFailure(Throwable error) {
684 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
685 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp);
686 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
691 } catch (Exception e) {
692 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
693 withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
694 return Futures.immediateFuture(resultBuilder.build());
699 public Future<RpcResult<IsTunnelInternalOrExternalOutput>> isTunnelInternalOrExternal(
700 IsTunnelInternalOrExternalInput input) {
701 RpcResultBuilder<IsTunnelInternalOrExternalOutput> resultBld;
702 String tunIfName = input.getTunnelInterfaceName();
704 IsTunnelInternalOrExternalOutputBuilder output = new IsTunnelInternalOrExternalOutputBuilder().setTunnelType(tunVal);
706 if(ItmUtils.itmCache.getInternalTunnel(tunIfName) != null) {
708 } else if (ItmUtils.itmCache.getExternalTunnel(tunIfName) != null) {
711 output.setTunnelType(tunVal);
712 resultBld = RpcResultBuilder.success();
713 resultBld.withResult(output.build());
714 return Futures.immediateFuture(resultBld.build());
718 public Future<RpcResult<IsDcgwPresentOutput>> isDcgwPresent(IsDcgwPresentInput input) {
719 RpcResultBuilder<IsDcgwPresentOutput> resultBld = RpcResultBuilder.success();
721 List<DcGatewayIp> dcGatewayIpList = ItmUtils.getDcGatewayIpList(dataBroker);
722 String dcgwIpStr = input.getDcgwIp();
723 IpAddress dcgwIpAddr = new IpAddress(dcgwIpStr.toCharArray());
726 if((dcGatewayIpList != null) &&
727 (!dcGatewayIpList.isEmpty()) &&
728 (dcGatewayIpList.contains(dcgwIpAddr))) {
731 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
732 resultBld.withResult(output.build());
736 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
737 resultBld.withResult(output.build());
739 return Futures.immediateFuture(resultBld.build());