fix for BUG-956 - deadlock by rpc invocation
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / OFRpcTaskFactory.java
1 /**
2  * Copyright (c) 2013 Cisco Systems, Inc. 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 package org.opendaylight.openflowplugin.openflow.md.core.sal;
9
10 import java.math.BigInteger;
11 import java.util.concurrent.Future;
12 import java.util.concurrent.TimeUnit;
13
14 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowConvertor;
15 import org.opendaylight.openflowplugin.openflow.md.core.session.TransactionKey;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
22 import org.opendaylight.yangtools.yang.common.RpcResult;
23
24 /**
25  * 
26  */
27 public abstract class OFRpcTaskFactory {
28
29     /**
30      * @param maxTimeout 
31      * @param maxTimeoutUnit 
32      * @param helper 
33      * @return UpdateFlow task
34      */
35     public static OFRpcTask<AddFlowInput, RpcResult<UpdateFlowOutput>> createAddFlowTask(
36             final long maxTimeout, final TimeUnit maxTimeoutUnit, final OFRpcTaskHelper helper) {
37         OFRpcTask<AddFlowInput, RpcResult<UpdateFlowOutput>> task = 
38                 new OFRpcTask<AddFlowInput, RpcResult<UpdateFlowOutput>>() {
39             
40             @Override
41             public void run() {
42                 helper.rawBarrierSend(maxTimeout, maxTimeoutUnit, getInput().isBarrier(), getCookie(), getResult());
43                 if (getResult().isDone()) {
44                     return;
45                 }
46
47                 // Convert the AddFlowInput to FlowModInput
48                 FlowModInputBuilder ofFlowModInput = FlowConvertor.toFlowModInput(getInput(), 
49                         getVersion(), getSession().getFeatures().getDatapathId());
50                 Long xId = getSession().getNextXid();
51                 ofFlowModInput.setXid(xId);
52
53                 if (null != getRpcNotificationProviderService()) {
54                     FlowAddedBuilder newFlow = new FlowAddedBuilder(
55                             (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow) getInput());
56                     newFlow.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
57                     newFlow.setFlowRef(getInput().getFlowRef());
58                     getRpcNotificationProviderService().publish(newFlow.build());
59                 }
60
61                 getSession().getbulkTransactionCache().put(new TransactionKey(xId), getInput());
62                 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = 
63                         getMessageService().flowMod(ofFlowModInput.build(), getCookie());
64                 OFRpcTaskHelper.chainFutures(resultFromOFLib, getResult());
65             }
66         };
67         return task;
68     }
69     
70     /**
71      * @param maxTimeout 
72      * @param maxTimeoutUnit 
73      * @param helper 
74      * @return UpdateFlow task
75      */
76     public static OFRpcTask<UpdateFlowInput, RpcResult<UpdateFlowOutput>> createUpdateFlowTask(
77             final long maxTimeout, final TimeUnit maxTimeoutUnit, final OFRpcTaskHelper helper) {
78         OFRpcTask<UpdateFlowInput, RpcResult<UpdateFlowOutput>> task = 
79                 new OFRpcTask<UpdateFlowInput, RpcResult<UpdateFlowOutput>>() {
80             
81             @Override
82             public void run() {
83                 helper.rawBarrierSend(maxTimeout, maxTimeoutUnit, getInput().getUpdatedFlow().isBarrier(), getCookie(), getResult());
84                 if (getResult().isDone()) {
85                     return;
86                 }
87
88                 // Convert the AddFlowInput to FlowModInput
89                 FlowModInputBuilder ofFlowModInput = FlowConvertor.toFlowModInput(getInput().getUpdatedFlow(), 
90                         getVersion(), getSession().getFeatures().getDatapathId());
91                 Long xId = getSession().getNextXid();
92                 ofFlowModInput.setXid(xId);
93
94                 if (null != getRpcNotificationProviderService()) {
95                     FlowAddedBuilder newFlow = new FlowAddedBuilder(
96                             (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow) getInput());
97                     newFlow.setTransactionId(new TransactionId(BigInteger.valueOf(xId.intValue())));
98                     newFlow.setFlowRef(getInput().getFlowRef());
99                     getRpcNotificationProviderService().publish(newFlow.build());
100                 }
101
102                 getSession().getbulkTransactionCache().put(new TransactionKey(xId), getInput());
103                 Future<RpcResult<UpdateFlowOutput>> resultFromOFLib = 
104                         getMessageService().flowMod(ofFlowModInput.build(), getCookie());
105                 OFRpcTaskHelper.chainFutures(resultFromOFLib, getResult());
106             }
107         };
108         return task;
109     }
110     
111 }