Update MRI projects for Aluminium
[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.util.Collection;
12 import java.util.List;
13 import java.util.Optional;
14 import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
15 import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
16 import org.opendaylight.openflowplugin.extension.api.ExtensionConvertorData;
17 import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
18 import org.opendaylight.openflowplugin.extension.api.path.MessagePath;
19 import org.opendaylight.openflowplugin.extension.onf.OnfConstants;
20 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
21 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.XidConvertorData;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInputBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.BundleInnerMessage;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleAddFlowCase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleAddGroupCase;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleRemoveFlowCase;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleRemoveGroupCase;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleUpdateFlowCase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleUpdateGroupCase;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.bundle.inner.message.grouping.bundle.inner.message.BundleUpdatePortCase;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.send.experimenter.input.experimenter.message.of.choice.BundleAddMessageSal;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.send.experimenter.input.experimenter.message.of.choice.BundleAddMessageSalBuilder;
44 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;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundleFlowModCase;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundleFlowModCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundleGroupModCase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundleGroupModCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundlePortModCase;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.BundlePortModCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.bundle.flow.mod._case.FlowModCaseDataBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.bundle.group.mod._case.GroupModCaseDataBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.bundle.add.message.grouping.bundle.inner.message.bundle.port.mod._case.PortModCaseDataBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.experimenter.input.experimenter.data.of.choice.BundleAddMessageOnf;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.experimenter.input.experimenter.data.of.choice.BundleAddMessageOnfBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.experimenter.input.experimenter.data.of.choice.bundle.add.message.onf.OnfAddMessageGroupingDataBuilder;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60 /**
61  * Converter for BundleAddMessage messages (ONF approved extension #230).
62  */
63 public class BundleAddMessageConverter implements
64         ConverterMessageToOFJava<BundleAddMessageSal, BundleAddMessageOnf, ExtensionConvertorData>,
65         ConvertorMessageFromOFJava<BundleAddMessageOnf, MessagePath> {
66
67     private static final Logger LOG = LoggerFactory.getLogger(BundleAddMessageConverter.class);
68     private static final ConvertorExecutor CONVERTER_EXECUTOR = ConvertorManagerFactory.createDefaultManager();
69
70     @Override
71     public BundleAddMessageOnf convert(BundleAddMessageSal experimenterMessageCase,
72             ExtensionConvertorData extensionData) throws ConversionException {
73         final OnfAddMessageGroupingDataBuilder dataBuilder = new OnfAddMessageGroupingDataBuilder();
74         dataBuilder.setBundleId(experimenterMessageCase.getSalAddMessageData().getBundleId());
75         dataBuilder.setFlags(experimenterMessageCase.getSalAddMessageData().getFlags());
76         dataBuilder.setBundleProperty(experimenterMessageCase.getSalAddMessageData().getBundleProperty());
77         final BundleInnerMessage innerMessage = experimenterMessageCase.getSalAddMessageData().getBundleInnerMessage();
78         final XidConvertorData data = new XidConvertorData(extensionData.getVersion());
79         data.setDatapathId(extensionData.getDatapathId());
80         data.setXid(extensionData.getXid());
81         LOG.trace("Flow or group pushed to the node: {} with transaction id : {} is {}",
82                 data.getDatapathId(), data.getXid(),
83                 experimenterMessageCase.getSalAddMessageData().getBundleInnerMessage());
84         if (innerMessage.implementedInterface().equals(BundleAddFlowCase.class)
85                 || innerMessage.implementedInterface().equals(BundleUpdateFlowCase.class)
86                 || innerMessage.implementedInterface().equals(BundleRemoveFlowCase.class)) {
87             dataBuilder.setBundleInnerMessage(convertBundleFlowCase(innerMessage, data));
88         } else if (innerMessage.implementedInterface().equals(BundleAddGroupCase.class)
89                 || innerMessage.implementedInterface().equals(BundleUpdateGroupCase.class)
90                 || innerMessage.implementedInterface().equals(BundleRemoveGroupCase.class)) {
91             dataBuilder.setBundleInnerMessage(convertBundleGroupCase(innerMessage, data));
92         } else if (innerMessage.implementedInterface().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     @Override
102     public BundleAddMessageSal convert(final BundleAddMessageOnf input, final MessagePath path) {
103         return new BundleAddMessageSalBuilder()
104                 .setSalAddMessageData(new SalAddMessageDataBuilder(input.getOnfAddMessageGroupingData())
105                         .build())
106                 .build();
107     }
108
109     private BundleFlowModCase convertBundleFlowCase(final BundleInnerMessage messageCase,
110             final XidConvertorData data) throws ConversionException {
111         Optional<List<FlowModInputBuilder>> flowModInputs = Optional.empty();
112         final Class clazz = messageCase.implementedInterface();
113         if (clazz.equals(BundleAddFlowCase.class)) {
114             flowModInputs = CONVERTER_EXECUTOR.convert(
115                     new AddFlowInputBuilder(((BundleAddFlowCase) messageCase).getAddFlowCaseData()).build(), data);
116         } else if (clazz.equals(BundleUpdateFlowCase.class)) {
117             flowModInputs = CONVERTER_EXECUTOR.convert(
118                     new UpdatedFlowBuilder(((BundleUpdateFlowCase) messageCase).getUpdateFlowCaseData()).build(), data);
119         } else if (clazz.equals(BundleRemoveFlowCase.class)) {
120             flowModInputs = CONVERTER_EXECUTOR.convert(
121                     new RemoveFlowInputBuilder(((BundleRemoveFlowCase) messageCase).getRemoveFlowCaseData()).build(),
122                     data);
123         }
124
125         if (flowModInputs.isPresent()) {
126             if (flowModInputs.get().size() == 1) {
127                 return new BundleFlowModCaseBuilder()
128                         .setFlowModCaseData(
129                                 new FlowModCaseDataBuilder(
130                                         flowModInputs
131                                                 .get()
132                                                 .get(0)
133                                                 .setXid(data.getXid())
134                                                 .build())
135                                         .build())
136                         .build();
137             } else {
138                 throw new ConversionException(
139                         "BundleFlowCase conversion unsuccessful - not able to convert to multiple flows.");
140             }
141         } else {
142             throw new ConversionException("BundleFlowCase conversion unsuccessful.");
143         }
144     }
145
146     private BundleGroupModCase convertBundleGroupCase(final BundleInnerMessage messageCase,
147             final XidConvertorData data) throws ConversionException {
148         Optional<GroupModInputBuilder> groupModInput = Optional.empty();
149         final Class clazz = messageCase.implementedInterface();
150         if (clazz.equals(BundleAddGroupCase.class)) {
151             groupModInput = CONVERTER_EXECUTOR.convert(
152                     new AddGroupInputBuilder(((BundleAddGroupCase) messageCase).getAddGroupCaseData()).build(), data);
153         } else if (clazz.equals(BundleUpdateGroupCase.class)) {
154             groupModInput = CONVERTER_EXECUTOR.convert(
155                     new UpdatedGroupBuilder(((BundleUpdateGroupCase) messageCase).getUpdateGroupCaseData()).build(),
156                     data);
157         } else if (clazz.equals(BundleRemoveGroupCase.class)) {
158             groupModInput = CONVERTER_EXECUTOR.convert(
159                     new RemoveGroupInputBuilder(((BundleRemoveGroupCase) messageCase).getRemoveGroupCaseData()).build(),
160                     data);
161         }
162
163         if (groupModInput.isPresent()) {
164             return new BundleGroupModCaseBuilder()
165                     .setGroupModCaseData(
166                             new GroupModCaseDataBuilder(groupModInput.get()
167                                     .setXid(data.getXid())
168                                     .build())
169                             .build()
170                     )
171                     .build();
172         } else {
173             throw new ConversionException("BundleGroupCase conversion unsuccessful.");
174         }
175     }
176
177     private BundlePortModCase convertBundlePortCase(final BundleInnerMessage messageCase,
178             final XidConvertorData data) throws ConversionException {
179         Optional<PortModInput> portModInput = Optional.empty();
180         final Class<?> clazz = messageCase.implementedInterface();
181         if (clazz.equals(BundleUpdatePortCase.class)) {
182             Collection<Port> ports
183                     = ((BundleUpdatePortCase) messageCase).getUpdatePortCaseData().getPort().nonnullPort().values();
184             Port port = ports.iterator().next();
185             portModInput = CONVERTER_EXECUTOR.convert(port, data);
186         }
187
188         if (portModInput.isPresent()) {
189             return new BundlePortModCaseBuilder()
190                     .setPortModCaseData(
191                             new PortModCaseDataBuilder(portModInput.get())
192                                     .setXid(data.getXid())
193                                     .build()
194                     )
195                     .build();
196         } else {
197             throw new ConversionException("BundlePortCase conversion unsuccessful.");
198         }
199     }
200
201     @Override
202     public ExperimenterId getExperimenterId() {
203         return new ExperimenterId(OnfConstants.ONF_EXPERIMENTER_ID);
204     }
205
206     @Override
207     public long getType() {
208         return OnfConstants.ONF_ET_BUNDLE_ADD_MESSAGE;
209     }
210 }