2 * Copyright IBM Corporation, 2013. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.openflowplugin.openflow.md.core.session;
10 import java.math.BigInteger;
11 import java.util.Collection;
12 import java.util.Collections;
13 import java.util.concurrent.Future;
15 import org.opendaylight.controller.sal.common.util.Rpcs;
16 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
17 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
18 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutputBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutputBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutputBuilder;
50 import org.opendaylight.yangtools.yang.common.RpcError;
51 import org.opendaylight.yangtools.yang.common.RpcResult;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 import com.google.common.util.concurrent.Futures;
58 * message dispatch service to send the message to switch.
63 public class MessageDispatchServiceImpl implements IMessageDispatchService {
65 private static final Logger LOG = LoggerFactory.getLogger(MessageDispatchServiceImpl.class);
67 private SessionContext session;
73 * - MessageDispatchService for this session
75 public MessageDispatchServiceImpl(SessionContext session) {
76 this.session = session;
80 * get proper connection adapter to send the message to switch.
82 * @param cookie to identify the right connection, it can be null also.
83 * @return connectionAdapter associated with cookie, otherwise return best
84 * suitable connection.
88 private ConnectionAdapter getConnectionAdapter(SwitchConnectionDistinguisher cookie) {
90 if (!session.isValid()) {
91 LOG.warn("Session for the cookie {} is invalid.", cookie);
92 throw new IllegalArgumentException("Session for the cookie is invalid. Reason: "
93 + "the switch has been recently diconnected OR inventory provides outdated information.");
95 LOG.debug("finding connecton for cookie value {}. ", cookie);
96 // set main connection as default
97 ConnectionAdapter connectionAdapter = session.getPrimaryConductor().getConnectionAdapter();
99 ConnectionConductor conductor = session.getAuxiliaryConductor(cookie);
100 // check if auxiliary connection exist
101 if (null != conductor) {
102 LOG.debug("found auxiliary connection for the cookie.");
103 connectionAdapter = conductor.getConnectionAdapter();
106 // TODO: pick connection to utilize all the available connection.
108 return connectionAdapter;
112 public Future<RpcResult<BarrierOutput>> barrier(BarrierInput input, SwitchConnectionDistinguisher cookie) {
113 return getConnectionAdapter(cookie).barrier(input);
117 public Future<RpcResult<Void>> experimenter(ExperimenterInput input, SwitchConnectionDistinguisher cookie) {
118 return getConnectionAdapter(cookie).experimenter(input);
122 public Future<RpcResult<UpdateFlowOutput>> flowMod(FlowModInput input, SwitchConnectionDistinguisher cookie) {
123 LOG.debug("Calling OFLibrary flowMod");
124 Future<RpcResult<Void>> response = getConnectionAdapter(cookie).flowMod(input);
126 // Send the same Xid back to caller - MessageDrivenSwitch
127 UpdateFlowOutputBuilder flowModOutput = new UpdateFlowOutputBuilder();
128 BigInteger bigIntXid = BigInteger.valueOf(input.getXid()) ;
129 flowModOutput.setTransactionId(new TransactionId(bigIntXid));
131 UpdateFlowOutput result = flowModOutput.build();
132 Collection<RpcError> errors = Collections.emptyList();
133 RpcResult<UpdateFlowOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
135 // solution 1: sending directly and hooking listener to get error
136 // hookup listener to catch the possible error with no reference to returned future-object
137 LOG.debug("Returning to ModelDrivenSwitch for flowMod RPC");
138 return Futures.immediateFuture(rpcResult);
143 public Future<RpcResult<GetAsyncOutput>> getAsync(GetAsyncInput input, SwitchConnectionDistinguisher cookie) {
144 return getConnectionAdapter(cookie).getAsync(input);
148 public Future<RpcResult<GetConfigOutput>> getConfig(GetConfigInput input, SwitchConnectionDistinguisher cookie) {
149 return getConnectionAdapter(cookie).getConfig(input);
153 public Future<RpcResult<GetFeaturesOutput>> getFeatures(GetFeaturesInput input, SwitchConnectionDistinguisher cookie) {
154 return getConnectionAdapter(cookie).getFeatures(input);
158 public Future<RpcResult<GetQueueConfigOutput>> getQueueConfig(GetQueueConfigInput input,
159 SwitchConnectionDistinguisher cookie) {
160 return getConnectionAdapter(cookie).getQueueConfig(input);
164 public Future<RpcResult<UpdateGroupOutput>> groupMod(GroupModInput input, SwitchConnectionDistinguisher cookie) {
165 LOG.debug("Calling OFLibrary groupMod");
166 Future<RpcResult<Void>> response = getConnectionAdapter(cookie).groupMod(input);
168 // Send the same Xid back to caller - MessageDrivenSwitch
169 UpdateGroupOutputBuilder groupModOutput = new UpdateGroupOutputBuilder();
170 BigInteger bigIntXid = BigInteger.valueOf(input.getXid());
171 groupModOutput.setTransactionId(new TransactionId(bigIntXid));
173 UpdateGroupOutput result = groupModOutput.build();
174 Collection<RpcError> errors = Collections.emptyList();
175 RpcResult<UpdateGroupOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
177 // solution 1: sending directly and hooking listener to get error
178 // hookup listener to catch the possible error with no reference to returned future-object
179 LOG.debug("Returning to ModelDrivenSwitch for groupMod RPC");
180 return Futures.immediateFuture(rpcResult);
185 public Future<RpcResult<UpdateMeterOutput>> meterMod(MeterModInput input, SwitchConnectionDistinguisher cookie) {
186 LOG.debug("Calling OFLibrary meterMod");
187 Future<RpcResult<Void>> response = getConnectionAdapter(cookie).meterMod(input);
189 // Send the same Xid back to caller - MessageDrivenSwitch
190 UpdateMeterOutputBuilder meterModOutput = new UpdateMeterOutputBuilder();
191 BigInteger bigIntXid =BigInteger.valueOf(input.getXid());
192 meterModOutput.setTransactionId(new TransactionId(bigIntXid));
194 UpdateMeterOutput result = meterModOutput.build();
195 Collection<RpcError> errors = Collections.emptyList();
196 RpcResult<UpdateMeterOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
198 // solution 1: sending directly and hooking listener to get error
199 // hookup listener to catch the possible error with no reference to returned future-object
200 LOG.debug("Returning to ModelDrivenSwitch for meterMod RPC");
201 return Futures.immediateFuture(rpcResult);
206 public Future<RpcResult<java.lang.Void>> multipartRequest(MultipartRequestInput input, SwitchConnectionDistinguisher cookie) {
207 return getConnectionAdapter(cookie).multipartRequest(input);
211 public Future<RpcResult<Void>> packetOut(PacketOutInput input, SwitchConnectionDistinguisher cookie) {
212 return getConnectionAdapter(cookie).packetOut(input);
216 public Future<RpcResult<UpdatePortOutput>> portMod(PortModInput input, SwitchConnectionDistinguisher cookie) {
218 LOG.debug("Calling OFLibrary portMod");
219 Future<RpcResult<Void>> response = getConnectionAdapter(cookie).portMod(input);
221 // Send the same Xid back to caller - ModelDrivenSwitch
222 UpdatePortOutputBuilder portModOutput = new UpdatePortOutputBuilder();
223 String stringXid =input.getXid().toString();
224 BigInteger bigIntXid = new BigInteger( stringXid );
225 portModOutput.setTransactionId(new TransactionId(bigIntXid));
226 UpdatePortOutput result = portModOutput.build();
227 Collection<RpcError> errors = Collections.emptyList();
228 RpcResult<UpdatePortOutput> rpcResult = Rpcs.getRpcResult(true, result, errors);
230 LOG.debug("Returning to ModelDrivenSwitch for portMod RPC");
231 return Futures.immediateFuture(rpcResult);
235 public Future<RpcResult<RoleRequestOutput>> roleRequest(RoleRequestInput input, SwitchConnectionDistinguisher cookie) {
236 return getConnectionAdapter(cookie).roleRequest(input);
240 public Future<RpcResult<Void>> setAsync(SetAsyncInput input, SwitchConnectionDistinguisher cookie) {
241 return getConnectionAdapter(cookie).setAsync(input);
245 public Future<RpcResult<Void>> setConfig(SetConfigInput input, SwitchConnectionDistinguisher cookie) {
246 return getConnectionAdapter(cookie).setConfig(input);
250 public Future<RpcResult<Void>> tableMod(TableModInput input, SwitchConnectionDistinguisher cookie) {
251 return getConnectionAdapter(cookie).tableMod(input);