package org.opendaylight.vpnservice.itm.rpc;
import java.math.BigInteger;
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
import org.opendaylight.vpnservice.itm.confighelpers.ItmExternalTunnelAddWorker;
+import org.opendaylight.vpnservice.itm.globals.ITMConstants;
+import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.vpnservice.itm.impl.ItmUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.op.rev150701.tunnels.DPNTEPsInfo;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.BuildTunnelFromDpnToDcgatewayInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.BuildTunnelToDcgatewayInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.GetTunnelInterfaceIdInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.GetTunnelInterfaceIdOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.GetTunnelInterfaceIdOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.itm.rpcs.rev151217.ItmRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.ExternalTunnelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.TunnelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.DPNTEPsInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.Tunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.TunnelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.AddExternalTunnelEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.BuildExternalTunnelFromDpnsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.CreateTerminatingServiceActionsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.RemoveExternalTunnelEndpointInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.RemoveExternalTunnelFromDpnsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.RemoveTerminatingServiceActionsInput;
import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
+import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
+import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
+import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
+import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
+import org.opendaylight.vpnservice.mdsalutil.ActionType;
import com.google.common.base.Optional;
public class ItmManagerRpcService implements ItmRpcService {
- private static final Logger LOG = LoggerFactory.getLogger(ItmRpcService.class);
+ private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class);
DataBroker dataBroker;
- public ItmManagerRpcService(DataBroker dataBroker) {
- this.dataBroker = dataBroker;
+ private IMdsalApiManager mdsalManager;
+
+
+ public void setMdsalManager(IMdsalApiManager mdsalManager) {
+ this.mdsalManager = mdsalManager;
}
- @Override
- public Future<RpcResult<java.lang.Void>> buildTunnelFromDpnToDcgateway(BuildTunnelFromDpnToDcgatewayInput input) {
- //Ignore the Futures for now
- final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
- ItmExternalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, input.getDpid(), null, input.getDcgwyid());
- result.set(RpcResultBuilder.<Void>success().build());
- return result ;
- }
+ IdManagerService idManagerService;
+
+ public ItmManagerRpcService(DataBroker dataBroker, IdManagerService idManagerService) {
+ this.dataBroker = dataBroker;
+ this.idManagerService = idManagerService;
+ }
@Override
- public Future<RpcResult<GetTunnelInterfaceIdOutput>> getTunnelInterfaceId(GetTunnelInterfaceIdInput input) {
- final SettableFuture<RpcResult<GetTunnelInterfaceIdOutput>> result = SettableFuture.create() ;
- RpcResultBuilder<GetTunnelInterfaceIdOutput> resultBld = null;
+ public Future<RpcResult<GetTunnelInterfaceNameOutput>> getTunnelInterfaceName(GetTunnelInterfaceNameInput input) {
+ RpcResultBuilder<GetTunnelInterfaceNameOutput> resultBld = null;
BigInteger sourceDpn = input.getSourceDpid() ;
BigInteger destinationDpn = input.getDestinationDpid() ;
- String parentName = null;
- IpAddress srcIp = null ;
- IpAddress destIp = null ;
- List<DPNTEPsInfo> meshDpnList = ItmUtils.getTunnelMeshInfo(dataBroker);
- for ( DPNTEPsInfo dpn : meshDpnList) {
- if( (dpn.getDPNID()).equals(sourceDpn) ){
- parentName = dpn.getTunnelEndPoints().get(0).getInterfaceName();
- srcIp = dpn.getTunnelEndPoints().get(0).getIpAddress() ;
- }else if( (dpn.getDPNID()).equals(destinationDpn)) {
- destIp = dpn.getTunnelEndPoints().get(0).getIpAddress() ;
- }
- }
- if( srcIp != null && destIp != null )
+ InstanceIdentifier<Tunnel> path = InstanceIdentifier.create(
+ TunnelList.class)
+ .child(Tunnel.class, new TunnelKey(destinationDpn, sourceDpn));
+
+ Optional<Tunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
+
+ if( tnl != null && tnl.isPresent())
{
- String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(parentName, srcIp.getIpv4Address().getValue(), destIp.getIpv4Address().getValue()) ;
- InstanceIdentifierBuilder<Interface> idBuilder = InstanceIdentifier.builder(InterfacesState.class)
- .child(Interface.class, new InterfaceKey(trunkInterfaceName));
- InstanceIdentifier<Interface> id = idBuilder.build();
- Optional<Interface> stateIf = ItmUtils.read(LogicalDatastoreType.OPERATIONAL, id, dataBroker);
- if(stateIf.isPresent()){
- GetTunnelInterfaceIdOutputBuilder output = new GetTunnelInterfaceIdOutputBuilder() ;
- output.setInterfaceid(stateIf.get().getIfIndex()) ;
- resultBld.withResult(output.build()) ;
- result.set(resultBld.build()) ;
- }else {
- result.set(RpcResultBuilder.<GetTunnelInterfaceIdOutput>failed().withError(RpcError.ErrorType.APPLICATION, "Interface Not found ").build()) ;
- }
+ Tunnel tunnel = tnl.get();
+ GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ;
+ output.setInterfaceName(tunnel.getTunnelInterfaceName()) ;
+ resultBld = RpcResultBuilder.success();
+ resultBld.withResult(output.build()) ;
}else {
- result.set(RpcResultBuilder.<GetTunnelInterfaceIdOutput>failed().withError(RpcError.ErrorType.APPLICATION, "Source or Destination Dpn Id not found ").build()) ;
+ resultBld = RpcResultBuilder.failed();
}
- return result ;
+
+ return Futures.immediateFuture(resultBld.build());
}
- @Override
- public Future<RpcResult<java.lang.Void>> buildTunnelToDcgateway(BuildTunnelToDcgatewayInput input) {
- //Ignore the Futures for now
- final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
- ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, null, input.getDcgwyid()) ;
- result.set(RpcResultBuilder.<Void>success().build());
- return result ;
- }
+
+ @Override
+ public Future<RpcResult<Void>> removeExternalTunnelEndpoint(
+ RemoveExternalTunnelEndpointInput input) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<Void>> removeExternalTunnelFromDpns(
+ RemoveExternalTunnelFromDpnsInput input) {
+ //Ignore the Futures for now
+ final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+// ItmExternalTunnelDeleteWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, input.getDpnId(), null, input.getDestinationIp());
+ result.set(RpcResultBuilder.<Void>success().build());
+ return result;
+ }
+
+ @Override
+ public Future<RpcResult<Void>> buildExternalTunnelFromDpns(
+ BuildExternalTunnelFromDpnsInput input) {
+ //Ignore the Futures for now
+ final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+ List<ListenableFuture<Void>> extTunnelResultList = ItmExternalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, idManagerService, input.getDpnId(), input.getDestinationIp(), input.getTunnelType());
+ for (ListenableFuture<Void> extTunnelResult : extTunnelResultList) {
+ Futures.addCallback(extTunnelResult, new FutureCallback<Void>(){
+
+ @Override
+ public void onSuccess(Void aVoid) {
+ result.set(RpcResultBuilder.<Void>success().build());
+ }
+
+ @Override
+ public void onFailure(Throwable error) {
+ String msg = String.format("Unable to create ext tunnel");
+ LOG.error("create ext tunnel failed. {}. {}", msg, error);
+ result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
+ }
+ });
+ }
+ result.set(RpcResultBuilder.<Void>success().build());
+ return result;
+ }
+
+ @Override
+ public Future<RpcResult<Void>> addExternalTunnelEndpoint(
+ AddExternalTunnelEndpointInput input) {
+ // TODO Auto-generated method stub
+
+ //Ignore the Futures for now
+ final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+ // ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, null, input.getDestinationIp()) ;
+ result.set(RpcResultBuilder.<Void>success().build());
+ return result;
+ }
+
+ @Override
+ public Future<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
+ GetExternalTunnelInterfaceNameInput input) {
+ final SettableFuture<RpcResult<GetExternalTunnelInterfaceNameOutput>> result = SettableFuture.create() ;
+ RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
+ BigInteger sourceDpn = input.getSourceDpid() ;
+ IpAddress destinationIp = input.getDestinationIp() ;
+ InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
+ ExternalTunnelList.class)
+ .child(ExternalTunnel.class, new ExternalTunnelKey(destinationIp, sourceDpn));
+
+ Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
+
+ if( ext != null && ext.isPresent())
+ {
+ ExternalTunnel exTunnel = ext.get();
+ GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ;
+ output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ;
+ resultBld = RpcResultBuilder.success();
+ resultBld.withResult(output.build()) ;
+ }else {
+ resultBld = RpcResultBuilder.failed();
+ }
+
+ return Futures.immediateFuture(resultBld.build());
+ }
+
+ @Override
+ public Future<RpcResult<java.lang.Void>> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
+ LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId() , input.getServiceId(), input.getInstruction());
+ final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+ int serviceId = input.getServiceId() ;
+ List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+ byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ // Flags Byte
+ byte Flags = (byte) 0x08;
+ vxLANHeader[0] = Flags;
+
+ // Extract the serviceId details and imprint on the VxLAN Header
+ vxLANHeader[4] = (byte) (serviceId >> 16);
+ vxLANHeader[5] = (byte) (serviceId >> 8);
+ vxLANHeader[6] = (byte) (serviceId >> 0);
+
+ // Matching metadata
+ mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
+ new BigInteger(1, vxLANHeader),
+ MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID }));
+
+ Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(ITMConstants.INTERNAL_TUNNEL_TABLE,
+ getFlowRef(ITMConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5, String.format("%s:%d","ITM Flow Entry ",serviceId),
+ 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
+
+ ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
+ Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
+
+ @Override
+ public void onSuccess(Void aVoid) {
+ result.set(RpcResultBuilder.<Void>success().build());
+ }
+
+ @Override
+ public void onFailure(Throwable error) {
+ String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
+ LOG.error("create terminating service actions failed. {}. {}", msg, error);
+ result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
+ }
+ });
+ result.set(RpcResultBuilder.<Void>success().build());
+ return result;
+ }
+
+ @Override
+ public Future<RpcResult<java.lang.Void>> removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
+ LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}", input.getDpnId(), input.getServiceId());
+ final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+ Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(ITMConstants.INTERNAL_TUNNEL_TABLE,
+ getFlowRef(ITMConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5, String.format("%s:%d","ITM Flow Entry ",input.getServiceId()),
+ 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),getTunnelMatchesForServiceId(input.getServiceId()), null );
+
+ ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
+ Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
+
+ @Override
+ public void onSuccess(Void aVoid) {
+ result.set(RpcResultBuilder.<Void>success().build());
+ }
+
+ @Override
+ public void onFailure(Throwable error) {
+ String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
+ LOG.error("remove terminating service actions failed. {}. {}", msg, error);
+ result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
+ }
+ });
+ result.set(RpcResultBuilder.<Void>success().build());
+
+ return result ;
+ }
+
+ public List<MatchInfo> getTunnelMatchesForServiceId(int serviceId) {
+ List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+ byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ // Flags Byte
+ byte Flags = (byte) 0x08;
+ vxLANHeader[0] = Flags;
+
+ // Extract the serviceId details and imprint on the VxLAN Header
+ vxLANHeader[4] = (byte) (serviceId >> 16);
+ vxLANHeader[5] = (byte) (serviceId >> 8);
+ vxLANHeader[6] = (byte) (serviceId >> 0);
+
+ // Matching metadata
+ mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[]{
+ new BigInteger(1, vxLANHeader),
+ MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID}));
+
+ return mkMatches;
+ }
+
+ private String getFlowRef(long termSvcTable, int svcId) {
+ return new StringBuffer().append(termSvcTable).append(svcId).toString();
+ }
+
}