Rework bit-copying functions and re-enable tests
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / protocol / serialization / util / ActionUtil.java
1 /*
2  * Copyright (c) 2016 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.impl.protocol.serialization.util;
10
11 import io.netty.buffer.ByteBuf;
12 import java.util.Optional;
13 import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderSerializer;
14 import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
15 import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
16 import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
17 import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMakerFactory;
18 import org.opendaylight.openflowplugin.extension.api.ConverterExtensionKey;
19 import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
20 import org.opendaylight.openflowplugin.extension.api.ConvertorToOFJava;
21 import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
22 import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
23 import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralExtensionGrouping;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * Utility class for action serialization.
32  */
33 public final class ActionUtil {
34     private static final Logger LOG = LoggerFactory.getLogger(ActionUtil.class);
35
36     private ActionUtil() {
37     }
38
39     /**
40      * Serialize OpenFlow action, using extension converter if available.
41      * TODO: Remove also extension converters
42      *
43      * @param action    OpenFlowPlugin action
44      * @param version   OpenFlow version
45      * @param registry  serializer registry
46      * @param outBuffer output buffer
47      */
48     @SuppressWarnings("unchecked")
49     public static void writeAction(Action action, short version, SerializerRegistry registry, ByteBuf outBuffer) {
50         try {
51             Optional.ofNullable(OFSessionUtil.getExtensionConvertorProvider())
52                     .flatMap(provider ->
53                             (GeneralExtensionGrouping.class.isInstance(action)
54                                     ? convertExtensionGrouping(provider, (GeneralExtensionGrouping)action, version)
55                                     : convertGenericAction(provider, action, version))
56                                     .map(ofjAction -> {
57                                         final OFSerializer<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common
58                                                 .action.rev150203.actions.grouping.Action> serializer = registry
59                                                 .getSerializer(TypeKeyMakerFactory.createActionKeyMaker(version)
60                                                         .make(ofjAction));
61
62                                         serializer.serialize(ofjAction, outBuffer);
63                                         return action;
64                                     })
65                     ).orElseGet(() -> {
66                         final OFSerializer<Action> serializer = registry.getSerializer(
67                                 new MessageTypeKey<>(
68                                         version, (Class<? extends Action>) action.getImplementedInterface()));
69
70                         serializer.serialize(action, outBuffer);
71                         return action;
72                     });
73         } catch (final IllegalStateException | ClassCastException e) {
74             LOG.warn("Serializer for action {} for version {} not found.", action.getImplementedInterface(), version);
75         }
76     }
77
78     /**
79      * Serialize OpenFlow action header, using extension converter if available.
80      * TODO: Remove also extension converters
81      *
82      * @param action    OpenFlowPlugin action
83      * @param version   OpenFlow version
84      * @param registry  serializer registry
85      * @param outBuffer output buffer
86      */
87     @SuppressWarnings("unchecked")
88     public static void writeActionHeader(Action action, short version, SerializerRegistry registry, ByteBuf outBuffer) {
89         try {
90             Optional.ofNullable(OFSessionUtil.getExtensionConvertorProvider())
91                     .flatMap(provider ->
92                             (GeneralExtensionGrouping.class.isInstance(action)
93                                     ? convertExtensionGrouping(provider, (GeneralExtensionGrouping)action, version)
94                                     : convertGenericAction(provider, action, version))
95                                     .map(ofjAction -> {
96                                         final HeaderSerializer<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow
97                                                 .common
98                                                 .action.rev150203.actions.grouping.Action> serializer = registry
99                                                 .getSerializer(TypeKeyMakerFactory.createActionKeyMaker(version)
100                                                         .make(ofjAction));
101
102                                         serializer.serializeHeader(ofjAction, outBuffer);
103                                         return action;
104                                     })
105                     ).orElseGet(() -> {
106                         final HeaderSerializer<Action> serializer = registry.getSerializer(
107                                 new MessageTypeKey<>(
108                                         version, (Class<? extends Action>) action.getImplementedInterface()));
109
110                         serializer.serializeHeader(action, outBuffer);
111                         return action;
112                     });
113         } catch (final IllegalStateException | ClassCastException e) {
114             LOG.warn("Header Serializer for action {} for version {} not found.", action.getImplementedInterface(),
115                     version);
116         }
117     }
118
119     /**
120      * Try to convert action that implements
121      * #{@link org.opendaylight.yang.gen.v1.urn
122      * .opendaylight.openflowplugin.extension.general.rev140714.GeneralExtensionGrouping}.
123      * to OpenFlowJava action
124      *
125      * @param provider extension converter provider
126      * @param action   GeneralExtensionGrouping action
127      * @param version  OpenFlow version
128      * @return optional OpenFlowJava action
129      */
130     private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions
131             .grouping.Action> convertExtensionGrouping(final ExtensionConverterProvider provider,
132                                                        final GeneralExtensionGrouping action,
133                                                        final short version) {
134         final ConverterExtensionKey<? extends ExtensionKey> key =
135                 new ConverterExtensionKey<>(action.getExtensionKey(), version);
136
137         final ConvertorToOFJava<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions
138                 .grouping.Action> converter = provider.getConverter(key);
139
140         return Optional.ofNullable(converter).map(c -> c.convert(action.getExtension()));
141     }
142
143     /**
144      * Try to convert generic OpenFlowPlugin action to OpenFlowJava action.
145      *
146      * @param provider extension converter provider
147      * @param action   OpenFlowPlugin action
148      * @param version  OpenFlow version
149      * @return optional OpenFlowJava action
150      */
151     @SuppressWarnings("unchecked")
152     private static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions
153             .grouping.Action> convertGenericAction(final ExtensionConverterProvider provider,
154                                                    final Action action,
155                                                    final short version) {
156
157         final TypeVersionKey<Action> key =
158                 new TypeVersionKey<>((Class<? extends Action>) action.getImplementedInterface(), version);
159
160         final ConvertorActionToOFJava<Action, org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action
161                 .rev150203.actions.grouping.Action> converter = provider.getConverter(key);
162
163
164         return Optional.ofNullable(converter).map(c -> c.convert(action));
165
166     }
167 }