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