Bump MRI upstreams
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / services / multilayer / MultiLayerExperimenterMultipartService.java
index 5f717af622f642d01e9bc3c732315c28a5ee0779..9077b096ed2a7725f9f2e405e9136878ffceb52b 100644 (file)
@@ -5,35 +5,46 @@
  * 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;
@@ -49,7 +60,39 @@ public class MultiLayerExperimenterMultipartService extends AbstractExperimenter
 
     @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();
 
@@ -60,59 +103,68 @@ public class MultiLayerExperimenterMultipartService extends AbstractExperimenter
                     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);
+    }
 }
+