2 * Copyright (c) 2013 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.openflow.md.core.sal;
10 import java.util.Collection;
11 import java.util.Collections;
12 import java.util.concurrent.Future;
14 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
15 import org.opendaylight.controller.sal.common.util.RpcErrors;
16 import org.opendaylight.controller.sal.common.util.Rpcs;
17 import org.opendaylight.openflowplugin.openflow.md.OFConstants;
18 import org.opendaylight.openflowplugin.openflow.md.core.MessageFactory;
19 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
20 import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService;
21 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
22 import org.opendaylight.openflowplugin.openflow.md.queue.MessageSpy;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
25 import org.opendaylight.yangtools.yang.binding.DataContainer;
26 import org.opendaylight.yangtools.yang.binding.Notification;
27 import org.opendaylight.yangtools.yang.common.RpcError;
28 import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
29 import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
30 import org.opendaylight.yangtools.yang.common.RpcResult;
32 import com.google.common.base.Objects;
33 import com.google.common.collect.Lists;
34 import com.google.common.util.concurrent.FutureCallback;
35 import com.google.common.util.concurrent.Futures;
36 import com.google.common.util.concurrent.ListenableFuture;
37 import com.google.common.util.concurrent.SettableFuture;
42 public abstract class OFRpcTaskUtil {
48 * @return rpcResult of given type, containing wrapped errors of barrier sending (if any) or success
50 public static Collection<RpcError> manageBarrier(OFRpcTaskContext taskContext, Boolean isBarrier,
51 SwitchConnectionDistinguisher cookie) {
52 Collection<RpcError> errors = null;
53 if (Objects.firstNonNull(isBarrier, Boolean.FALSE)) {
54 Future<RpcResult<BarrierOutput>> barrierFuture = sendBarrier(taskContext.getSession(), cookie, taskContext.getMessageService());
56 RpcResult<BarrierOutput> barrierResult = barrierFuture.get(
57 taskContext.getMaxTimeout(), taskContext.getMaxTimeoutUnit());
58 if (!barrierResult.isSuccessful()) {
59 errors = barrierResult.getErrors();
61 } catch (Exception e) {
62 RpcError rpcError = RpcErrors.getRpcError(
63 OFConstants.APPLICATION_TAG, OFConstants.ERROR_TAG_TIMEOUT,
64 "barrier sending failed", ErrorSeverity.WARNING,
65 "switch failed to respond on barrier request - message ordering is not preserved", ErrorType.RPC, e);
66 errors = Lists.newArrayList(rpcError);
71 errors = Collections.emptyList();
80 * @param messageService
81 * @return barrier response
83 private static Future<RpcResult<BarrierOutput>> sendBarrier(SessionContext session,
84 SwitchConnectionDistinguisher cookie, IMessageDispatchService messageService) {
85 BarrierInput barrierInput = MessageFactory.createBarrier(
86 session.getFeatures().getVersion(), session.getNextXid());
87 return messageService.barrier(barrierInput, cookie);
91 * @param result rpcResult with success = false, errors = given collection
92 * @param barrierErrors
94 public static <T> void wrapBarrierErrors(SettableFuture<RpcResult<T>> result,
95 Collection<RpcError> barrierErrors) {
96 result.set(Rpcs.<T>getRpcResult(false, barrierErrors));
101 * @param originalResult
102 * @param notificationProviderService
103 * @param notificationComposer lazy notification composer
105 public static <R, N extends Notification, INPUT extends DataContainer> void hookFutureNotification(
106 final OFRpcTask<INPUT, R> task,
107 ListenableFuture<R> originalResult,
108 final NotificationProviderService notificationProviderService,
109 final NotificationComposer<N> notificationComposer) {
110 Futures.addCallback(originalResult, new FutureCallback<R>() {
112 public void onSuccess(R result) {
113 if (null != notificationProviderService) {
114 notificationProviderService.publish(notificationComposer.compose());
116 task.getTaskContext().getMessageSpy().spyMessage(
117 task.getInput(), MessageSpy.STATISTIC_GROUP.TO_SWITCH_SUBMITTED_SUCCESS);
121 public void onFailure(Throwable t) {
122 task.getTaskContext().getMessageSpy().spyMessage(
123 task.getInput(), MessageSpy.STATISTIC_GROUP.TO_SWITCH_SUBMITTED_FAILURE);