Merge remote-tracking branch 'liblldp/master'
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / protocol / deserialization / MessageDeserializerInjector.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.deserialization;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import java.util.function.Consumer;
13 import java.util.function.Function;
14 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerExtensionProvider;
15 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
16 import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey;
17 import org.opendaylight.openflowjava.protocol.api.keys.TypeToClassKey;
18 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
19 import org.opendaylight.openflowplugin.impl.protocol.deserialization.messages.AsyncConfigMessageDeserializer;
20 import org.opendaylight.openflowplugin.impl.protocol.deserialization.messages.FlowMessageDeserializer;
21 import org.opendaylight.openflowplugin.impl.protocol.deserialization.messages.GroupMessageDeserializer;
22 import org.opendaylight.openflowplugin.impl.protocol.deserialization.messages.MeterMessageDeserializer;
23 import org.opendaylight.openflowplugin.impl.protocol.deserialization.messages.PacketInMessageDeserializer;
24 import org.opendaylight.openflowplugin.impl.protocol.deserialization.messages.PortMessageDeserializer;
25 import org.opendaylight.openflowplugin.impl.protocol.deserialization.multipart.MultipartReplyMessageDeserializer;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.async.config.service.rev170619.AsyncConfigMessage;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.async.config.service.rev170619.GetAsyncOutput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortMessage;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowMessage;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupMessage;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterMessage;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
40
41 final class MessageDeserializerInjector {
42
43     private MessageDeserializerInjector() {
44     }
45
46     /**
47      * Injects message deserializers into provided.
48      * {@link org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerExtensionProvider}
49      *
50      * @param provider OpenflowJava deserializer extension provider
51      */
52     static void injectDeserializers(final DeserializerExtensionProvider provider) {
53         // Inject new message deserializers here using injector created by createInjector method
54         final Function<Integer, Function<Class<? extends OfHeader>, Consumer<OFDeserializer<? extends OfHeader>>>>
55                 injector = createInjector(provider, EncodeConstants.OF13_VERSION_ID);
56
57         injector.apply(10).apply(org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709
58                 .PacketInMessage.class).accept(new PacketInMessageDeserializer());
59         injector.apply(19).apply(MultipartReply.class).accept(new MultipartReplyMessageDeserializer());
60         injector.apply(27).apply(AsyncConfigMessage.class).accept(new AsyncConfigMessageDeserializer());
61     }
62
63     /**
64      * Reverts original message deserializers in provided.
65      * {@link org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerExtensionProvider}
66      *
67      * @param provider OpenflowJava deserializer extension provider
68      */
69     static void revertDeserializers(final DeserializerExtensionProvider provider) {
70         provider.unregisterDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 10));
71         provider.registerDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 10),
72                 PacketInMessage.class);
73         provider.unregisterDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 19));
74         provider.registerDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 19),
75                 MultipartReplyMessage.class);
76         provider.unregisterDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 27));
77         provider.registerDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 27),
78                 GetAsyncOutput.class);
79     }
80
81     /**
82      * Create injector that will inject new deserializers into.
83      * #{@link org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerExtensionProvider}
84      *
85      * @param provider OpenflowJava deserializer extension provider
86      * @param version  Openflow version
87      * @return injector
88      */
89     @VisibleForTesting
90     static Function<Integer, Function<Class<? extends OfHeader>, Consumer<OFDeserializer<? extends OfHeader>>>>
91         createInjector(
92             final DeserializerExtensionProvider provider,
93             final short version) {
94         return code -> retType -> deserializer -> {
95             provider.unregisterDeserializerMapping(new TypeToClassKey(version, code));
96             provider.registerDeserializerMapping(new TypeToClassKey(version, code), retType);
97             provider.registerDeserializer(
98                     new MessageCodeKey(version, code, retType),
99                     deserializer);
100         };
101     }
102
103     @VisibleForTesting
104     static void injectLegacyDeserializers(final DeserializerExtensionProvider provider) {
105         final Function<Integer, Function<Class<? extends OfHeader>, Consumer<OFDeserializer<? extends OfHeader>>>>
106                 injector = createInjector(provider, EncodeConstants.OF13_VERSION_ID);
107
108         injector.apply(14).apply(FlowMessage.class).accept(new FlowMessageDeserializer());
109         injector.apply(15).apply(GroupMessage.class).accept(new GroupMessageDeserializer());
110         injector.apply(29).apply(MeterMessage.class).accept(new MeterMessageDeserializer());
111         injector.apply(16).apply(PortMessage.class).accept(new PortMessageDeserializer());
112     }
113
114     @VisibleForTesting
115     static void revertLegacyDeserializers(final DeserializerExtensionProvider provider) {
116         provider.unregisterDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 14));
117         provider.registerDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 14),
118                 FlowModInput.class);
119         provider.unregisterDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 15));
120         provider.registerDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 15),
121                 GroupModInput.class);
122         provider.unregisterDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 29));
123         provider.registerDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 29),
124                 MeterModInput.class);
125         provider.unregisterDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 16));
126         provider.registerDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 16),
127                 PortModInput.class);
128         provider.unregisterDeserializerMapping(new TypeToClassKey(EncodeConstants.OF13_VERSION_ID, 19));
129     }
130
131 }