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