1 package org.opendaylight.openflowplugin.openflow.md.core.session;
3 import java.math.BigInteger;
4 import java.util.Collection;
5 import java.util.Collections;
6 import java.util.concurrent.Future;
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;
51 import com.google.common.util.concurrent.Futures;
54 * message dispatch service to send the message to switch.
59 public class MessageDispatchServiceImpl implements IMessageDispatchService {
61 private static final Logger LOG = LoggerFactory.getLogger(MessageDispatchServiceImpl.class);
63 private SessionContext session;
69 * - MessageDispatchService for this session
71 public MessageDispatchServiceImpl(SessionContext session) {
72 this.session = session;
76 * get proper connection adapter to send the message to switch.
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.
84 private ConnectionAdapter getConnectionAdapter(SwitchConnectionDistinguisher cookie) {
86 if (!session.isValid()) {
87 LOG.warn("Session for the cookie {} is invalid.", cookie);
88 throw new IllegalArgumentException("Session for the cookie is invalid.");
90 LOG.debug("finding connecton for cookie value {}. ", cookie);
91 // set main connection as default
92 ConnectionAdapter connectionAdapter = session.getPrimaryConductor().getConnectionAdapter();
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();
101 // TODO: pick connection to utilize all the available connection.
103 return connectionAdapter;
107 public Future<RpcResult<BarrierOutput>> barrier(BarrierInput input, SwitchConnectionDistinguisher cookie) {
108 return getConnectionAdapter(cookie).barrier(input);
112 public Future<RpcResult<Void>> experimenter(ExperimenterInput input, SwitchConnectionDistinguisher cookie) {
113 return getConnectionAdapter(cookie).experimenter(input);
117 public Future<RpcResult<UpdateFlowOutput>> flowMod(FlowModInput input, SwitchConnectionDistinguisher cookie) {
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(input);
124 LOG.debug("Calling OFLibrary flowMod");
125 Future<RpcResult<Void>> response = getConnectionAdapter(cookie).flowMod(mdInput.build());
127 // Send the same Xid back to caller - MessageDrivenSwitch
128 UpdateFlowOutputBuilder flowModOutput = new UpdateFlowOutputBuilder();
129 String stringXid =Xid.toString();
130 BigInteger bigIntXid = new BigInteger( stringXid );
131 flowModOutput.setTransactionId(new TransactionId(bigIntXid));
133 UpdateFlowOutput result = flowModOutput.build();
134 Collection<RpcError> errors = Collections.emptyList();
135 RpcResult<UpdateFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
137 // solution 1: sending directly and hooking listener to get error
138 // hookup listener to catch the possible error with no reference to returned future-object
139 LOG.debug("Returning to ModelDrivenSwitch for flowMod RPC");
140 return Futures.immediateFuture(rpcResult);
145 public Future<RpcResult<GetAsyncOutput>> getAsync(GetAsyncInput input, SwitchConnectionDistinguisher cookie) {
146 return getConnectionAdapter(cookie).getAsync(input);
150 public Future<RpcResult<GetConfigOutput>> getConfig(GetConfigInput input, SwitchConnectionDistinguisher cookie) {
151 return getConnectionAdapter(cookie).getConfig(input);
155 public Future<RpcResult<GetFeaturesOutput>> getFeatures(GetFeaturesInput input, SwitchConnectionDistinguisher cookie) {
156 return getConnectionAdapter(cookie).getFeatures(input);
160 public Future<RpcResult<GetQueueConfigOutput>> getQueueConfig(GetQueueConfigInput input,
161 SwitchConnectionDistinguisher cookie) {
162 return getConnectionAdapter(cookie).getQueueConfig(input);
166 public Future<RpcResult<UpdateGroupOutput>> groupMod(GroupModInput input, SwitchConnectionDistinguisher cookie) {
168 // Set Xid before invoking RPC on OFLibrary
169 // TODO : Cleaner approach is to use a copy constructor once it is implemented
170 Long Xid = session.getNextXid();
171 GroupModInputBuilder mdInput = new GroupModInputBuilder();
173 mdInput.setBucketsList(input.getBucketsList());
174 mdInput.setCommand(input.getCommand());
175 mdInput.setGroupId(input.getGroupId());
176 mdInput.setType(input.getType());
177 mdInput.setVersion(input.getVersion());
178 LOG.debug("Calling OFLibrary groupMod");
179 Future<RpcResult<Void>> response = getConnectionAdapter(cookie).groupMod(mdInput.build());
181 // Send the same Xid back to caller - MessageDrivenSwitch
182 UpdateGroupOutputBuilder groupModOutput = new UpdateGroupOutputBuilder();
183 String stringXid =Xid.toString();
184 BigInteger bigIntXid = new BigInteger( stringXid );
185 groupModOutput.setTransactionId(new TransactionId(bigIntXid));
186 UpdateGroupOutput result = groupModOutput.build();
187 Collection<RpcError> errors = Collections.emptyList();
188 RpcResult<UpdateGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
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);
198 public Future<RpcResult<UpdateMeterOutput>> meterMod(MeterModInput input, SwitchConnectionDistinguisher cookie) {
200 // Set Xid before invoking RPC on OFLibrary
201 // TODO : Cleaner approach is to use a copy constructor once it is implemented
202 Long Xid = session.getNextXid();
203 MeterModInputBuilder mdInput = new MeterModInputBuilder();
205 mdInput.setBands(input.getBands());
206 mdInput.setCommand(input.getCommand());
207 mdInput.setFlags(input.getFlags());
208 mdInput.setMeterId(input.getMeterId());
209 mdInput.setVersion(input.getVersion());
210 mdInput.setVersion(input.getVersion());
211 LOG.debug("Calling OFLibrary meterMod");
212 Future<RpcResult<Void>> response = getConnectionAdapter(cookie).meterMod(mdInput.build());
214 // Send the same Xid back to caller - MessageDrivenSwitch
215 UpdateMeterOutputBuilder meterModOutput = new UpdateMeterOutputBuilder();
216 String stringXid =Xid.toString();
217 BigInteger bigIntXid = new BigInteger( stringXid );
218 meterModOutput.setTransactionId(new TransactionId(bigIntXid));
219 UpdateMeterOutput result = meterModOutput.build();
220 Collection<RpcError> errors = Collections.emptyList();
221 RpcResult<UpdateMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
223 // solution 1: sending directly and hooking listener to get error
224 // hookup listener to catch the possible error with no reference to returned future-object
225 LOG.debug("Returning to ModelDrivenSwitch for meterMod RPC");
226 return Futures.immediateFuture(rpcResult);
231 public Future<RpcResult<java.lang.Void>> multipartRequest(MultipartRequestInput input, SwitchConnectionDistinguisher cookie) {
232 return getConnectionAdapter(cookie).multipartRequest(input);
236 public Future<RpcResult<Void>> packetOut(PacketOutInput input, SwitchConnectionDistinguisher cookie) {
237 return getConnectionAdapter(cookie).packetOut(input);
241 public Future<RpcResult<UpdatePortOutput>> portMod(PortModInput input, SwitchConnectionDistinguisher cookie) {
243 LOG.debug("Calling OFLibrary portMod");
244 Future<RpcResult<Void>> response = getConnectionAdapter(cookie).portMod(input);
246 // Send the same Xid back to caller - ModelDrivenSwitch
247 UpdatePortOutputBuilder portModOutput = new UpdatePortOutputBuilder();
248 String stringXid =input.getXid().toString();
249 BigInteger bigIntXid = new BigInteger( stringXid );
250 portModOutput.setTransactionId(new TransactionId(bigIntXid));
251 UpdatePortOutput result = portModOutput.build();
252 Collection<RpcError> errors = Collections.emptyList();
253 RpcResult<UpdatePortOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
255 LOG.debug("Returning to ModelDrivenSwitch for portMod RPC");
256 return Futures.immediateFuture(rpcResult);
260 public Future<RpcResult<RoleRequestOutput>> roleRequest(RoleRequestInput input, SwitchConnectionDistinguisher cookie) {
261 return getConnectionAdapter(cookie).roleRequest(input);
265 public Future<RpcResult<Void>> setAsync(SetAsyncInput input, SwitchConnectionDistinguisher cookie) {
266 return getConnectionAdapter(cookie).setAsync(input);
270 public Future<RpcResult<Void>> setConfig(SetConfigInput input, SwitchConnectionDistinguisher cookie) {
271 return getConnectionAdapter(cookie).setConfig(input);
275 public Future<RpcResult<Void>> tableMod(TableModInput input, SwitchConnectionDistinguisher cookie) {
276 return getConnectionAdapter(cookie).tableMod(input);