Merge "Returning of future from request context - PacketProcessingService."
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / statistics / services / OpendaylightFlowStatisticsServiceImpl.java
1 /**
2  * Copyright (c) 2015 Cisco Systems, Inc. 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.openflowplugin.impl.statistics.services;
9
10 import com.google.common.base.Function;
11 import com.google.common.base.MoreObjects;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.concurrent.Future;
17 import javax.annotation.Nullable;
18 import org.opendaylight.openflowplugin.api.OFConstants;
19 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
20 import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
21 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
22 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
23 import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
24 import org.opendaylight.openflowplugin.api.openflow.device.Xid;
25 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
26 import org.opendaylight.openflowplugin.impl.services.CommonService;
27 import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
28 import org.opendaylight.openflowplugin.impl.util.StatisticsServiceUtil;
29 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
30 import org.opendaylight.openflowplugin.openflow.md.util.FlowCreatorUtil;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.aggregate.flow.statistics.from.flow.table._for.given.match.output.AggregatedFlowStatistics;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
52 import org.opendaylight.yangtools.yang.common.RpcResult;
53 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57 /**
58  * @author joe
59  */
60 public class OpendaylightFlowStatisticsServiceImpl extends CommonService implements OpendaylightFlowStatisticsService {
61
62     private static final Logger LOG = LoggerFactory.getLogger(OpendaylightFlowStatisticsServiceImpl.class);
63
64     public OpendaylightFlowStatisticsServiceImpl(final RequestContextStack requestContextStack, DeviceContext deviceContext) {
65         super(requestContextStack, deviceContext);
66     }
67
68     @Override
69     public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
70             final GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) {
71
72
73         return handleServiceCall(
74                 new Function<RequestContext<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>, 
75                 ListenableFuture<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>>>() {
76
77                     @Override
78                     public ListenableFuture<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> apply(final RequestContext<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput> requestContext) {
79
80                         // Create multipart request body for fetch all the group stats
81                         final MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder = new MultipartRequestAggregateCaseBuilder();
82                         final MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
83                         mprAggregateRequestBuilder.setTableId(input.getTableId().getValue());
84                         mprAggregateRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
85                         mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
86                         mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
87                         mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
88                         final short version = getVersion();
89                         FlowCreatorUtil.setWildcardedFlowMatch(version, mprAggregateRequestBuilder);
90
91                         // Set request body to main multipart request
92                         multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder
93                                 .build());
94                         final Xid xid = requestContext.getXid();
95                         final MultipartRequestInputBuilder mprInput = RequestInputUtils.createMultipartHeader(
96                                 MultipartType.OFPMPAGGREGATE, xid.getValue(), version);
97
98                         mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
99
100                         return StatisticsServiceUtil.getRpcResultListenableFuture(xid, mprInput.build(), getDeviceContext());
101                     }
102                 });
103
104     }
105
106     @Override
107     public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
108             final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
109
110
111         ListenableFuture<RpcResult<List<MultipartReply>>> rpcResultListenableFuture = handleServiceCall(
112                 new Function<RequestContext<List<MultipartReply>>, ListenableFuture<RpcResult<List<MultipartReply>>>>() {
113
114                     @Override
115                     public ListenableFuture<RpcResult<List<MultipartReply>>> apply(final RequestContext<List<MultipartReply>> requestContext) {
116                         final Xid xid = requestContext.getXid();
117                         final DeviceContext deviceContext = getDeviceContext();
118                         deviceContext.getMultiMsgCollector().registerMultipartRequestContext(requestContext);
119                         final MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder = new MultipartRequestAggregateCaseBuilder();
120                         final MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
121                         final short tableId = MoreObjects.firstNonNull(input.getTableId(), OFConstants.OFPTT_ALL).shortValue();
122                         mprAggregateRequestBuilder.setTableId(tableId);
123                         long outputPortValue = MoreObjects.firstNonNull(input.getOutPort(), OFConstants.OFPP_ANY).longValue();
124                         mprAggregateRequestBuilder.setOutPort(outputPortValue);
125                         // TODO: repeating code
126
127                         final short version = getVersion();
128                         if (version == OFConstants.OFP_VERSION_1_3) {
129
130                             if (input.getCookie() == null) {
131                                 mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
132                             } else {
133                                 mprAggregateRequestBuilder.setCookie(MoreObjects.firstNonNull(input.getCookie().getValue(), OFConstants.DEFAULT_COOKIE));
134                             }
135
136                             if (input.getCookieMask() == null) {
137                                 mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
138                             } else {
139                                 mprAggregateRequestBuilder.setCookieMask(MoreObjects.firstNonNull(input.getCookieMask().getValue(), OFConstants.DEFAULT_COOKIE_MASK));
140                             }
141                             long outGroup = MoreObjects.firstNonNull(input.getOutGroup(), OFConstants.OFPG_ANY).longValue();
142                             mprAggregateRequestBuilder.setOutGroup(outGroup);
143                         } else {
144                             mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
145                             mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
146                             mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
147                         }
148
149                         MatchReactor.getInstance().convert(input.getMatch(), version, mprAggregateRequestBuilder,
150                                 deviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId());
151
152                         FlowCreatorUtil.setWildcardedFlowMatch(version, mprAggregateRequestBuilder);
153
154                         // Set request body to main multipart request
155                         multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder
156                                 .build());
157
158                         final MultipartRequestInputBuilder mprInput = RequestInputUtils.createMultipartHeader(
159                                 MultipartType.OFPMPAGGREGATE, xid.getValue(), version);
160
161                         mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
162                         return StatisticsServiceUtil.getRpcResultListenableFuture(xid, mprInput.build(), getDeviceContext());
163                     }
164                 });
165
166         return Futures.transform(rpcResultListenableFuture, new Function<RpcResult<List<MultipartReply>>, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>>() {
167             @Nullable
168             @Override
169             public RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput> apply(RpcResult<List<MultipartReply>> input) {
170                 final DeviceContext deviceContext = getDeviceContext();
171                 TranslatorLibrary translatorLibrary = deviceContext.oook();
172                 RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput> rpcResult;
173                 if (input.isSuccessful()) {
174                     MultipartReply reply = input.getResult().get(0);
175                     final TranslatorKey translatorKey = new TranslatorKey(reply.getVersion(), MultipartReplyAggregateCase.class.getName());
176                     final MessageTranslator<MultipartReply, AggregatedFlowStatistics> messageTranslator = translatorLibrary.lookupTranslator(translatorKey);
177                     List<AggregatedFlowStatistics> aggregStats = new ArrayList<AggregatedFlowStatistics>();
178
179                     for (MultipartReply multipartReply : input.getResult()) {
180                         aggregStats.add(messageTranslator.translate(multipartReply, deviceContext, null));
181                     }
182
183                     GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder =
184                             new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder();
185                     getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder.setAggregatedFlowStatistics(aggregStats);
186
187                     rpcResult = RpcResultBuilder
188                             .<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>success()
189                             .withResult(getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder.build())
190                             .build();
191
192                 } else {
193                     rpcResult = RpcResultBuilder
194                             .<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>failed()
195                             .withRpcErrors(input.getErrors())
196                             .build();
197                 }
198                 return rpcResult;
199             }
200         });
201
202     }
203
204     @Override
205     public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
206             final GetAllFlowStatisticsFromFlowTableInput input) {
207
208         return handleServiceCall(new Function<RequestContext<GetAllFlowStatisticsFromFlowTableOutput>,
209                 ListenableFuture<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>>>() {
210
211             @Override
212             public ListenableFuture<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> apply(final RequestContext<GetAllFlowStatisticsFromFlowTableOutput> requestContext) {
213
214                 final MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
215                 mprFlowRequestBuilder.setTableId(input.getTableId().getValue());
216                 mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
217                 mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
218                 mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
219                 mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
220
221                 final short version = getVersion();
222                 FlowCreatorUtil.setWildcardedFlowMatch(version, mprFlowRequestBuilder);
223
224                 final MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
225                 multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
226
227                 final Xid xid = requestContext.getXid();
228                 final MultipartRequestInputBuilder mprInput = RequestInputUtils.createMultipartHeader(
229                         MultipartType.OFPMPFLOW, xid.getValue(), version);
230
231                 mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
232                 return StatisticsServiceUtil.getRpcResultListenableFuture(xid, mprInput.build(), getDeviceContext());
233             }
234         });
235     }
236
237     @Override
238     public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
239             final GetAllFlowsStatisticsFromAllFlowTablesInput input) {
240
241
242         return handleServiceCall(new Function<RequestContext<GetAllFlowsStatisticsFromAllFlowTablesOutput>,
243                 ListenableFuture<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>>>() {
244
245             @Override
246             public ListenableFuture<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> apply(final RequestContext<GetAllFlowsStatisticsFromAllFlowTablesOutput> requestContext) {
247
248                 final MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
249                 final MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
250                 mprFlowRequestBuilder.setTableId(OFConstants.OFPTT_ALL);
251                 mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
252                 mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
253                 mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
254                 mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
255                 final short version = getVersion();
256                 FlowCreatorUtil.setWildcardedFlowMatch(version, mprFlowRequestBuilder);
257
258                 final Xid xid = requestContext.getXid();
259                 final MultipartRequestInputBuilder mprInput = RequestInputUtils.createMultipartHeader(
260                         MultipartType.OFPMPFLOW, xid.getValue(), version);
261
262                 multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
263                 mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
264                 return StatisticsServiceUtil.getRpcResultListenableFuture(xid, mprInput.build(), getDeviceContext());
265             }
266         });
267     }
268
269     @Override
270     public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
271             final GetFlowStatisticsFromFlowTableInput input) {
272
273
274         return handleServiceCall(new Function<RequestContext<GetFlowStatisticsFromFlowTableOutput>, ListenableFuture<RpcResult<GetFlowStatisticsFromFlowTableOutput>>>() {
275
276             @Override
277             public ListenableFuture<RpcResult<GetFlowStatisticsFromFlowTableOutput>> apply(final RequestContext<GetFlowStatisticsFromFlowTableOutput> requestContext) {
278
279                 final MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
280                 final MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
281                 mprFlowRequestBuilder.setTableId(input.getTableId());
282
283                 if (input.getOutPort() != null) {
284                     mprFlowRequestBuilder.setOutPort(input.getOutPort().longValue());
285                 } else {
286                     mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
287                 }
288
289                 if (input.getOutGroup() != null) {
290                     mprFlowRequestBuilder.setOutGroup(input.getOutGroup());
291                 } else {
292                     mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
293                 }
294
295                 if (input.getCookie() != null) {
296                     mprFlowRequestBuilder.setCookie(input.getCookie().getValue());
297                 } else {
298                     mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
299                 }
300
301                 if (input.getCookieMask() != null) {
302                     mprFlowRequestBuilder.setCookieMask(input.getCookieMask().getValue());
303                 } else {
304                     mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
305                 }
306
307                 // convert and inject match
308                 final short version = getVersion();
309                 final DeviceContext deviceContext = getDeviceContext();
310                 MatchReactor.getInstance().convert(input.getMatch(), version, mprFlowRequestBuilder,
311                         deviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId());
312
313                 // Set request body to main multipart request
314                 final Xid xid = requestContext.getXid();
315                 multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
316                 final MultipartRequestInputBuilder mprInput = RequestInputUtils.createMultipartHeader(
317                         MultipartType.OFPMPFLOW, xid.getValue(), version);
318                 mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
319                 return StatisticsServiceUtil.getRpcResultListenableFuture(xid, mprInput.build(), getDeviceContext());
320             }
321         });
322     }
323
324 }