* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.openflowplugin.impl.services.multilayer;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.Future;
import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorData;
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
+import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
+import org.opendaylight.openflowplugin.extension.api.exception.ConverterNotFoundException;
import org.opendaylight.openflowplugin.extension.api.path.MessagePath;
import org.opendaylight.openflowplugin.impl.services.AbstractExperimenterMultipartService;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.send.experimenter.mp.request.output.ExperimenterCoreMessageItem;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.send.experimenter.mp.request.output.ExperimenterCoreMessageItemBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice;
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.ErrorType;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
@Override
@SuppressWarnings("unchecked")
- public Future<RpcResult<SendExperimenterMpRequestOutput>> handleAndReply(SendExperimenterMpRequestInput input) {
+ protected OfHeader buildRequest(Xid xid, SendExperimenterMpRequestInput input) throws ServiceException {
+ final TypeVersionKey key = new TypeVersionKey<>(
+ input.getExperimenterMessageOfChoice().implementedInterface(),
+ getVersion());
+
+ final ConverterMessageToOFJava<ExperimenterMessageOfChoice, ExperimenterDataOfChoice,
+ ConvertorData> messageConverter = getExtensionConverterProvider().getMessageConverter(key);
+
+ if (messageConverter == null) {
+ throw new ServiceException(new ConverterNotFoundException(key.toString()));
+ }
+
+ try {
+ return RequestInputUtils
+ .createMultipartHeader(MultipartType.OFPMPEXPERIMENTER, xid.getValue(), getVersion())
+ .setMultipartRequestBody(new MultipartRequestExperimenterCaseBuilder()
+ .setMultipartRequestExperimenter(new MultipartRequestExperimenterBuilder()
+ .setExperimenter(messageConverter.getExperimenterId())
+ .setExpType(messageConverter.getType())
+ .setExperimenterDataOfChoice(messageConverter
+ .convert(input.getExperimenterMessageOfChoice(), null))
+ .build())
+ .build())
+ .build();
+ } catch (final ConversionException e) {
+ throw new ServiceException(e);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public ListenableFuture<RpcResult<SendExperimenterMpRequestOutput>> handleAndReply(
+ SendExperimenterMpRequestInput input) {
final ListenableFuture<RpcResult<List<MultipartReply>>> multipartFuture = handleServiceCall(input);
final SettableFuture<RpcResult<SendExperimenterMpRequestOutput>> finalFuture = SettableFuture.create();
final List<MultipartReply> multipartReplies = result.getResult();
if (multipartReplies.isEmpty()) {
LOG.warn("Multipart reply to Experimenter-Mp request shouldn't be empty list.");
- finalFuture.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed().withError(ErrorType.RPC, "Multipart reply list is empty.").build());
+ finalFuture.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed()
+ .withError(ErrorType.RPC, "Multipart reply list is empty.").build());
} else {
LOG.debug(
- "OnSuccess, rpc result successful, multipart response for rpc sendExperimenterMpRequest with xid {} obtained.",
+ "OnSuccess, rpc result successful,"
+ + " multipart response for rpc sendExperimenterMpRequest with xid {} obtained.",
multipartReplies.get(0).getXid());
- final SendExperimenterMpRequestOutputBuilder sendExpMpReqOutputBuilder = new SendExperimenterMpRequestOutputBuilder();
+ final SendExperimenterMpRequestOutputBuilder sendExpMpReqOutputBuilder =
+ new SendExperimenterMpRequestOutputBuilder();
final List<ExperimenterCoreMessageItem> expCoreMessageItem = new ArrayList<>();
- for(MultipartReply multipartReply : multipartReplies){
- final MultipartReplyExperimenterCase caseBody = (MultipartReplyExperimenterCase)multipartReply.getMultipartReplyBody();
+ for (MultipartReply multipartReply : multipartReplies) {
+ final MultipartReplyExperimenterCase caseBody =
+ (MultipartReplyExperimenterCase)multipartReply.getMultipartReplyBody();
final MultipartReplyExperimenter replyBody = caseBody.getMultipartReplyExperimenter();
final ExperimenterDataOfChoice vendorData = replyBody.getExperimenterDataOfChoice();
final MessageTypeKey<? extends ExperimenterDataOfChoice> key = new MessageTypeKey<>(
getVersion(),
- (Class<? extends ExperimenterDataOfChoice>) vendorData.getImplementedInterface());
+ (Class<? extends ExperimenterDataOfChoice>) vendorData.implementedInterface());
final ConvertorMessageFromOFJava<ExperimenterDataOfChoice, MessagePath> messageConverter =
getExtensionConverterProvider().getMessageConverter(key);
if (messageConverter == null) {
LOG.warn("Custom converter for {}[OF:{}] not found",
- vendorData.getImplementedInterface(),
+ vendorData.implementedInterface(),
getVersion());
- finalFuture.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed().withError(ErrorType.RPC, "Custom converter not found.").build());
- return;
- }
- try {
- final ExperimenterMessageOfChoice messageOfChoice = messageConverter.convert(vendorData, MessagePath.MPMESSAGE_RPC_OUTPUT);
- final ExperimenterCoreMessageItemBuilder expCoreMessageItemBuilder = new ExperimenterCoreMessageItemBuilder();
- expCoreMessageItemBuilder.setExperimenterMessageOfChoice(messageOfChoice);
- expCoreMessageItem.add(expCoreMessageItemBuilder.build());
- } catch (final ConversionException e) {
- LOG.error("Conversion of experimenter message reply failed. Exception: {}", e);
- finalFuture.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed().withError(ErrorType.RPC, "Conversion of experimenter rpc output failed.").build());
+ finalFuture.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed()
+ .withError(ErrorType.RPC, "Custom converter not found.").build());
return;
}
+ final ExperimenterMessageOfChoice messageOfChoice =
+ messageConverter.convert(vendorData, MessagePath.MPMESSAGE_RPC_OUTPUT);
+ final ExperimenterCoreMessageItemBuilder expCoreMessageItemBuilder =
+ new ExperimenterCoreMessageItemBuilder();
+ expCoreMessageItemBuilder.setExperimenterMessageOfChoice(messageOfChoice);
+ expCoreMessageItem.add(expCoreMessageItemBuilder.build());
}
sendExpMpReqOutputBuilder.setExperimenterCoreMessageItem(expCoreMessageItem);
finalFuture.set(RpcResultBuilder.success(sendExpMpReqOutputBuilder.build()).build());
}
} else {
- LOG.warn("OnSuccess, rpc result unsuccessful, multipart response for rpc sendExperimenterMpRequest was unsuccessful.");
- finalFuture.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed().withRpcErrors(result.getErrors()).build());
+ LOG.warn("OnSuccess, rpc result unsuccessful,"
+ + " multipart response for rpc sendExperimenterMpRequest was unsuccessful.");
+ finalFuture.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed()
+ .withRpcErrors(result.getErrors()).build());
}
}
@Override
- public void onFailure(final Throwable t) {
- LOG.warn("Failure multipart response for Experimenter-Mp request. Exception: {}", t);
- finalFuture.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed().withError(ErrorType.RPC, "Future error", t).build());
+ public void onFailure(final Throwable throwable) {
+ LOG.warn("Failure multipart response for Experimenter-Mp request", throwable);
+ finalFuture.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed()
+ .withError(ErrorType.RPC, "Future error", throwable).build());
}
}
- Futures.addCallback(multipartFuture, new CallBackImpl());
+ Futures.addCallback(multipartFuture, new CallBackImpl(), MoreExecutors.directExecutor());
return finalFuture;
}
+ @VisibleForTesting
+ OfHeader buildRequestTest(Xid xid, SendExperimenterMpRequestInput input) throws ServiceException {
+ return buildRequest(xid, input);
+ }
}
+