Merge "Table update rpc added as provider"
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / session / MessageDispatchServiceImpl.java
1 package org.opendaylight.openflowplugin.openflow.md.core.session;
2
3 import java.math.BigInteger;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.concurrent.Future;
7
8  import org.opendaylight.controller.sal.common.util.Rpcs;
9 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
10 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
11 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutputBuilder;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutputBuilder;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInputBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInputBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutputBuilder;
47 import org.opendaylight.yangtools.yang.common.RpcError;
48 import org.opendaylight.yangtools.yang.common.RpcResult;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 import com.google.common.util.concurrent.Futures;
53
54 /**
55  * message dispatch service to send the message to switch.
56  *
57  * @author AnilGujele
58  *
59  */
60 public class MessageDispatchServiceImpl implements IMessageDispatchService {
61
62     private static final Logger LOG = LoggerFactory.getLogger(MessageDispatchServiceImpl.class);
63
64     private SessionContext session;
65
66     /**
67      * constructor
68      *
69      * @param session
70      *            - MessageDispatchService for this session
71      */
72     public MessageDispatchServiceImpl(SessionContext session) {
73         this.session = session;
74     }
75
76     /**
77      * get proper connection adapter to send the message to switch.
78      *
79      * @param cookie to identify the right connection, it can be null also.
80      * @return connectionAdapter associated with cookie, otherwise return best
81      *         suitable connection.
82      *
83      */
84
85     private ConnectionAdapter getConnectionAdapter(SwitchConnectionDistinguisher cookie) {
86
87         if (!session.isValid()) {
88             LOG.warn("Session for the cookie {} is invalid.", cookie);
89             throw new IllegalArgumentException("Session for the cookie is invalid.");
90         }
91         LOG.debug("finding connecton for cookie value {}. ", cookie);
92         // set main connection as default
93         ConnectionAdapter connectionAdapter = session.getPrimaryConductor().getConnectionAdapter();
94         if (null != cookie) {
95             ConnectionConductor conductor = session.getAuxiliaryConductor(cookie);
96             // check if auxiliary connection exist
97             if (null != conductor) {
98                 LOG.debug("found auxiliary connection for the cookie.");
99                 connectionAdapter = conductor.getConnectionAdapter();
100             }
101         } else {
102             // TODO: pick connection to utilize all the available connection.
103         }
104         return connectionAdapter;
105     }
106
107     @Override
108     public Future<RpcResult<BarrierOutput>> barrier(BarrierInput input, SwitchConnectionDistinguisher cookie) {
109         Long Xid = session.getNextXid();
110         BarrierInputBuilder inputBuilder = new BarrierInputBuilder(input);        
111         inputBuilder.setXid(Xid);
112         return getConnectionAdapter(cookie).barrier(inputBuilder.build());
113     }
114
115     @Override
116     public Future<RpcResult<Void>> experimenter(ExperimenterInput input, SwitchConnectionDistinguisher cookie) {
117         return getConnectionAdapter(cookie).experimenter(input);
118     }
119
120     @Override
121     public Future<RpcResult<UpdateFlowOutput>> flowMod(FlowModInput input, SwitchConnectionDistinguisher cookie) {
122
123         // Set Xid before invoking RPC on OFLibrary
124         // TODO : let caller set xid, in that case it will not be required to create FlowModInput again here to set xid 
125         Long Xid = session.getNextXid();
126         FlowModInputBuilder mdInput = new FlowModInputBuilder(input);
127         mdInput.setXid(Xid);
128         LOG.debug("Calling OFLibrary flowMod");
129         Future<RpcResult<Void>> response = getConnectionAdapter(cookie).flowMod(mdInput.build());
130
131         // Send the same Xid back to caller - MessageDrivenSwitch
132         UpdateFlowOutputBuilder flowModOutput = new UpdateFlowOutputBuilder();
133         String stringXid =Xid.toString();
134         BigInteger bigIntXid = new BigInteger( stringXid );
135         flowModOutput.setTransactionId(new TransactionId(bigIntXid));
136
137         UpdateFlowOutput result = flowModOutput.build();
138         Collection<RpcError> errors = Collections.emptyList();
139         RpcResult<UpdateFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
140
141         // solution 1: sending directly and hooking listener to get error
142         // hookup listener to catch the possible error with no reference to returned future-object
143         LOG.debug("Returning to ModelDrivenSwitch for flowMod RPC");
144         return Futures.immediateFuture(rpcResult);
145
146     }
147
148     @Override
149     public Future<RpcResult<GetAsyncOutput>> getAsync(GetAsyncInput input, SwitchConnectionDistinguisher cookie) {
150         return getConnectionAdapter(cookie).getAsync(input);
151     }
152
153     @Override
154     public Future<RpcResult<GetConfigOutput>> getConfig(GetConfigInput input, SwitchConnectionDistinguisher cookie) {
155         return getConnectionAdapter(cookie).getConfig(input);
156     }
157
158     @Override
159     public Future<RpcResult<GetFeaturesOutput>> getFeatures(GetFeaturesInput input, SwitchConnectionDistinguisher cookie) {
160         return getConnectionAdapter(cookie).getFeatures(input);
161     }
162
163     @Override
164     public Future<RpcResult<GetQueueConfigOutput>> getQueueConfig(GetQueueConfigInput input,
165             SwitchConnectionDistinguisher cookie) {
166         return getConnectionAdapter(cookie).getQueueConfig(input);
167     }
168
169     @Override
170     public Future<RpcResult<UpdateGroupOutput>> groupMod(GroupModInput input, SwitchConnectionDistinguisher cookie) {
171
172         // Set Xid before invoking RPC on OFLibrary
173         // TODO : let caller set xid, in that case it will not be required to create object again here to set xid 
174         Long Xid = session.getNextXid();
175         GroupModInputBuilder mdInput = new GroupModInputBuilder(input);
176         mdInput.setXid(Xid);
177         LOG.debug("Calling OFLibrary groupMod");
178         Future<RpcResult<Void>> response = getConnectionAdapter(cookie).groupMod(mdInput.build());
179
180         // Send the same Xid back to caller - MessageDrivenSwitch
181         UpdateGroupOutputBuilder groupModOutput = new UpdateGroupOutputBuilder();
182         String stringXid =Xid.toString();
183         BigInteger bigIntXid = new BigInteger( stringXid );
184         groupModOutput.setTransactionId(new TransactionId(bigIntXid));
185        
186         UpdateGroupOutput result = groupModOutput.build();
187         Collection<RpcError> errors = Collections.emptyList();
188         RpcResult<UpdateGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
189
190         // solution 1: sending directly and hooking listener to get error
191         // hookup listener to catch the possible error with no reference to returned future-object
192         LOG.debug("Returning to ModelDrivenSwitch for groupMod RPC");
193         return Futures.immediateFuture(rpcResult);
194
195     }
196
197     @Override
198     public Future<RpcResult<UpdateMeterOutput>> meterMod(MeterModInput input, SwitchConnectionDistinguisher cookie) {
199
200         // Set Xid before invoking RPC on OFLibrary
201      // TODO : let caller set xid, in that case it will not be required to create MeterModInput again here to set xid 
202         Long Xid = session.getNextXid();
203         MeterModInputBuilder mdInput = new MeterModInputBuilder(input);
204         mdInput.setXid(Xid);
205         LOG.debug("Calling OFLibrary meterMod");
206         Future<RpcResult<Void>> response = getConnectionAdapter(cookie).meterMod(mdInput.build());
207
208         // Send the same Xid back to caller - MessageDrivenSwitch
209         UpdateMeterOutputBuilder meterModOutput = new UpdateMeterOutputBuilder();
210         String stringXid =Xid.toString();
211         BigInteger bigIntXid = new BigInteger( stringXid );
212         meterModOutput.setTransactionId(new TransactionId(bigIntXid));
213         
214         UpdateMeterOutput result = meterModOutput.build();
215         Collection<RpcError> errors = Collections.emptyList();
216         RpcResult<UpdateMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
217
218         // solution 1: sending directly and hooking listener to get error
219         // hookup listener to catch the possible error with no reference to returned future-object
220         LOG.debug("Returning to ModelDrivenSwitch for meterMod RPC");
221         return Futures.immediateFuture(rpcResult);
222
223     }
224
225     @Override
226     public Future<RpcResult<java.lang.Void>> multipartRequest(MultipartRequestInput input, SwitchConnectionDistinguisher cookie) {
227         return getConnectionAdapter(cookie).multipartRequest(input);
228     }
229
230     @Override
231     public Future<RpcResult<Void>> packetOut(PacketOutInput input, SwitchConnectionDistinguisher cookie) {
232         return getConnectionAdapter(cookie).packetOut(input);
233     }
234
235     @Override
236     public Future<RpcResult<UpdatePortOutput>> portMod(PortModInput input, SwitchConnectionDistinguisher cookie) {
237
238         LOG.debug("Calling OFLibrary portMod");
239         Future<RpcResult<Void>> response = getConnectionAdapter(cookie).portMod(input);
240
241         // Send the same Xid back to caller - ModelDrivenSwitch
242         UpdatePortOutputBuilder portModOutput = new UpdatePortOutputBuilder();
243         String stringXid =input.getXid().toString();
244         BigInteger bigIntXid = new BigInteger( stringXid );
245         portModOutput.setTransactionId(new TransactionId(bigIntXid));
246         UpdatePortOutput result = portModOutput.build();
247         Collection<RpcError> errors = Collections.emptyList();
248         RpcResult<UpdatePortOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
249
250         LOG.debug("Returning to ModelDrivenSwitch for portMod RPC");
251         return Futures.immediateFuture(rpcResult);
252     }
253
254     @Override
255     public Future<RpcResult<RoleRequestOutput>> roleRequest(RoleRequestInput input, SwitchConnectionDistinguisher cookie) {
256         return getConnectionAdapter(cookie).roleRequest(input);
257     }
258
259     @Override
260     public Future<RpcResult<Void>> setAsync(SetAsyncInput input, SwitchConnectionDistinguisher cookie) {
261         return getConnectionAdapter(cookie).setAsync(input);
262     }
263
264     @Override
265     public Future<RpcResult<Void>> setConfig(SetConfigInput input, SwitchConnectionDistinguisher cookie) {
266         return getConnectionAdapter(cookie).setConfig(input);
267     }
268
269     @Override
270     public Future<RpcResult<Void>> tableMod(TableModInput input, SwitchConnectionDistinguisher cookie) {
271         return getConnectionAdapter(cookie).tableMod(input);
272     }
273 }