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