2 * Copyright (c) 2017 Pantheon Technologies s.r.o. 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
9 package org.opendaylight.openflowplugin.impl.services.multilayer;
11 import com.google.common.base.MoreObjects;
12 import com.google.common.base.Preconditions;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import java.util.Optional;
17 import java.util.stream.Collectors;
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.RequestContextStack;
22 import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
23 import org.opendaylight.openflowplugin.api.openflow.device.Xid;
24 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
25 import org.opendaylight.openflowplugin.impl.services.AbstractAggregateFlowMultipartService;
26 import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
27 import org.opendaylight.openflowplugin.impl.util.FlowCreatorUtil;
28 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
29 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
30 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchInjector;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.aggregate.flow.statistics.from.flow.table._for.given.match.output.AggregatedFlowStatistics;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
42 import org.opendaylight.yangtools.yang.common.RpcResult;
43 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
44 import org.opendaylight.yangtools.yang.common.Uint32;
45 import org.opendaylight.yangtools.yang.common.Uint8;
47 public class MultiLayerAggregateFlowMultipartService extends AbstractAggregateFlowMultipartService<MultipartReply> {
49 private final TranslatorLibrary translatorLibrary;
50 private final ConvertorExecutor convertorExecutor;
51 private final VersionConvertorData data;
53 public MultiLayerAggregateFlowMultipartService(final RequestContextStack requestContextStack,
54 final DeviceContext deviceContext,
55 final ConvertorExecutor convertorExecutor,
56 final TranslatorLibrary translatorLibrary) {
57 super(requestContextStack, deviceContext);
58 this.convertorExecutor = convertorExecutor;
59 this.translatorLibrary = translatorLibrary;
60 this.data = new VersionConvertorData(getVersion());
65 protected OfHeader buildRequest(final Xid xid,
66 final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
67 final MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder
68 = new MultipartRequestAggregateCaseBuilder();
69 final MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
70 final Uint8 tableId = MoreObjects.firstNonNull(input.getTableId(), OFConstants.OFPTT_ALL);
71 mprAggregateRequestBuilder.setTableId(tableId);
72 long outputPortValue = MoreObjects.firstNonNull(input.getOutPort(), OFConstants.OFPP_ANY).longValue();
73 mprAggregateRequestBuilder.setOutPort(Uint32.valueOf(outputPortValue));
75 final Uint8 version = getVersion();
76 if (OFConstants.OFP_VERSION_1_3.equals(version)) {
78 if (input.getCookie() == null) {
79 mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
81 mprAggregateRequestBuilder
82 .setCookie(MoreObjects.firstNonNull(input.getCookie().getValue(), OFConstants.DEFAULT_COOKIE));
85 if (input.getCookieMask() == null) {
86 mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
88 mprAggregateRequestBuilder.setCookieMask(
89 MoreObjects.firstNonNull(input.getCookieMask().getValue(), OFConstants.DEFAULT_COOKIE_MASK));
91 Uint32 outGroup = MoreObjects.firstNonNull(input.getOutGroup(), OFConstants.OFPG_ANY);
92 mprAggregateRequestBuilder.setOutGroup(outGroup);
94 mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
95 mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
96 mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
99 // convert and inject match
100 final Optional<Object> conversionMatch = convertorExecutor.convert(input.getMatch(), data);
101 MatchInjector.inject(conversionMatch, mprAggregateRequestBuilder, data.getVersion());
103 FlowCreatorUtil.setWildcardedFlowMatch(version, mprAggregateRequestBuilder);
105 // Set request body to main multipart request
106 multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder.build());
108 final MultipartRequestInputBuilder mprInput = RequestInputUtils
109 .createMultipartHeader(MultipartType.OFPMPAGGREGATE, xid.getValue(), version);
111 mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
113 return mprInput.build();
117 public ListenableFuture<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> handleAndReply(
118 final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
119 return Futures.transform(handleServiceCall(input),
121 if (Preconditions.checkNotNull(result).isSuccessful()) {
122 final MessageTranslator<MultipartReply, AggregatedFlowStatistics>
123 messageTranslator = translatorLibrary.lookupTranslator(
124 new TranslatorKey(getVersion(),
125 MultipartReplyAggregateCase.class.getName()));
127 return RpcResultBuilder.success(
128 new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder()
129 .setAggregatedFlowStatistics(result.getResult().stream()
130 .map(multipartReply ->
141 return RpcResultBuilder
142 .<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>failed()
143 .withRpcErrors(result.getErrors()).build();
144 }, MoreExecutors.directExecutor());