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