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 java.util.Collections;
12 import java.util.List;
13 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
14 import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
15 import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
16 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
17 import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
18 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
19 import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
20 import org.opendaylight.openflowplugin.impl.common.MultipartReplyTranslatorUtil;
21 import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
22 import org.opendaylight.openflowplugin.impl.statistics.StatisticsGatheringUtils;
23 import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
24 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
29 import org.opendaylight.yangtools.yang.common.RpcError;
30 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 public abstract class AbstractMultipartRequestOnTheFlyCallback<T extends OfHeader>
35 extends AbstractMultipartRequestCallback<T> {
36 private static final Logger LOG = LoggerFactory.getLogger(AbstractMultipartRequestOnTheFlyCallback.class);
37 private final DeviceInfo deviceInfo;
38 private final EventIdentifier doneEventIdentifier;
39 private final TxFacade txFacade;
40 private final MultipartWriterProvider statisticsWriterProvider;
41 private final DeviceRegistry deviceRegistry;
42 private volatile Service.State gatheringState = Service.State.NEW;
43 private final ConvertorExecutor convertorExecutor;
45 public AbstractMultipartRequestOnTheFlyCallback(final RequestContext<List<T>> context, Class<?> requestType,
46 final DeviceContext deviceContext,
47 final EventIdentifier eventIdentifier,
48 final MultipartWriterProvider statisticsWriterProvider,
49 final ConvertorExecutor convertorExecutor) {
50 super(context, requestType, deviceContext, eventIdentifier);
51 deviceInfo = deviceContext.getDeviceInfo();
53 new EventIdentifier(getMultipartType().name(), deviceContext.getDeviceInfo().getNodeId().toString());
54 txFacade = deviceContext;
55 deviceRegistry = deviceContext;
56 this.statisticsWriterProvider = statisticsWriterProvider;
57 this.convertorExecutor = convertorExecutor;
61 @SuppressWarnings({"unchecked", "checkstyle:IllegalCatch"})
62 public void onSuccess(final OfHeader result) {
64 LOG.warn("Response received was null.");
66 if (!Service.State.TERMINATED.equals(gatheringState)) {
71 } else if (Service.State.TERMINATED.equals(gatheringState)) {
72 LOG.warn("Unexpected response received: xid={}, {}", result.getXid(), result.implementedInterface());
76 if (!isMultipart(result)) {
77 LOG.warn("Unexpected response type received: {}.", result.getClass());
78 setResult(RpcResultBuilder.<List<T>>failed().withError(RpcError.ErrorType.APPLICATION,
79 String.format("Unexpected response type received: %s.", result.getClass())).build());
82 final T resultCast = (T) result;
84 if (Service.State.NEW.equals(gatheringState)) {
89 MultipartReplyTranslatorUtil
90 .translate(resultCast, deviceInfo, convertorExecutor, null)
93 statisticsWriterProvider
94 .lookup(getMultipartType())
95 .ifPresent(writer -> writer.write(reply, false));
96 } catch (final Exception ex) {
97 LOG.warn("Stats processing of type {} for node {} failed during write-to-tx step",
98 getMultipartType(), deviceInfo, ex);
101 } catch (final Exception ex) {
102 LOG.warn("Unexpected exception occurred while translating response: {}.", result.getClass(), ex);
103 setResult(RpcResultBuilder.<List<T>>failed().withError(RpcError.ErrorType.APPLICATION,
104 String.format("Unexpected exception occurred while translating response: %s. %s",
107 endCollecting(false);
111 if (!isReqMore(resultCast)) {
121 protected TxFacade getTxFacade() {
126 * Starts collecting of multipart data.
128 private synchronized void startCollecting() {
129 EventsTimeCounter.markStart(doneEventIdentifier);
130 gatheringState = Service.State.RUNNING;
132 final InstanceIdentifier<FlowCapableNode> instanceIdentifier = deviceInfo
133 .getNodeInstanceIdentifier()
134 .augmentation(FlowCapableNode.class);
136 switch (getMultipartType()) {
138 StatisticsGatheringUtils.deleteAllKnownFlows(
141 deviceRegistry.getDeviceFlowRegistry());
142 deviceRegistry.getDeviceFlowRegistry().processMarks();
144 case OFPMPMETERCONFIG:
145 StatisticsGatheringUtils.deleteAllKnownMeters(
148 deviceRegistry.getDeviceMeterRegistry());
149 deviceRegistry.getDeviceMeterRegistry().processMarks();
152 StatisticsGatheringUtils.deleteAllKnownGroups(
155 deviceRegistry.getDeviceGroupRegistry());
156 deviceRegistry.getDeviceGroupRegistry().processMarks();
164 * Ends collecting of multipart data.
165 * @param setResult set empty success result
167 private void endCollecting(final boolean setResult) {
168 gatheringState = Service.State.TERMINATED;
169 EventsTimeCounter.markEnd(doneEventIdentifier);
170 EventsTimeCounter.markEnd(getEventIdentifier());
171 spyMessage(MessageSpy.StatisticsGroup.FROM_SWITCH_TRANSLATE_OUT_SUCCESS);
174 setResult(RpcResultBuilder.success(Collections.<T>emptyList()).build());
177 txFacade.submitTransaction();
179 switch (getMultipartType()) {
181 deviceRegistry.getDeviceFlowRegistry().processMarks();
183 case OFPMPMETERCONFIG:
184 deviceRegistry.getDeviceMeterRegistry().processMarks();
187 deviceRegistry.getDeviceGroupRegistry().processMarks();
195 * Get multipart type.
196 * @return multipart type
198 protected abstract MultipartType getMultipartType();