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.services;
10 import com.google.common.util.concurrent.Service;
11 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
12 import java.util.Collections;
13 import java.util.List;
14 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
15 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
16 import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
17 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
18 import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
19 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
20 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
21 import org.opendaylight.openflowplugin.impl.common.MultipartReplyTranslatorUtil;
22 import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
23 import org.opendaylight.openflowplugin.impl.statistics.StatisticsGatheringUtils;
24 import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
25 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.opendaylight.yangtools.yang.common.ErrorType;
31 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
35 public abstract class AbstractMultipartRequestOnTheFlyCallback<T extends OfHeader>
36 extends AbstractMultipartRequestCallback<T> {
37 private static final Logger LOG = LoggerFactory.getLogger(AbstractMultipartRequestOnTheFlyCallback.class);
39 private final DeviceInfo deviceInfo;
40 private final EventIdentifier doneEventIdentifier;
41 private final TxFacade txFacade;
42 private final MultipartWriterProvider statisticsWriterProvider;
43 private final DeviceRegistry deviceRegistry;
44 private final ConvertorExecutor convertorExecutor;
46 private volatile Service.State gatheringState = Service.State.NEW;
48 @SuppressFBWarnings(value = "MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR",
49 justification = "getMultipartType() should be okay to call")
50 public AbstractMultipartRequestOnTheFlyCallback(final RequestContext<List<T>> context, final Class<?> requestType,
51 final DeviceContext deviceContext,
52 final EventIdentifier eventIdentifier,
53 final MultipartWriterProvider statisticsWriterProvider,
54 final ConvertorExecutor convertorExecutor) {
55 super(context, requestType, deviceContext, eventIdentifier);
56 deviceInfo = deviceContext.getDeviceInfo();
58 new EventIdentifier(getMultipartType().name(), deviceContext.getDeviceInfo().getNodeId().toString());
59 txFacade = deviceContext;
60 deviceRegistry = deviceContext;
61 this.statisticsWriterProvider = statisticsWriterProvider;
62 this.convertorExecutor = convertorExecutor;
66 @SuppressWarnings({"unchecked", "checkstyle:IllegalCatch"})
67 public void onSuccess(final OfHeader result) {
69 LOG.warn("Response received was null.");
71 if (!Service.State.TERMINATED.equals(gatheringState)) {
76 } else if (Service.State.TERMINATED.equals(gatheringState)) {
77 LOG.warn("Unexpected response received: xid={}, {}", result.getXid(), result.implementedInterface());
81 if (!isMultipart(result)) {
82 LOG.warn("Unexpected response type received: {}.", result.getClass());
83 setResult(RpcResultBuilder.<List<T>>failed().withError(ErrorType.APPLICATION,
84 String.format("Unexpected response type received: %s.", result.getClass())).build());
87 final T resultCast = (T) result;
89 if (Service.State.NEW.equals(gatheringState)) {
94 MultipartReplyTranslatorUtil
95 .translate(resultCast, deviceInfo, convertorExecutor, null)
98 statisticsWriterProvider
99 .lookup(getMultipartType())
100 .ifPresent(writer -> writer.write(reply, false));
101 } catch (final Exception ex) {
102 LOG.warn("Stats processing of type {} for node {} failed during write-to-tx step",
103 getMultipartType(), deviceInfo, ex);
106 } catch (final Exception ex) {
107 LOG.warn("Unexpected exception occurred while translating response: {}.", result.getClass(), ex);
108 setResult(RpcResultBuilder.<List<T>>failed().withError(ErrorType.APPLICATION,
109 String.format("Unexpected exception occurred while translating response: %s. %s",
112 endCollecting(false);
116 if (!isReqMore(resultCast)) {
126 protected TxFacade getTxFacade() {
131 * Starts collecting of multipart data.
133 private synchronized void startCollecting() {
134 EventsTimeCounter.markStart(doneEventIdentifier);
135 gatheringState = Service.State.RUNNING;
137 final InstanceIdentifier<FlowCapableNode> instanceIdentifier = deviceInfo
138 .getNodeInstanceIdentifier()
139 .augmentation(FlowCapableNode.class);
141 switch (getMultipartType()) {
143 StatisticsGatheringUtils.deleteAllKnownFlows(
146 deviceRegistry.getDeviceFlowRegistry());
147 deviceRegistry.getDeviceFlowRegistry().processMarks();
149 case OFPMPMETERCONFIG:
150 StatisticsGatheringUtils.deleteAllKnownMeters(
153 deviceRegistry.getDeviceMeterRegistry());
154 deviceRegistry.getDeviceMeterRegistry().processMarks();
157 StatisticsGatheringUtils.deleteAllKnownGroups(
160 deviceRegistry.getDeviceGroupRegistry());
161 deviceRegistry.getDeviceGroupRegistry().processMarks();
169 * Ends collecting of multipart data.
170 * @param setResult set empty success result
172 private void endCollecting(final boolean setResult) {
173 gatheringState = Service.State.TERMINATED;
174 EventsTimeCounter.markEnd(doneEventIdentifier);
175 EventsTimeCounter.markEnd(getEventIdentifier());
176 spyMessage(MessageSpy.StatisticsGroup.FROM_SWITCH_TRANSLATE_OUT_SUCCESS);
179 setResult(RpcResultBuilder.success(Collections.<T>emptyList()).build());
182 txFacade.submitTransaction();
184 switch (getMultipartType()) {
186 deviceRegistry.getDeviceFlowRegistry().processMarks();
188 case OFPMPMETERCONFIG:
189 deviceRegistry.getDeviceMeterRegistry().processMarks();
192 deviceRegistry.getDeviceGroupRegistry().processMarks();
200 * Get multipart type.
201 * @return multipart type
203 protected abstract MultipartType getMultipartType();