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