Updated BgpManager for Be
[vpnservice.git] / itm / itm-impl / src / main / java / org / opendaylight / vpnservice / itm / rpc / ItmManagerRpcService.java
1 /*
2  * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.vpnservice.itm.rpc;
9
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.concurrent.Future;
14
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
20 import org.opendaylight.vpnservice.itm.confighelpers.ItmExternalTunnelAddWorker;
21 import org.opendaylight.vpnservice.itm.globals.ITMConstants;
22 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
23 import org.opendaylight.vpnservice.itm.impl.ItmUtils;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.ExternalTunnelList;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.TunnelList;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.dpn.endpoints.DPNTEPsInfo;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnel;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.external.tunnel.list.ExternalTunnelKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.Tunnel;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.op.rev150701.tunnel.list.TunnelKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.AddExternalTunnelEndpointInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.BuildExternalTunnelFromDpnsInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.CreateTerminatingServiceActionsInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameOutputBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameOutput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetTunnelInterfaceNameOutputBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.RemoveExternalTunnelEndpointInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.RemoveExternalTunnelFromDpnsInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.RemoveTerminatingServiceActionsInput;
46 import org.opendaylight.yangtools.yang.common.RpcResult;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48
49 import com.google.common.util.concurrent.FutureCallback;
50 import com.google.common.util.concurrent.Futures;
51 import com.google.common.util.concurrent.ListenableFuture;
52 import com.google.common.util.concurrent.SettableFuture;
53
54 import org.opendaylight.yangtools.yang.common.RpcError;
55 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
56 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
57 import org.opendaylight.vpnservice.mdsalutil.MatchFieldType;
58 import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
59 import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
60 import org.opendaylight.vpnservice.mdsalutil.ActionInfo;
61 import org.opendaylight.vpnservice.mdsalutil.ActionType;
62
63 import com.google.common.base.Optional;
64
65 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
66
67 public class ItmManagerRpcService implements ItmRpcService {
68
69    private static final Logger LOG = LoggerFactory.getLogger(ItmManagerRpcService.class);
70         DataBroker dataBroker;
71         private IMdsalApiManager mdsalManager;
72         public ItmManagerRpcService(DataBroker dataBroker) {
73         this.dataBroker = dataBroker;
74     }
75
76     public void setMdsalManager(IMdsalApiManager mdsalManager) {
77             this.mdsalManager = mdsalManager;
78     }
79
80      @Override
81      public Future<RpcResult<GetTunnelInterfaceNameOutput>> getTunnelInterfaceName(GetTunnelInterfaceNameInput input) {
82          RpcResultBuilder<GetTunnelInterfaceNameOutput> resultBld = null;
83          BigInteger sourceDpn = input.getSourceDpid() ;
84          BigInteger destinationDpn = input.getDestinationDpid() ;
85          InstanceIdentifier<Tunnel> path = InstanceIdentifier.create(
86                  TunnelList.class)
87                      .child(Tunnel.class, new TunnelKey(destinationDpn, sourceDpn));      
88          
89          Optional<Tunnel> tnl = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
90
91          if( tnl != null && tnl.isPresent())
92          {
93               Tunnel tunnel = tnl.get();
94               GetTunnelInterfaceNameOutputBuilder output = new GetTunnelInterfaceNameOutputBuilder() ;
95               output.setInterfaceName(tunnel.getTunnelInterfaceName()) ;
96               resultBld = RpcResultBuilder.success();
97               resultBld.withResult(output.build()) ;
98          }else {
99              resultBld = RpcResultBuilder.failed();
100          }
101          
102          return Futures.immediateFuture(resultBld.build());
103      }
104
105
106     @Override
107     public Future<RpcResult<Void>> removeExternalTunnelEndpoint(
108             RemoveExternalTunnelEndpointInput input) {
109         // TODO Auto-generated method stub
110         return null;
111     }
112
113     @Override
114     public Future<RpcResult<Void>> removeExternalTunnelFromDpns(
115             RemoveExternalTunnelFromDpnsInput input) {
116         //Ignore the Futures for now
117         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
118 //        ItmExternalTunnelDeleteWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, input.getDpnId(), null, input.getDestinationIp());
119         result.set(RpcResultBuilder.<Void>success().build());
120         return result;
121     }
122
123     @Override
124     public Future<RpcResult<Void>> buildExternalTunnelFromDpns(
125             BuildExternalTunnelFromDpnsInput input) {
126         //Ignore the Futures for now
127         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
128         List<ListenableFuture<Void>> extTunnelResultList = ItmExternalTunnelAddWorker.buildTunnelsFromDpnToExternalEndPoint(dataBroker, input.getDpnId(), input.getDestinationIp(), input.getTunnelType());
129         for (ListenableFuture<Void> extTunnelResult : extTunnelResultList) {
130             Futures.addCallback(extTunnelResult, new FutureCallback<Void>(){
131
132                 @Override
133                 public void onSuccess(Void aVoid) {
134                     result.set(RpcResultBuilder.<Void>success().build());
135                 }
136
137                 @Override
138                 public void onFailure(Throwable error) {
139                     String msg = String.format("Unable to create ext tunnel");
140                     LOG.error("create ext tunnel failed. {}. {}", msg, error);
141                     result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
142                 }
143             });
144         }
145         result.set(RpcResultBuilder.<Void>success().build());
146         return result;
147     }
148
149     @Override
150     public Future<RpcResult<Void>> addExternalTunnelEndpoint(
151             AddExternalTunnelEndpointInput input) {
152         // TODO Auto-generated method stub
153
154         //Ignore the Futures for now
155         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
156     //    ItmExternalTunnelAddWorker.buildTunnelsToExternalEndPoint(dataBroker, null, input.getDestinationIp()) ;
157         result.set(RpcResultBuilder.<Void>success().build());
158         return result;
159     }
160
161     @Override
162     public Future<RpcResult<GetExternalTunnelInterfaceNameOutput>> getExternalTunnelInterfaceName(
163             GetExternalTunnelInterfaceNameInput input) {
164         final SettableFuture<RpcResult<GetExternalTunnelInterfaceNameOutput>> result = SettableFuture.create() ;
165         RpcResultBuilder<GetExternalTunnelInterfaceNameOutput> resultBld;
166         BigInteger sourceDpn = input.getSourceDpid() ;
167         IpAddress destinationIp = input.getDestinationIp() ;
168         InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(
169                 ExternalTunnelList.class)
170                     .child(ExternalTunnel.class, new ExternalTunnelKey(destinationIp, sourceDpn));      
171         
172         Optional<ExternalTunnel> ext = ItmUtils.read(LogicalDatastoreType.CONFIGURATION, path, dataBroker);
173
174         if( ext != null && ext.isPresent())
175         {
176              ExternalTunnel exTunnel = ext.get();
177              GetExternalTunnelInterfaceNameOutputBuilder output = new GetExternalTunnelInterfaceNameOutputBuilder() ;
178              output.setInterfaceName(exTunnel.getTunnelInterfaceName()) ;
179              resultBld = RpcResultBuilder.success();
180              resultBld.withResult(output.build()) ;
181         }else {
182             resultBld = RpcResultBuilder.failed();
183         }
184         
185         return Futures.immediateFuture(resultBld.build());
186     }
187
188     @Override
189     public Future<RpcResult<java.lang.Void>> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
190         LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId() , input.getServiceId(), input.getInstruction());
191        final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
192        int serviceId = input.getServiceId() ;
193        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
194        byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
195     // Flags Byte
196        byte Flags = (byte) 0x08;
197        vxLANHeader[0] = Flags;
198
199        // Extract the serviceId details and imprint on the VxLAN Header
200        vxLANHeader[4] = (byte) (serviceId >> 16);
201        vxLANHeader[5] = (byte) (serviceId >> 8);
202        vxLANHeader[6] = (byte) (serviceId >> 0);
203
204        // Matching metadata
205        mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
206                                new BigInteger(1, vxLANHeader),
207                                MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID }));
208
209        Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(ITMConstants.INTERNAL_TUNNEL_TABLE,
210                        getFlowRef(ITMConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5, String.format("%s:%d","ITM Flow Entry ",serviceId),
211                        0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
212
213        ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
214        Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
215
216            @Override
217            public void onSuccess(Void aVoid) {
218                result.set(RpcResultBuilder.<Void>success().build());
219            }
220
221            @Override
222            public void onFailure(Throwable error) {
223                String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
224                LOG.error("create terminating service actions failed. {}. {}", msg, error);
225                result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
226            }
227        });
228        result.set(RpcResultBuilder.<Void>success().build());
229        return result;
230     }
231
232     @Override
233     public Future<RpcResult<java.lang.Void>> removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
234         LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}", input.getDpnId(), input.getServiceId());
235         final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
236         Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(ITMConstants.INTERNAL_TUNNEL_TABLE,
237                 getFlowRef(ITMConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5, String.format("%s:%d","ITM Flow Entry ",input.getServiceId()),
238                 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),getTunnelMatchesForServiceId(input.getServiceId()), null );
239
240         ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
241         Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
242
243             @Override
244             public void onSuccess(Void aVoid) {
245                 result.set(RpcResultBuilder.<Void>success().build());
246             }
247
248             @Override
249             public void onFailure(Throwable error) {
250                 String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
251                 LOG.error("remove terminating service actions failed. {}. {}", msg, error);
252                 result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
253             }
254         });
255         result.set(RpcResultBuilder.<Void>success().build());
256
257        return result ;
258     }
259
260     public List<MatchInfo> getTunnelMatchesForServiceId(int serviceId) {
261         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
262         byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
263
264         // Flags Byte
265         byte Flags = (byte) 0x08;
266         vxLANHeader[0] = Flags;
267
268         // Extract the serviceId details and imprint on the VxLAN Header
269         vxLANHeader[4] = (byte) (serviceId >> 16);
270         vxLANHeader[5] = (byte) (serviceId >> 8);
271         vxLANHeader[6] = (byte) (serviceId >> 0);
272
273         // Matching metadata
274         mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[]{
275                 new BigInteger(1, vxLANHeader),
276                 MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID}));
277
278         return mkMatches;
279     }
280
281     private String getFlowRef(long termSvcTable, int svcId) {
282         return new StringBuffer().append(termSvcTable).append(svcId).toString();
283     }
284
285 }