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;
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;
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;
50 import com.google.common.util.concurrent.Futures;
53 * message dispatch service to send the message to switch.
58 public class MessageDispatchServiceImpl implements IMessageDispatchService {
60 private static final Logger LOG = LoggerFactory.getLogger(MessageDispatchServiceImpl.class);
62 private SessionContext session;
68 * - MessageDispatchService for this session
70 public MessageDispatchServiceImpl(SessionContext session) {
71 this.session = session;
75 * get proper connection adapter to send the message to switch.
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.
83 private ConnectionAdapter getConnectionAdapter(SwitchConnectionDistinguisher cookie) {
85 if (!session.isValid()) {
86 LOG.warn("Session for the cookie {} is invalid.", cookie);
87 throw new IllegalArgumentException("Session for the cookie is invalid.");
89 LOG.debug("finding connecton for cookie value {}. ", cookie);
90 // set main connection as default
91 ConnectionAdapter connectionAdapter = session.getPrimaryConductor().getConnectionAdapter();
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();
100 // TODO: pick connection to utilize all the available connection.
102 return connectionAdapter;
106 public Future<RpcResult<BarrierOutput>> barrier(BarrierInput input, SwitchConnectionDistinguisher cookie) {
107 return getConnectionAdapter(cookie).barrier(input);
111 public Future<RpcResult<Void>> experimenter(ExperimenterInput input, SwitchConnectionDistinguisher cookie) {
112 return getConnectionAdapter(cookie).experimenter(input);
116 public Future<RpcResult<UpdateFlowOutput>> flowMod(FlowModInput input, SwitchConnectionDistinguisher cookie) {
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();
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());
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));
145 UpdateFlowOutput result = flowModOutput.build();
146 Collection<RpcError> errors = Collections.emptyList();
147 RpcResult<UpdateFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
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);
157 public Future<RpcResult<GetAsyncOutput>> getAsync(GetAsyncInput input, SwitchConnectionDistinguisher cookie) {
158 return getConnectionAdapter(cookie).getAsync(input);
162 public Future<RpcResult<GetConfigOutput>> getConfig(GetConfigInput input, SwitchConnectionDistinguisher cookie) {
163 return getConnectionAdapter(cookie).getConfig(input);
167 public Future<RpcResult<GetFeaturesOutput>> getFeatures(GetFeaturesInput input, SwitchConnectionDistinguisher cookie) {
168 return getConnectionAdapter(cookie).getFeatures(input);
172 public Future<RpcResult<GetQueueConfigOutput>> getQueueConfig(GetQueueConfigInput input,
173 SwitchConnectionDistinguisher cookie) {
174 return getConnectionAdapter(cookie).getQueueConfig(input);
178 public Future<RpcResult<UpdateGroupOutput>> groupMod(GroupModInput input, SwitchConnectionDistinguisher cookie) {
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();
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());
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);
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);
210 public Future<RpcResult<UpdateMeterOutput>> meterMod(MeterModInput input, SwitchConnectionDistinguisher cookie) {
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();
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());
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);
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);
243 public Future<RpcResult<Void>> packetOut(PacketOutInput input, SwitchConnectionDistinguisher cookie) {
244 return getConnectionAdapter(cookie).packetOut(input);
248 public Future<RpcResult<Void>> portMod(PortModInput input, SwitchConnectionDistinguisher cookie) {
249 return getConnectionAdapter(cookie).portMod(input);
253 public Future<RpcResult<RoleRequestOutput>> roleRequest(RoleRequestInput input, SwitchConnectionDistinguisher cookie) {
254 return getConnectionAdapter(cookie).roleRequest(input);
258 public Future<RpcResult<Void>> setAsync(SetAsyncInput input, SwitchConnectionDistinguisher cookie) {
259 return getConnectionAdapter(cookie).setAsync(input);
263 public Future<RpcResult<Void>> setConfig(SetConfigInput input, SwitchConnectionDistinguisher cookie) {
264 return getConnectionAdapter(cookie).setConfig(input);
268 public Future<RpcResult<Void>> tableMod(TableModInput input, SwitchConnectionDistinguisher cookie) {
269 return getConnectionAdapter(cookie).tableMod(input);