ONF Bundles sample application 20/58120/5
authormiroslav.macko <miroslav.macko@pantheon.tech>
Mon, 29 May 2017 09:41:49 +0000 (11:41 +0200)
committerMiroslav Macko <miroslav.macko@pantheon.tech>
Fri, 16 Jun 2017 07:02:19 +0000 (07:02 +0000)
- Add group and flows using ONF bundles implementation

Change-Id: Iba0be279a5219947bcd69f7e91eefab6d8d5212f
Signed-off-by: miroslav.macko <miroslav.macko@pantheon.tech>
pom.xml
samples/sample-bundles/pom.xml [new file with mode: 0644]
samples/sample-bundles/src/main/java/org/opendaylight/openflowplugin/samples/sample/bundles/Activator.java [new file with mode: 0644]

diff --git a/pom.xml b/pom.xml
index 6cd28de59f2bfc213f4f9291b791d44cb31280ca..b966d44b3ca025eda717c7b3b4cb4414f2f0a80a 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -44,6 +44,7 @@
       <module>features-he-aggregator</module>
       <module>samples/sample-consumer</module>
       <module>samples/learning-switch</module>
+      <module>samples/sample-bundles</module>
       <module>applications</module>
       <module>model</module>
   </modules>
diff --git a/samples/sample-bundles/pom.xml b/samples/sample-bundles/pom.xml
new file mode 100644 (file)
index 0000000..56ad7d9
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2017 Pantheon Technologies s.r.o. and others.  All rights reserved.
+  ~
+  ~ This program and the accompanying materials are made available under the
+  ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+  ~ and is available at http://www.eclipse.org/legal/epl-v10.html
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.openflowplugin</groupId>
+        <artifactId>openflowplugin-parent</artifactId>
+        <version>0.5.0-SNAPSHOT</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
+
+    <artifactId>sample-bundles</artifactId>
+    <packaging>bundle</packaging>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Embed-Transitive>
+                            false
+                        </Embed-Transitive>
+                        <Bundle-Activator>
+                            org.opendaylight.openflowplugin.samples.sample.bundles.Activator
+                        </Bundle-Activator>
+                    </instructions>
+                    <manifestLocation>${project.build.directory}/META-INF</manifestLocation>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.model</groupId>
+            <artifactId>model-flow-base</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-inventory</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-binding-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>yang-binding</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin</groupId>
+            <artifactId>openflowplugin-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin</groupId>
+            <artifactId>openflowplugin-extension-onf</artifactId>
+        </dependency>
+    </dependencies>
+</project>
+
diff --git a/samples/sample-bundles/src/main/java/org/opendaylight/openflowplugin/samples/sample/bundles/Activator.java b/samples/sample-bundles/src/main/java/org/opendaylight/openflowplugin/samples/sample/bundles/Activator.java
new file mode 100644 (file)
index 0000000..61c72f0
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * 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.samples.sample.bundles;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.AbstractBrokerAwareActivator;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
+import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.BucketId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.BucketsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.BucketBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.AddBundleMessagesInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.ControlBundleInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.ControlBundleInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.SalBundleService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.Messages;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.MessagesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.messages.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.add.bundle.messages.input.messages.MessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleAddFlowCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleAddGroupCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.bundle.add.flow._case.AddFlowCaseDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.bundle.add.group._case.AddGroupCaseDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleControlType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.BundleId;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Sample bundles activator
+ */
+public class Activator extends AbstractBrokerAwareActivator implements BindingAwareConsumer, ClusteredDataTreeChangeListener<FlowCapableNode>, AutoCloseable {
+
+    private static final Logger LOG = LoggerFactory.getLogger(Activator.class);
+
+    private static final BundleId BUNDLE_ID = new BundleId(1L);
+    private static final BundleFlags BUNDLE_FLAGS = new BundleFlags(true, true);
+    private static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
+
+    private DataBroker dataBroker;
+    private SalBundleService bundleService;
+
+    @Override
+    public void close() throws Exception {
+        LOG.debug("close() passing");
+    }
+
+    @Override
+    public void onSessionInitialized(ConsumerContext consumerContext) {
+        LOG.debug("inSessionInitialized() passing");
+        dataBroker = consumerContext.getSALService(DataBroker.class);
+
+        final InstanceIdentifier<FlowCapableNode> path = InstanceIdentifier.create(Nodes.class).child(Node.class).
+                augmentation(FlowCapableNode.class);
+        final DataTreeIdentifier<FlowCapableNode> identifier = new DataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, path);
+
+        dataBroker.registerDataTreeChangeListener(identifier, Activator.this);
+        bundleService = consumerContext.getRpcService(SalBundleService.class);
+    }
+
+    @Override
+    public void onDataTreeChanged(@Nonnull Collection<DataTreeModification<FlowCapableNode>> modifications) {
+        for (DataTreeModification modification : modifications) {
+            if (modification.getRootNode().getModificationType() == ModificationType.WRITE) {
+                LOG.info("Node connected:  {}", modification.getRootPath().getRootIdentifier().firstIdentifierOf(Node.class));
+
+                final NodeRef nodeRef = new NodeRef(modification.getRootPath().getRootIdentifier().firstIdentifierOf(Node.class));
+
+                final ControlBundleInput openBundleInput = new ControlBundleInputBuilder()
+                        .setNode(nodeRef)
+                        .setBundleId(BUNDLE_ID)
+                        .setFlags(BUNDLE_FLAGS)
+                        .setType(BundleControlType.ONFBCTOPENREQUEST)
+                        .build();
+
+                final ControlBundleInput commitBundleInput = new ControlBundleInputBuilder()
+                        .setNode(nodeRef)
+                        .setBundleId(BUNDLE_ID)
+                        .setFlags(BUNDLE_FLAGS)
+                        .setType(BundleControlType.ONFBCTCOMMITREQUEST)
+                        .build();
+
+                final List<Message> innerMessages = createMessages(nodeRef);
+                final Messages messages = new MessagesBuilder().setMessage(innerMessages).build();
+                final AddBundleMessagesInput addBundleMessagesInput = new AddBundleMessagesInputBuilder()
+                        .setNode(nodeRef)
+                        .setBundleId(BUNDLE_ID)
+                        .setFlags(BUNDLE_FLAGS)
+                        .setMessages(messages)
+                        .build();
+
+                makeCompletableFuture(bundleService.controlBundle(openBundleInput))
+                        .thenComposeAsync(voidRpcResult -> {
+                            LOG.debug("Open successful: {}, msg: {}", voidRpcResult.isSuccessful(), voidRpcResult.getErrors());
+
+                            final CompletableFuture<RpcResult<Void>> addFuture =
+                                    makeCompletableFuture(bundleService.addBundleMessages(addBundleMessagesInput));
+
+                            return addFuture;
+                        }).thenComposeAsync(voidRpcResult -> {
+                            LOG.debug("AddBundleMessages successful: {}, msg: {}", voidRpcResult.isSuccessful(), voidRpcResult.getErrors());
+
+                            final CompletableFuture<RpcResult<Void>> controlCommitFuture =
+                                    makeCompletableFuture(bundleService.controlBundle(commitBundleInput));
+
+                            return controlCommitFuture;
+                        }).thenAccept(voidRpcResult -> {
+                            LOG.debug("Commit successful: {}, msg: {}", voidRpcResult.isSuccessful(), voidRpcResult.getErrors());
+                });
+            }
+        }
+    }
+
+    private static <T> CompletableFuture<T> makeCompletableFuture(Future<T> future) {
+        return CompletableFuture.supplyAsync(() -> {
+            try {
+                return future.get();
+            } catch (InterruptedException | ExecutionException e) {
+                throw new RuntimeException(e);
+            }
+        }, EXECUTOR);
+    }
+
+    @Override
+    protected void onBrokerAvailable(BindingAwareBroker bindingAwareBroker, BundleContext bundleContext) {
+        LOG.debug("onBrokerAvailable() passing");
+        bindingAwareBroker.registerConsumer(this);
+    }
+
+    private static List<Message> createMessages(NodeRef nodeRef) {
+        List<Message> messages  = new ArrayList<>();
+
+
+        messages.add(new MessageBuilder().setNode(nodeRef).setBundleInnerMessage(
+                new BundleAddGroupCaseBuilder()
+                        .setAddGroupCaseData(new AddGroupCaseDataBuilder(createGroup(1l)).build()).build()).build());
+
+        messages.add(new MessageBuilder().setNode(nodeRef).setBundleInnerMessage(
+                new BundleAddFlowCaseBuilder()
+                        .setAddFlowCaseData(new AddFlowCaseDataBuilder(createFlow("42", 1l, 1, (short) 1)).build()).build()).build());
+
+        messages.add(new MessageBuilder().setNode(nodeRef).setBundleInnerMessage(
+                new BundleAddFlowCaseBuilder()
+                        .setAddFlowCaseData(new AddFlowCaseDataBuilder(createFlow("43", 1l, 2, (short) 2)).build()).build()).build());
+
+        LOG.debug("createMessages() passing {}", messages);
+
+        return messages;
+    }
+
+    private static Flow createFlow(String flowId, long groupId, int priority, short tableId) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        matchBuilder.setEthernetMatch(new EthernetMatchBuilder()
+                .setEthernetType(new EthernetTypeBuilder()
+                        .setType(new EtherType(2048l)).build()).build());
+
+        FlowBuilder flowBuilder = new FlowBuilder();
+        flowBuilder.setMatch(matchBuilder.build());
+        flowBuilder.setInstructions(createGroupInstructions(groupId).build());
+        flowBuilder.setPriority(priority);
+        flowBuilder.setCookie(new FlowCookie(new BigInteger(flowId + "" + priority)));
+
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+        flowBuilder.setStrict(false);
+        flowBuilder.setContainerName(null);
+        flowBuilder.setId(new FlowId(flowId));
+        flowBuilder.setTableId(tableId);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName("FlowWithGroupInstruction");
+
+        return flowBuilder.build();
+    }
+
+    private static Group createGroup(long groupId) {
+        GroupBuilder groupBuilder = new GroupBuilder();
+        GroupKey groupKey = new GroupKey(new GroupId(groupId));
+        groupBuilder.setKey(groupKey);
+        groupBuilder.setGroupId(groupKey.getGroupId());
+        groupBuilder.setBarrier(false);
+        groupBuilder.setGroupName("Foo");
+        groupBuilder.setContainerName(null);
+        groupBuilder.setGroupType(GroupTypes.GroupAll);
+        groupBuilder.setBuckets(createBuckets().build());
+
+        return groupBuilder.build();
+    }
+
+    private static BucketsBuilder createBuckets() {
+        List<Bucket> bucketList = new ArrayList<>();
+        List<Action> actionList = new ArrayList<>();
+
+        actionList.add(new ActionBuilder()
+                .setOrder(0)
+                .setAction(new PopVlanActionCaseBuilder()
+                        .setPopVlanAction(new PopVlanActionBuilder().build())
+                        .build()).build());
+
+        BucketBuilder bucketBuilder = new BucketBuilder();
+        bucketBuilder.setBucketId(new BucketId(12l));
+        bucketBuilder.setAction(actionList);
+
+        bucketList.add(bucketBuilder.build());
+
+        actionList = new ArrayList<>();
+        SetFieldCaseBuilder setFieldCaseBuilder = new SetFieldCaseBuilder();
+        setFieldCaseBuilder.setSetField(new SetFieldBuilder()
+                .setLayer3Match(new Ipv4MatchBuilder()
+                        .setIpv4Source(new Ipv4Prefix("10.0.1.0/32"))
+                        .build())
+                .build());
+
+        actionList.add(new ActionBuilder()
+                .setAction(setFieldCaseBuilder.build())
+                .setOrder(0)
+                .build());
+
+        setFieldCaseBuilder = new SetFieldCaseBuilder();
+        setFieldCaseBuilder.setSetField(new SetFieldBuilder()
+                .setLayer3Match(new Ipv4MatchBuilder()
+                        .setIpv4Destination(new Ipv4Prefix("10.0.10.0/32"))
+                        .build())
+                .build());
+
+        actionList.add(new ActionBuilder()
+                .setAction(setFieldCaseBuilder.build())
+                .setOrder(0)
+                .build());
+
+        bucketBuilder = new BucketBuilder();
+        bucketBuilder.setBucketId(new BucketId(13l));
+        bucketBuilder.setAction(actionList);
+
+        bucketList.add(bucketBuilder.build());
+
+        BucketsBuilder bucketsBuilder = new BucketsBuilder();
+        bucketsBuilder.setBucket(bucketList);
+
+        return bucketsBuilder;
+    }
+
+    private static InstructionsBuilder createGroupInstructions(long groupId) {
+        List<Action> actionList = new ArrayList<>();
+        ActionBuilder actionBuilder = new ActionBuilder();
+
+        GroupActionBuilder groupActionBuilder = new GroupActionBuilder();
+        groupActionBuilder.setGroupId(groupId);
+
+        actionBuilder.setAction(new GroupActionCaseBuilder().setGroupAction(groupActionBuilder.build()).build());
+        actionBuilder.setOrder(1);
+        actionBuilder.setKey(new ActionKey(0));
+        actionList.add(actionBuilder.build());
+
+        ApplyActionsBuilder applyActionsBuilder = new ApplyActionsBuilder();
+        applyActionsBuilder.setAction(actionList);
+
+        InstructionBuilder instructionBuilder = new InstructionBuilder();
+        instructionBuilder.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(applyActionsBuilder.build()).build());
+        instructionBuilder.setOrder(0);
+        instructionBuilder.setKey(new InstructionKey(0));
+
+        InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
+        List<Instruction> instructions = new ArrayList<>();
+        instructions.add(instructionBuilder.build());
+        instructionsBuilder.setInstruction(instructions);
+
+        return instructionsBuilder;
+    }
+}