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