2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.openflowplugin.impl.statistics.services;
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;
61 public class OpendaylightFlowStatisticsServiceImpl extends CommonService implements OpendaylightFlowStatisticsService {
63 private static final Logger LOG = LoggerFactory.getLogger(OpendaylightFlowStatisticsServiceImpl.class);
65 public OpendaylightFlowStatisticsServiceImpl(final RequestContextStack requestContextStack, DeviceContext deviceContext) {
66 super(requestContextStack, deviceContext);
70 public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>> getAggregateFlowStatisticsFromFlowTableForAllFlows(
71 final GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput input) {
74 return this.<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput, Void>handleServiceCall(
75 new Function<RequestContext<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput>, ListenableFuture<RpcResult<Void>>>() {
78 public ListenableFuture<RpcResult<Void>> apply(final RequestContext<GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput> requestContext) {
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);
91 // Set request body to main multipart request
92 multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder
94 final Xid xid = requestContext.getXid();
95 final MultipartRequestInputBuilder mprInput = RequestInputUtils.createMultipartHeader(
96 MultipartType.OFPMPAGGREGATE, xid.getValue(), version);
98 mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
100 final Future<RpcResult<Void>> resultFromOFLib = getDeviceContext().getPrimaryConnectionContext()
101 .getConnectionAdapter().multipartRequest(mprInput.build());
103 return JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
110 public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
111 final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
114 ListenableFuture<RpcResult<List<MultipartReply>>> rpcResultListenableFuture = handleServiceCall(
115 new Function<RequestContext<List<MultipartReply>>, ListenableFuture<RpcResult<Void>>>() {
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
130 final short version = getVersion();
131 if (version == OFConstants.OFP_VERSION_1_3) {
133 if (input.getCookie() == null) {
134 mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
136 mprAggregateRequestBuilder.setCookie(MoreObjects.firstNonNull(input.getCookie().getValue(), OFConstants.DEFAULT_COOKIE));
139 if (input.getCookieMask() == null) {
140 mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
142 mprAggregateRequestBuilder.setCookieMask(MoreObjects.firstNonNull(input.getCookieMask().getValue(), OFConstants.DEFAULT_COOKIE_MASK));
144 long outGroup = MoreObjects.firstNonNull(input.getOutGroup(), OFConstants.OFPG_ANY).longValue();
145 mprAggregateRequestBuilder.setOutGroup(outGroup);
147 mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
148 mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
149 mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
152 MatchReactor.getInstance().convert(input.getMatch(), version, mprAggregateRequestBuilder,
153 deviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId());
155 FlowCreatorUtil.setWildcardedFlowMatch(version, mprAggregateRequestBuilder);
157 // Set request body to main multipart request
158 multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder
161 final MultipartRequestInputBuilder mprInput = RequestInputUtils.createMultipartHeader(
162 MultipartType.OFPMPAGGREGATE, xid.getValue(), version);
164 mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
165 final Future<RpcResult<Void>> resultFromOFLib = deviceContext.getPrimaryConnectionContext()
166 .getConnectionAdapter().multipartRequest(mprInput.build());
167 return JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
171 return Futures.transform(rpcResultListenableFuture, new Function<RpcResult<List<MultipartReply>>, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>>() {
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>();
184 for (MultipartReply multipartReply : input.getResult()) {
185 aggregStats.add(messageTranslator.translate(multipartReply, deviceContext, null));
188 GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder =
189 new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder();
190 getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder.setAggregatedFlowStatistics(aggregStats);
192 rpcResult = RpcResultBuilder
193 .<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>success()
194 .withResult(getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder.build())
198 rpcResult = RpcResultBuilder
199 .<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>failed()
200 .withRpcErrors(input.getErrors())
210 public Future<RpcResult<GetAllFlowStatisticsFromFlowTableOutput>> getAllFlowStatisticsFromFlowTable(
211 final GetAllFlowStatisticsFromFlowTableInput input) {
213 return this.<GetAllFlowStatisticsFromFlowTableOutput, Void>handleServiceCall(new Function<RequestContext<GetAllFlowStatisticsFromFlowTableOutput>, ListenableFuture<RpcResult<Void>>>() {
216 public ListenableFuture<RpcResult<Void>> apply(final RequestContext<GetAllFlowStatisticsFromFlowTableOutput> requestContext) {
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);
225 final short version = getVersion();
226 FlowCreatorUtil.setWildcardedFlowMatch(version, mprFlowRequestBuilder);
228 final MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
229 multipartRequestFlowCaseBuilder.setMultipartRequestFlow(mprFlowRequestBuilder.build());
231 final Xid xid = requestContext.getXid();
232 final MultipartRequestInputBuilder mprInput = RequestInputUtils.createMultipartHeader(
233 MultipartType.OFPMPFLOW, xid.getValue(), version);
235 mprInput.setMultipartRequestBody(multipartRequestFlowCaseBuilder.build());
236 final Future<RpcResult<Void>> resultFromOFLib = getDeviceContext().getPrimaryConnectionContext()
237 .getConnectionAdapter().multipartRequest(mprInput.build());
238 return JdkFutureAdapters.listenInPoolThread(resultFromOFLib);
244 public Future<RpcResult<GetAllFlowsStatisticsFromAllFlowTablesOutput>> getAllFlowsStatisticsFromAllFlowTables(
245 final GetAllFlowsStatisticsFromAllFlowTablesInput input) {
248 return this.<GetAllFlowsStatisticsFromAllFlowTablesOutput, Void>handleServiceCall(new Function<RequestContext<GetAllFlowsStatisticsFromAllFlowTablesOutput>, ListenableFuture<RpcResult<Void>>>() {
251 public ListenableFuture<RpcResult<Void>> apply(final RequestContext<GetAllFlowsStatisticsFromAllFlowTablesOutput> requestContext) {
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);
263 final Xid xid = requestContext.getXid();
264 final MultipartRequestInputBuilder mprInput = RequestInputUtils.createMultipartHeader(
265 MultipartType.OFPMPFLOW, xid.getValue(), version);
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);
277 public Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> getFlowStatisticsFromFlowTable(
278 final GetFlowStatisticsFromFlowTableInput input) {
281 return this.<GetFlowStatisticsFromFlowTableOutput, Void>handleServiceCall(new Function<RequestContext<GetFlowStatisticsFromFlowTableOutput>, ListenableFuture<RpcResult<Void>>>() {
284 public ListenableFuture<RpcResult<Void>> apply(final RequestContext<GetFlowStatisticsFromFlowTableOutput> requestContext) {
286 final MultipartRequestFlowCaseBuilder multipartRequestFlowCaseBuilder = new MultipartRequestFlowCaseBuilder();
287 final MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
288 mprFlowRequestBuilder.setTableId(input.getTableId());
290 if (input.getOutPort() != null) {
291 mprFlowRequestBuilder.setOutPort(input.getOutPort().longValue());
293 mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
296 if (input.getOutGroup() != null) {
297 mprFlowRequestBuilder.setOutGroup(input.getOutGroup());
299 mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
302 if (input.getCookie() != null) {
303 mprFlowRequestBuilder.setCookie(input.getCookie().getValue());
305 mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
308 if (input.getCookieMask() != null) {
309 mprFlowRequestBuilder.setCookieMask(input.getCookieMask().getValue());
311 mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
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());
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);
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);