Fix port update
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / PortConvertor.java
1 /*
2  * Copyright (c) 2014 Ericsson India Global Services Pvt Ltd. 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.openflow.md.core.sal.convertor;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import com.google.common.base.MoreObjects;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.Objects;
16 import java.util.Set;
17 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
18 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Convertor;
19 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
20 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.Ports;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.PortsBuilder;
33 import org.opendaylight.yangtools.yang.binding.DataContainer;
34
35 /**
36  * Converts port mod, port status and port description MD-SAL messages to OF library data
37  *
38  * Example usage:
39  * <pre>
40  * {@code
41  * VersionConvertorData data = new VersionConvertorData(version);
42  * Optional<PortModInput> ofPort = convertorManager.convert(salPort, data);
43  * }
44  * </pre>
45  */
46 public class PortConvertor extends Convertor<Port, PortModInput, VersionConvertorData> {
47
48     private static final Set<Class<? extends DataContainer>> TYPES = Collections.singleton(Port.class);
49
50     /**
51      * Create default empty port mod input
52      * Use this method, if result from convertor is empty.
53      *
54      * @param version Openflow version
55      * @return default empty port mod input
56      */
57     public static PortModInput defaultResult(short version) {
58         return new PortModInputBuilder()
59                 .setVersion(version)
60                 .build();
61     }
62
63     private static PortConfig maskPortConfigFields(
64             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig configData) {
65
66         if (Objects.isNull(configData)) {
67             return null;
68         }
69
70         Boolean portDown = configData.isPORTDOWN();
71         Boolean noRecv = configData.isNORECV();
72         Boolean noFwd = configData.isNOFWD();
73         Boolean noPacketIn = configData.isNOPACKETIN();
74
75         return new PortConfig(noFwd, noPacketIn, noRecv, portDown);
76
77     }
78
79     private static PortConfigV10 maskPortConfigV10Fields(
80             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig configData) {
81
82         if (Objects.isNull(configData)) {
83             return null;
84         }
85
86         Boolean portDown = configData.isPORTDOWN();
87         Boolean noRecv = configData.isNORECV();
88         Boolean noFwd = configData.isNOFWD();
89         Boolean noPacketIn = configData.isNOPACKETIN();
90
91         return new PortConfigV10(false, noFwd, noPacketIn, noRecv, true, true, portDown);
92
93     }
94
95     private static PortFeatures getPortFeatures(
96             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures salPortFeatures) {
97
98         return new PortFeatures(salPortFeatures.isHundredGbFd(), salPortFeatures.isHundredMbFd(),
99                 salPortFeatures.isHundredMbHd(), salPortFeatures.isTenGbFd(), salPortFeatures.isTenMbFd(),
100                 salPortFeatures.isTenMbHd(), salPortFeatures.isOneGbFd(), salPortFeatures.isOneGbHd(),
101                 salPortFeatures.isOneTbFd(), salPortFeatures.isFortyGbFd(), salPortFeatures.isAutoeng(),
102                 salPortFeatures.isCopper(), salPortFeatures.isFiber(), salPortFeatures.isOther(),
103                 salPortFeatures.isPause(), salPortFeatures.isPauseAsym());
104     }
105
106     private static PortFeaturesV10 getPortFeaturesV10(
107             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures salPortFeatures) {
108
109         return new PortFeaturesV10(salPortFeatures.isHundredMbFd(), salPortFeatures.isHundredMbHd(), salPortFeatures.isTenGbFd(), salPortFeatures.isTenMbFd(), salPortFeatures.isTenMbHd(),
110                 salPortFeatures.isOneGbFd(), salPortFeatures.isOneGbHd(), salPortFeatures.isAutoeng(), salPortFeatures.isCopper(), salPortFeatures.isFiber(),
111                 salPortFeatures.isPause(), salPortFeatures.isPauseAsym());
112     }
113
114     /**
115      * This method is called as a reply to OFPMP_PORT_DESCRIPTION
116      * message(OF1.3.1)
117      *
118      * @param source  FlowCapablePort
119      * @param version openflow version
120      * @return OF:Ports
121      */
122     @VisibleForTesting
123     static Ports toPortDesc(
124             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.FlowCapablePort source,
125             short version) {
126
127         PortsBuilder oFPortDescDataBuilder = new PortsBuilder();
128
129         oFPortDescDataBuilder.setPortNo(
130                 OpenflowPortsUtil.getProtocolPortNumber(OpenflowVersion.get(version), source.getPortNumber())); // portNO
131
132         oFPortDescDataBuilder.setHwAddr(source.getHardwareAddress());
133         oFPortDescDataBuilder.setName(source.getName());
134
135         PortConfig config = maskPortConfigFields(source.getConfiguration());
136
137         oFPortDescDataBuilder.setConfig(config);
138
139         PortState portState = getPortState(source.getState());
140
141         oFPortDescDataBuilder.setState(portState);
142         oFPortDescDataBuilder.setCurrentFeatures(getPortFeatures(source.getCurrentFeature()));
143         oFPortDescDataBuilder.setAdvertisedFeatures(getPortFeatures(source.getAdvertisedFeatures()));
144         oFPortDescDataBuilder.setSupportedFeatures(getPortFeatures(source.getSupported()));
145         oFPortDescDataBuilder.setPeerFeatures(getPortFeatures(source.getPeerFeatures()));
146         oFPortDescDataBuilder.setCurrSpeed(source.getCurrentSpeed());
147         oFPortDescDataBuilder.setMaxSpeed(source.getMaximumSpeed());
148
149         return oFPortDescDataBuilder.build();
150
151     }
152
153     private static PortState getPortState(
154             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortState state) {
155
156         boolean isLinkDown = state.isLinkDown();
157         boolean isBlocked = state.isBlocked();
158         boolean isLive = state.isLive();
159
160         return new PortState(isLinkDown, isBlocked, isLive);
161
162     }
163
164     @Override
165     public Collection<Class<? extends DataContainer>> getTypes() {
166         return TYPES;
167     }
168
169     @Override
170     public PortModInput convert(Port source, VersionConvertorData data) {
171         PortConfig config = maskPortConfigFields(source.getConfiguration());
172         PortConfigV10 configV10 = maskPortConfigV10Fields(source.getConfiguration());
173
174         PortModInputBuilder portModInputBuilder = new PortModInputBuilder();
175         portModInputBuilder.setAdvertise(getPortFeatures(source.getAdvertisedFeatures()));
176         portModInputBuilder.setPortNo(new PortNumber(
177                 OpenflowPortsUtil.getProtocolPortNumber(OpenflowVersion.get(data.getVersion()), source.getPortNumber())));
178
179         portModInputBuilder.setConfig(config);
180         portModInputBuilder.setMask(MoreObjects.firstNonNull(maskPortConfigFields(source.getMask()),
181                 new PortConfig(true, true, true, true)));
182
183         portModInputBuilder.setHwAddress(new MacAddress(source.getHardwareAddress()));
184
185         portModInputBuilder.setVersion(data.getVersion());
186
187         portModInputBuilder.setConfigV10(configV10);
188         portModInputBuilder.setMaskV10(MoreObjects.firstNonNull(maskPortConfigV10Fields(source.getMask()),
189                 new PortConfigV10(true, true, true, true, true, true, true)));
190         portModInputBuilder.setAdvertiseV10(getPortFeaturesV10(source.getAdvertisedFeatures()));
191         return portModInputBuilder.build();
192     }
193 }