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