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.MatchFieldType;
32 import org.opendaylight.genius.mdsalutil.MatchInfo;
33 import org.opendaylight.genius.mdsalutil.NwConstants;
34 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
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() throws Exception {
111 LOG.info("ItmManagerRpcService Started");
115 public void close() throws Exception {
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());
206 result.set(RpcResultBuilder.<Void>success().build());
211 public Future<RpcResult<Void>> addExternalTunnelEndpoint(
212 AddExternalTunnelEndpointInput input) {
213 // TODO Auto-generated method stub
215 //Ignore the Futures for now
216 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
217 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker) ;
218 ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, idManagerService,meshedDpnList, input.getDestinationIp(), input.getTunnelType()) ;InstanceIdentifier<DcGatewayIp> extPath= InstanceIdentifier.builder(DcGatewayIpList.class).child(DcGatewayIp.class, new DcGatewayIpKey(input.getDestinationIp())).build();
219 DcGatewayIp dcGatewayIp = new DcGatewayIpBuilder().setIpAddress(input.getDestinationIp()).setTunnnelType(input.getTunnelType()).build();
220 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
221 t.put(LogicalDatastoreType.CONFIGURATION, extPath,dcGatewayIp, true);
222 ListenableFuture<Void> futureCheck = t.submit();
223 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
225 @Override public void onSuccess(Void aVoid) {
226 result.set(RpcResultBuilder.<Void>success().build());
229 @Override public void onFailure(Throwable error) {
231 "Unable to create DcGatewayIp {} in datastore for ip "+ input.getDestinationIp() + "and tunnel type " + input.getTunnelType();
233 result.set(RpcResultBuilder.<Void>failed()
234 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
241 public Future<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
242 GetExternalTunnelInterfaceNameInput input) {
243 SettableFuture.create();
244 RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
245 String sourceNode = input.getSourceNode();
246 String dstNode = input.getDestinationNode();
247 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
248 ExternalTunnelList.class)
249 .child(ExternalTunnel.class, new ExternalTunnelKey(dstNode, sourceNode, input.getTunnelType()));
251 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
253 if( ext != null && ext.isPresent())
255 ExternalTunnel exTunnel = ext.get();
256 GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ;
257 output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ;
258 resultBld = RpcResultBuilder.success();
259 resultBld.withResult(output.build()) ;
261 resultBld = RpcResultBuilder.failed();
264 return Futures.immediateFuture(resultBld.build());
268 public Future<RpcResult<java.lang.Void>> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
269 LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId() , input.getServiceId(), input.getInstruction());
270 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
271 int serviceId = input.getServiceId() ;
272 List<MatchInfo> mkMatches = getTunnelMatchesForServiceId(serviceId);
273 byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
275 byte Flags = (byte) 0x08;
276 vxLANHeader[0] = Flags;
278 // Extract the serviceId details and imprint on the VxLAN Header
279 vxLANHeader[4] = (byte) (serviceId >> 16);
280 vxLANHeader[5] = (byte) (serviceId >> 8);
281 vxLANHeader[6] = (byte) (serviceId >> 0);
284 // mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
285 // new BigInteger(1, vxLANHeader),
286 // MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID }));
288 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
289 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5, String.format("%s:%d","ITM Flow Entry ",serviceId),
290 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
292 ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
293 Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
296 public void onSuccess(Void aVoid) {
297 result.set(RpcResultBuilder.<Void>success().build());
301 public void onFailure(Throwable error) {
302 String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
303 LOG.error("create terminating service actions failed. {}. {}", msg, error);
304 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
307 // result.set(RpcResultBuilder.<Void>success().build());
312 public Future<RpcResult<java.lang.Void>> removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
313 LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}", input.getDpnId(), input.getServiceId());
314 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
315 Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE,
316 getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5, String.format("%s:%d","ITM Flow Entry ",input.getServiceId()),
317 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),getTunnelMatchesForServiceId(input.getServiceId()), null );
319 ListenableFuture<Void> installFlowResult = mdsalManager.removeFlow(input.getDpnId(), terminatingServiceTableFlow);
320 Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
323 public void onSuccess(Void aVoid) {
324 result.set(RpcResultBuilder.<Void>success().build());
328 public void onFailure(Throwable error) {
329 String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
330 LOG.error("remove terminating service actions failed. {}. {}", msg, error);
331 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
334 //result.set(RpcResultBuilder.<Void>success().build());
340 public List<MatchInfo> getTunnelMatchesForServiceId(int serviceId) {
341 List<MatchInfo> mkMatches = new ArrayList<>();
342 byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
345 byte Flags = (byte) 0x08;
346 vxLANHeader[0] = Flags;
348 // Extract the serviceId details and imprint on the VxLAN Header
349 vxLANHeader[4] = (byte) (serviceId >> 16);
350 vxLANHeader[5] = (byte) (serviceId >> 8);
351 vxLANHeader[6] = (byte) (serviceId >> 0);
354 mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[]{
355 BigInteger.valueOf(serviceId)}));
360 private String getFlowRef(long termSvcTable, int svcId) {
361 return String.valueOf(termSvcTable) + svcId;
365 public Future<RpcResult<GetInternalOrExternalInterfaceNameOutput>> getInternalOrExternalInterfaceName(
366 GetInternalOrExternalInterfaceNameInput input) {
367 RpcResultBuilder<GetInternalOrExternalInterfaceNameOutput> resultBld = RpcResultBuilder.failed();
368 BigInteger srcDpn = input.getSourceDpid() ;
370 IpAddress dstIp = input.getDestinationIp() ;
371 InstanceIdentifier<ExternalTunnel> path1 = InstanceIdentifier.create(
372 ExternalTunnelList.class)
373 .child(ExternalTunnel.class, new ExternalTunnelKey(String.valueOf(dstIp), srcDpn.toString(), TunnelTypeMplsOverGre.class));
375 Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path1, dataBroker);
377 if( ext != null && ext.isPresent())
379 ExternalTunnel extTunnel = ext.get();
380 GetInternalOrExternalInterfaceNameOutputBuilder output = new GetInternalOrExternalInterfaceNameOutputBuilder().setInterfaceName(extTunnel.getTunnelInterfaceName() );
381 resultBld = RpcResultBuilder.success();
382 resultBld.withResult(output.build()) ;
384 List<DPNTEPsInfo> meshedDpnList = ItmUtils.getTunnelMeshInfo(dataBroker);
385 if(meshedDpnList == null){
386 LOG.error("There are no tunnel mesh info in config DS");
387 return Futures.immediateFuture(resultBld.build());
389 // Look for external tunnels if not look for internal tunnel
390 for (DPNTEPsInfo teps : meshedDpnList) {
391 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
392 if (dstIp.equals(firstEndPt.getIpAddress())) {
393 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(
395 .child(InternalTunnel.class, new InternalTunnelKey(teps.getDPNID(), srcDpn, input.getTunnelType()));
397 Optional<InternalTunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
398 if (tnl != null && tnl.isPresent()) {
399 InternalTunnel tunnel = tnl.get();
400 GetInternalOrExternalInterfaceNameOutputBuilder
402 new GetInternalOrExternalInterfaceNameOutputBuilder()
403 .setInterfaceName(tunnel.getTunnelInterfaceName());
404 resultBld = RpcResultBuilder.success();
405 resultBld.withResult(output.build());
408 LOG.error("Tunnel not found for source DPN {} ans destination IP {}", srcDpn, dstIp);
413 return Futures.immediateFuture(resultBld.build());
417 public Future<RpcResult<java.lang.Void>> deleteL2GwDevice(DeleteL2GwDeviceInput input) {
418 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
419 boolean foundVxlanTzone = false;
421 final IpAddress hwIp = input.getIpAddress();
422 final String node_id = input.getNodeId();
423 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
424 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
425 if (tZonesOptional.isPresent()) {
426 TransportZones tZones = tZonesOptional.get();
427 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
428 LOG.error("No teps configured");
429 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
432 for (TransportZone tzone : tZones.getTransportZone()) {
433 if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class)))
435 foundVxlanTzone = true;
436 String transportZone = tzone.getZoneName();
437 if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
438 result.set(RpcResultBuilder.<Void>failed()
439 .withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
442 SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
443 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id);
444 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
445 .child(TransportZone.class, new TransportZoneKey(transportZone))
446 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
448 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
449 //TO DO: add retry if it fails
451 t.delete(LogicalDatastoreType.CONFIGURATION, path);
453 ListenableFuture<Void> futureCheck = t.submit();
454 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
456 @Override public void onSuccess(Void aVoid) {
457 result.set(RpcResultBuilder.<Void>success().build());
460 @Override public void onFailure(Throwable error) {
461 String msg = String.format("Unable to delete HwVtep {} from datastore", node_id);
462 LOG.error("Unable to delete HwVtep {}, {} from datastore", node_id, hwIp);
463 result.set(RpcResultBuilder.<Void>failed()
464 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
471 result.set(RpcResultBuilder.<Void>failed()
472 .withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
476 if (!foundVxlanTzone) {
477 result.set(RpcResultBuilder.<Void>failed()
478 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
483 } catch (Exception e) {
484 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
485 withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
486 return Futures.immediateFuture(resultBuilder.build());
491 public Future<RpcResult<java.lang.Void>> addL2GwDevice(AddL2GwDeviceInput input) {
493 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
494 boolean foundVxlanTzone = false;
496 final IpAddress hwIp = input.getIpAddress();
497 final String node_id = input.getNodeId();
498 //iterate through all transport zones and put TORs under vxlan
499 //if no vxlan tzone is cnfigured, return an error.
500 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
501 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath,
503 if (tZonesOptional.isPresent()) {
504 TransportZones tZones = tZonesOptional.get();
505 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
506 LOG.error("No transportZone configured");
507 result.set(RpcResultBuilder.<Void>failed()
508 .withError(RpcError.ErrorType.APPLICATION, "No transportZone Configured").build());
511 for (TransportZone tzone : tZones.getTransportZone()) {
512 if (!(tzone.getTunnelType().equals(TunnelTypeVxlan.class)))
514 String transportZone = tzone.getZoneName();
515 if (tzone.getSubnets() == null || tzone.getSubnets().isEmpty()) {
518 foundVxlanTzone = true;
519 SubnetsKey subnetsKey = tzone.getSubnets().get(0).getKey();
520 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id);
521 InstanceIdentifier<DeviceVteps> path = InstanceIdentifier.builder(TransportZones.class)
522 .child(TransportZone.class, new TransportZoneKey(transportZone))
523 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey)
525 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp)
526 .setNodeId(node_id).setTopologyId(input.getTopologyId()).build();
527 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
528 //TO DO: add retry if it fails
529 t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
531 ListenableFuture<Void> futureCheck = t.submit();
532 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
534 @Override public void onSuccess(Void aVoid) {
535 result.set(RpcResultBuilder.<Void>success().build());
538 @Override public void onFailure(Throwable error) {
539 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
540 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id, hwIp);
541 result.set(RpcResultBuilder.<Void>failed()
542 .withError(RpcError.ErrorType.APPLICATION, msg, error).build());
549 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No TransportZones configured").build());
553 if (!foundVxlanTzone) {
554 result.set(RpcResultBuilder.<Void>failed()
555 .withError(RpcError.ErrorType.APPLICATION, "No VxLan TransportZones configured")
560 } catch (Exception e) {
561 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
562 withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
563 return Futures.immediateFuture(resultBuilder.build());
568 public Future<RpcResult<java.lang.Void>> addL2GwMlagDevice(AddL2GwMlagDeviceInput input)
571 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
573 final IpAddress hwIp = input.getIpAddress();
574 final List<String> node_id = input.getNodeId();
575 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
576 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
577 if (tZonesOptional.isPresent()) {
578 TransportZones tZones = tZonesOptional.get();
579 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
580 LOG.error("No teps configured");
581 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
584 String transportZone = tZones.getTransportZone().get(0).getZoneName();
585 if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) {
586 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
589 SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey();
590 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id.get(0));
591 InstanceIdentifier<DeviceVteps> path =
592 InstanceIdentifier.builder(TransportZones.class)
593 .child(TransportZone.class, new TransportZoneKey(transportZone))
594 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey).build();
595 DeviceVteps deviceVtep = new DeviceVtepsBuilder().setKey(deviceVtepKey).setIpAddress(hwIp).setNodeId(node_id.get(0)).setTopologyId(input.getTopologyId()).build();
596 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
597 //TO DO: add retry if it fails
598 LOG.trace("writing hWvtep{}",deviceVtep);
599 t.put(LogicalDatastoreType.CONFIGURATION, path, deviceVtep, true);
601 if(node_id.size() == 2) {
602 LOG.trace("second node-id {}",node_id.get(1));
603 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, node_id.get(1));
604 InstanceIdentifier<DeviceVteps> path2 = InstanceIdentifier.builder(TransportZones.class)
605 .child(TransportZone.class, new TransportZoneKey(transportZone))
606 .child(Subnets.class, subnetsKey).child(DeviceVteps.class, deviceVtepKey2).build();
607 DeviceVteps deviceVtep2 = new DeviceVtepsBuilder().setKey(deviceVtepKey2).setIpAddress(hwIp).setNodeId(node_id.get(1))
608 .setTopologyId(input.getTopologyId()).build();
609 //TO DO: add retry if it fails
610 LOG.trace("writing {}",deviceVtep2);
611 t.put(LogicalDatastoreType.CONFIGURATION, path2, deviceVtep2, true);
612 }ListenableFuture<Void> futureCheck = t.submit();
613 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
616 public void onSuccess(Void aVoid) {
617 result.set(RpcResultBuilder.<Void>success().build());
621 public void onFailure(Throwable error) {
622 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
623 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp);
624 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
629 } catch (Exception e) {
630 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
631 withError(RpcError.ErrorType.APPLICATION, "Adding l2 Gateway to DS Failed", e);
632 return Futures.immediateFuture(resultBuilder.build());
636 public Future<RpcResult<Void>> deleteL2GwMlagDevice(DeleteL2GwMlagDeviceInput input) {
638 final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
640 final IpAddress hwIp = input.getIpAddress();
641 final List<String> node_id = input.getNodeId();
642 InstanceIdentifier<TransportZones> containerPath = InstanceIdentifier.create(TransportZones.class);
643 Optional<TransportZones> tZonesOptional = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, containerPath, dataBroker);
644 if (tZonesOptional.isPresent()) {
645 TransportZones tZones = tZonesOptional.get();
646 if (tZones.getTransportZone() == null || tZones.getTransportZone().isEmpty()) {
647 LOG.error("No teps configured");
648 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No teps Configured").build());
651 String transportZone = tZones.getTransportZone().get(0).getZoneName();
652 if (tZones.getTransportZone().get(0).getSubnets() == null || tZones.getTransportZone().get(0).getSubnets().isEmpty()) {
653 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, "No subnets Configured").build());
656 SubnetsKey subnetsKey = tZones.getTransportZone().get(0).getSubnets().get(0).getKey();
657 DeviceVtepsKey deviceVtepKey = new DeviceVtepsKey(hwIp, node_id.get(0));
658 InstanceIdentifier<DeviceVteps> path =
659 InstanceIdentifier.builder(TransportZones.class)
660 .child(TransportZone.class, new TransportZoneKey(transportZone))
661 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
662 deviceVtepKey).build();
663 WriteTransaction t = dataBroker.newWriteOnlyTransaction();
664 //TO DO: add retry if it fails
665 t.delete(LogicalDatastoreType.CONFIGURATION, path);
667 DeviceVtepsKey deviceVtepKey2 = new DeviceVtepsKey(hwIp, node_id.get(1));
668 InstanceIdentifier<DeviceVteps> path2 =
669 InstanceIdentifier.builder(TransportZones.class)
670 .child(TransportZone.class, new TransportZoneKey(transportZone))
671 .child(Subnets.class, subnetsKey).child(DeviceVteps.class,
672 deviceVtepKey2).build();
673 //TO DO: add retry if it fails
674 t.delete(LogicalDatastoreType.CONFIGURATION, path2);
676 ListenableFuture<Void> futureCheck = t.submit();
677 Futures.addCallback(futureCheck, new FutureCallback<Void>() {
680 public void onSuccess(Void aVoid) {
681 result.set(RpcResultBuilder.<Void>success().build());
685 public void onFailure(Throwable error) {
686 String msg = String.format("Unable to write HwVtep {} to datastore", node_id);
687 LOG.error("Unable to write HwVtep {}, {} to datastore", node_id , hwIp);
688 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
693 } catch (Exception e) {
694 RpcResultBuilder<java.lang.Void> resultBuilder = RpcResultBuilder.<Void>failed().
695 withError(RpcError.ErrorType.APPLICATION, "Deleting l2 Gateway to DS Failed", e);
696 return Futures.immediateFuture(resultBuilder.build());
701 public Future<RpcResult<IsTunnelInternalOrExternalOutput>> isTunnelInternalOrExternal(
702 IsTunnelInternalOrExternalInput input) {
703 RpcResultBuilder<IsTunnelInternalOrExternalOutput> resultBld;
704 String tunIfName = input.getTunnelInterfaceName();
706 IsTunnelInternalOrExternalOutputBuilder output = new IsTunnelInternalOrExternalOutputBuilder().setTunnelType(tunVal);
708 if(ItmUtils.itmCache.getInternalTunnel(tunIfName) != null) {
710 } else if (ItmUtils.itmCache.getExternalTunnel(tunIfName) != null) {
713 output.setTunnelType(tunVal);
714 resultBld = RpcResultBuilder.success();
715 resultBld.withResult(output.build());
716 return Futures.immediateFuture(resultBld.build());
720 public Future<RpcResult<IsDcgwPresentOutput>> isDcgwPresent(IsDcgwPresentInput input) {
721 RpcResultBuilder<IsDcgwPresentOutput> resultBld = RpcResultBuilder.success();
723 List<DcGatewayIp> dcGatewayIpList = ItmUtils.getDcGatewayIpList(dataBroker);
724 String dcgwIpStr = input.getDcgwIp();
725 IpAddress dcgwIpAddr = new IpAddress(dcgwIpStr.toCharArray());
728 if((dcGatewayIpList != null) &&
729 (!dcGatewayIpList.isEmpty()) &&
730 (dcGatewayIpList.contains(dcgwIpAddr))) {
733 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
734 resultBld.withResult(output.build());
738 IsDcgwPresentOutputBuilder output = new IsDcgwPresentOutputBuilder().setRetVal(retVal);
739 resultBld.withResult(output.build());
741 return Futures.immediateFuture(resultBld.build());