Merge "Fix codestyle"
[openflowplugin.git] / extension / openflowplugin-extension-onf / src / main / java / org / opendaylight / openflowplugin / extension / onf / converter / BundleAddMessageConverter.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.openflowplugin.extension.onf.converter;
10
11 import java.math.BigInteger;
12 import java.util.List;
13 import java.util.Optional;
14 import org.opendaylight.openflowplugin.api.OFConstants;
15 import org.opendaylight.openflowplugin.extension.api.BundleMessageDataInjector;
16 import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
17 import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
18 import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
19 import org.opendaylight.openflowplugin.extension.api.path.MessagePath;
20 import org.opendaylight.openflowplugin.extension.onf.OnfConstants;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
24 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.PortBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInputBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.BundleInnerMessage;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleAddFlowCase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleAddGroupCase;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleRemoveFlowCase;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleRemoveGroupCase;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleUpdateFlowCase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleUpdateGroupCase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleUpdatePortCase;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.send.experimenter.input.experimenter.message.of.choice.BundleAddMessageSal;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.send.experimenter.input.experimenter.message.of.choice.BundleAddMessageSalBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.send.experimenter.input.experimenter.message.of.choice.bundle.add.message.sal.SalAddMessageDataBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundleFlowModCase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundleFlowModCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundleGroupModCase;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundleGroupModCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundlePortModCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundlePortModCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.bundle.flow.mod._case.FlowModCaseDataBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.bundle.group.mod._case.GroupModCaseDataBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.bundle.port.mod._case.PortModCaseDataBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.experimenter.input.experimenter.data.of.choice.BundleAddMessageOnf;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.experimenter.input.experimenter.data.of.choice.BundleAddMessageOnfBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.experimenter.input.experimenter.data.of.choice.bundle.add.message.onf.OnfAddMessageGroupingDataBuilder;
61
62 /**
63  * Converter for BundleAddMessage messages (ONF approved extension #230).
64  */
65 public class BundleAddMessageConverter implements
66         ConverterMessageToOFJava<BundleAddMessageSal, BundleAddMessageOnf>,
67         ConvertorMessageFromOFJava<BundleAddMessageOnf, MessagePath>,
68         BundleMessageDataInjector {
69
70     private static final ConvertorExecutor converterExecutor = ConvertorManagerFactory.createDefaultManager();
71     private long xid;
72     private NodeRef node;
73
74     @Override
75     public BundleAddMessageOnf convert(BundleAddMessageSal experimenterMessageCase) throws ConversionException {
76         final OnfAddMessageGroupingDataBuilder dataBuilder = new OnfAddMessageGroupingDataBuilder();
77         dataBuilder.setBundleId(experimenterMessageCase.getSalAddMessageData().getBundleId());
78         dataBuilder.setFlags(experimenterMessageCase.getSalAddMessageData().getFlags());
79         dataBuilder.setBundleProperty(experimenterMessageCase.getSalAddMessageData().getBundleProperty());
80         final BundleInnerMessage innerMessage = experimenterMessageCase.getSalAddMessageData().getBundleInnerMessage();
81         final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(OFConstants.OFP_VERSION_1_3);
82         data.setDatapathId(digDatapathId(node));
83
84         if (innerMessage.getImplementedInterface().equals(BundleAddFlowCase.class)   ||
85                 innerMessage.getImplementedInterface().equals(BundleUpdateFlowCase.class) ||
86                 innerMessage.getImplementedInterface().equals(BundleRemoveFlowCase.class)) {
87             dataBuilder.setBundleInnerMessage(convertBundleFlowCase(innerMessage, data));
88         } else if (innerMessage.getImplementedInterface().equals(BundleAddGroupCase.class) ||
89                 innerMessage.getImplementedInterface().equals(BundleUpdateGroupCase.class) ||
90                 innerMessage.getImplementedInterface().equals(BundleRemoveGroupCase.class)) {
91             dataBuilder.setBundleInnerMessage(convertBundleGroupCase(innerMessage, data));
92         } else if (innerMessage.getImplementedInterface().equals(BundleUpdatePortCase.class)) {
93             dataBuilder.setBundleInnerMessage(convertBundlePortCase(innerMessage, data));
94         } else {
95             throw new ConversionException("Unsupported inner message");
96         }
97
98         return new BundleAddMessageOnfBuilder().setOnfAddMessageGroupingData(dataBuilder.build()).build();
99     }
100
101     private BundleFlowModCase convertBundleFlowCase(final BundleInnerMessage messageCase, final VersionDatapathIdConvertorData data) throws ConversionException {
102         Optional<List<FlowModInputBuilder>> flowModInputs = Optional.empty();
103         final Class clazz = messageCase.getImplementedInterface();
104         if (clazz.equals(BundleAddFlowCase.class)) {
105             flowModInputs = converterExecutor.convert(new AddFlowInputBuilder(((BundleAddFlowCase)messageCase).getAddFlowCaseData()).build(), data);
106         } else if (clazz.equals(BundleUpdateFlowCase.class)) {
107             flowModInputs = converterExecutor.convert(new UpdatedFlowBuilder(((BundleUpdateFlowCase)messageCase).getUpdateFlowCaseData()).build(), data);
108         } else if (clazz.equals(BundleRemoveFlowCase.class)) {
109             flowModInputs = converterExecutor.convert(new RemoveFlowInputBuilder(((BundleRemoveFlowCase)messageCase).getRemoveFlowCaseData()).build(), data);
110         }
111
112         if (flowModInputs.isPresent()) {
113             if (flowModInputs.get().size() == 1) {
114                 return new BundleFlowModCaseBuilder()
115                         .setFlowModCaseData(
116                                 new FlowModCaseDataBuilder(
117                                         (flowModInputs
118                                                 .get()
119                                                 .get(0)
120                                                 .setXid(xid))
121                                                 .build())
122                                         .build())
123                         .build();
124             } else {
125                 throw new ConversionException("BundleFlowCase conversion unsuccessful - not able to convert to multiple flows.");
126             }
127         } else {
128             throw new ConversionException("BundleFlowCase conversion unsuccessful.");
129         }
130     }
131
132     private BundleGroupModCase convertBundleGroupCase(final BundleInnerMessage messageCase, final VersionDatapathIdConvertorData data) throws ConversionException {
133         Optional<GroupModInputBuilder> groupModInput = Optional.empty();
134         final Class clazz = messageCase.getImplementedInterface();
135         if (clazz.equals(BundleAddGroupCase.class)) {
136             groupModInput = converterExecutor.convert(new AddGroupInputBuilder(((BundleAddGroupCase)messageCase).getAddGroupCaseData()).build(), data);
137         } else if (clazz.equals(BundleUpdateGroupCase.class)) {
138             groupModInput = converterExecutor.convert(new UpdatedGroupBuilder(((BundleUpdateGroupCase)messageCase).getUpdateGroupCaseData()).build(), data);
139         } else if (clazz.equals(BundleRemoveGroupCase.class)) {
140             groupModInput = converterExecutor.convert(new RemoveGroupInputBuilder(((BundleRemoveGroupCase)messageCase).getRemoveGroupCaseData()).build(), data);
141         }
142
143         if (groupModInput.isPresent()) {
144             return new BundleGroupModCaseBuilder()
145                     .setGroupModCaseData(
146                             new GroupModCaseDataBuilder(groupModInput.get()
147                                     .setXid(xid)
148                                     .build())
149                             .build()
150                     )
151                     .build();
152         } else {
153             throw new ConversionException("BundleGroupCase conversion unsuccessful.");
154         }
155     }
156
157     private BundlePortModCase convertBundlePortCase(final BundleInnerMessage messageCase, final VersionDatapathIdConvertorData data) throws ConversionException {
158         Optional<PortModInput> portModInput = Optional.empty();
159         final Class clazz = messageCase.getImplementedInterface();
160         if (clazz.equals(BundleUpdatePortCase.class)) {
161             portModInput = converterExecutor.convert(new PortBuilder(((BundleUpdatePortCase)messageCase).getUpdatePortCaseData().getPort().getPort().get(0)).build(), data);
162         }
163
164         if (portModInput.isPresent()) {
165             return new BundlePortModCaseBuilder()
166                     .setPortModCaseData(
167                             new PortModCaseDataBuilder(portModInput.get())
168                                     .setXid(xid)
169                                     .build()
170                     )
171                     .build();
172         } else {
173             throw new ConversionException("BundlePortCase conversion unsuccessful.");
174         }
175     }
176
177     private static BigInteger digDatapathId(final NodeRef ref) {
178         return InventoryDataServiceUtil.dataPathIdFromNodeId(ref.getValue().firstKeyOf(Node.class).getId());
179     }
180
181     @Override
182     public ExperimenterId getExperimenterId() {
183         return new ExperimenterId(OnfConstants.ONF_EXPERIMENTER_ID);
184     }
185
186     @Override
187     public long getType() {
188         return OnfConstants.ONF_ET_BUNDLE_ADD_MESSAGE;
189     }
190
191     @Override
192     public void setXid(long xid) {
193         this.xid = xid;
194     }
195
196     @Override
197     public void setNode(NodeRef node) {
198         this.node = node;
199     }
200
201     @Override
202     public BundleAddMessageSal convert(final BundleAddMessageOnf input, final MessagePath path) throws ConversionException {
203         return new BundleAddMessageSalBuilder()
204                 .setSalAddMessageData(new SalAddMessageDataBuilder(input.getOnfAddMessageGroupingData())
205                         .build())
206                 .build();
207     }
208 }