3093bc4302a5b0214b18d4efe56899dffa88816c
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / services / multilayer / MultiLayerAggregateFlowMultipartService.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. 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
9 package org.opendaylight.openflowplugin.impl.services.multilayer;
10
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;
46
47 public class MultiLayerAggregateFlowMultipartService extends AbstractAggregateFlowMultipartService<MultipartReply> {
48
49     private final TranslatorLibrary translatorLibrary;
50     private final ConvertorExecutor convertorExecutor;
51     private final VersionConvertorData data;
52
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());
61     }
62
63
64     @Override
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));
74
75         final Uint8 version = getVersion();
76         if (OFConstants.OFP_VERSION_1_3.equals(version)) {
77
78             if (input.getCookie() == null) {
79                 mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
80             } else {
81                 mprAggregateRequestBuilder
82                         .setCookie(MoreObjects.firstNonNull(input.getCookie().getValue(), OFConstants.DEFAULT_COOKIE));
83             }
84
85             if (input.getCookieMask() == null) {
86                 mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
87             } else {
88                 mprAggregateRequestBuilder.setCookieMask(
89                         MoreObjects.firstNonNull(input.getCookieMask().getValue(), OFConstants.DEFAULT_COOKIE_MASK));
90             }
91             Uint32 outGroup = MoreObjects.firstNonNull(input.getOutGroup(), OFConstants.OFPG_ANY);
92             mprAggregateRequestBuilder.setOutGroup(outGroup);
93         } else {
94             mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
95             mprAggregateRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
96             mprAggregateRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
97         }
98
99         // convert and inject match
100         final Optional<Object> conversionMatch = convertorExecutor.convert(input.getMatch(), data);
101         MatchInjector.inject(conversionMatch, mprAggregateRequestBuilder, data.getVersion());
102
103         FlowCreatorUtil.setWildcardedFlowMatch(version, mprAggregateRequestBuilder);
104
105         // Set request body to main multipart request
106         multipartRequestAggregateCaseBuilder.setMultipartRequestAggregate(mprAggregateRequestBuilder.build());
107
108         final MultipartRequestInputBuilder mprInput = RequestInputUtils
109                 .createMultipartHeader(MultipartType.OFPMPAGGREGATE, xid.getValue(), version);
110
111         mprInput.setMultipartRequestBody(multipartRequestAggregateCaseBuilder.build());
112
113         return mprInput.build();
114     }
115
116     @Override
117     public ListenableFuture<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> handleAndReply(
118             final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
119         return Futures.transform(handleServiceCall(input),
120             result -> {
121                 if (Preconditions.checkNotNull(result).isSuccessful()) {
122                     final MessageTranslator<MultipartReply, AggregatedFlowStatistics>
123                              messageTranslator = translatorLibrary.lookupTranslator(
124                                  new TranslatorKey(getVersion(),
125                                                MultipartReplyAggregateCase.class.getName()));
126
127                     return RpcResultBuilder.success(
128                              new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder()
129                                      .setAggregatedFlowStatistics(result.getResult().stream()
130                                                                           .map(multipartReply ->
131                                                                                        messageTranslator
132                                                                                   .translate(
133                                                                                           multipartReply,
134                                                                                           getDeviceInfo(),
135                                                                                           null))
136                                                                           .collect(Collectors
137                                                                                            .toList())))
138                              .build();
139                 }
140
141                 return RpcResultBuilder
142                              .<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>failed()
143                              .withRpcErrors(result.getErrors()).build();
144             }, MoreExecutors.directExecutor());
145     }
146 }