blob: ec6f6bf37238474f335db32e117895a7b9d75583 [file] [log] [blame]
Jian Licc01e452020-12-21 01:44:05 +09001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.kubevirtnode.codec;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.node.ArrayNode;
20import com.fasterxml.jackson.databind.node.ObjectNode;
21import org.onlab.packet.IpAddress;
Daniel Park734b5532022-09-26 15:13:59 +090022import org.onlab.packet.MacAddress;
Jian Licc01e452020-12-21 01:44:05 +090023import org.onosproject.codec.CodecContext;
24import org.onosproject.codec.JsonCodec;
25import org.onosproject.kubevirtnode.api.DefaultKubevirtNode;
26import org.onosproject.kubevirtnode.api.KubevirtNode;
27import org.onosproject.kubevirtnode.api.KubevirtNodeState;
28import org.onosproject.kubevirtnode.api.KubevirtPhyInterface;
29import org.onosproject.net.DeviceId;
30import org.slf4j.Logger;
31
32import java.util.ArrayList;
33import java.util.List;
34import java.util.stream.IntStream;
35
36import static com.google.common.base.Preconditions.checkNotNull;
37import static org.onlab.util.Tools.nullIsIllegal;
38import static org.onosproject.kubevirtnode.api.Constants.DATA_IP;
39import static org.onosproject.kubevirtnode.api.Constants.HOST_NAME;
40import static org.onosproject.kubevirtnode.api.Constants.MANAGEMENT_IP;
41import static org.slf4j.LoggerFactory.getLogger;
42
43/**
44 * Kubevirt node codec used for serializing and de-serializing JSON string.
45 */
46public final class KubevirtNodeCodec extends JsonCodec<KubevirtNode> {
47
48 private final Logger log = getLogger(getClass());
49
50 private static final String TYPE = "type";
51 private static final String INTEGRATION_BRIDGE = "integrationBridge";
Jian Li4fe40e52021-01-06 03:29:58 +090052 private static final String TUNNEL_BRIDGE = "tunnelBridge";
Jian Licc01e452020-12-21 01:44:05 +090053 private static final String STATE = "state";
54 private static final String PHYSICAL_INTERFACES = "phyIntfs";
Daniel Park515f5f32021-02-22 17:12:20 +090055 private static final String GATEWAY_BRIDGE_NAME = "gatewayBridgeName";
Daniel Park734b5532022-09-26 15:13:59 +090056 private static final String ELB_BRIDGE_NAME = "elbBridgeName";
57 private static final String ELB_IP = "elbIp";
58 private static final String ELB_GW_IP = "elbGwIp";
59 private static final String ELB_GW_MAC = "elbGwMac";
Jian Licc01e452020-12-21 01:44:05 +090060
61 private static final String MISSING_MESSAGE = " is required in OpenstackNode";
62
63 @Override
64 public ObjectNode encode(KubevirtNode node, CodecContext context) {
65 checkNotNull(node, "Kubevirt node cannot be null");
66
67 ObjectNode result = context.mapper().createObjectNode()
68 .put(HOST_NAME, node.hostname())
69 .put(TYPE, node.type().name())
70 .put(STATE, node.state().name())
71 .put(MANAGEMENT_IP, node.managementIp().toString());
72
73 // serialize integration bridge config
74 if (node.intgBridge() != null) {
75 result.put(INTEGRATION_BRIDGE, node.intgBridge().toString());
76 }
77
Jian Li4fe40e52021-01-06 03:29:58 +090078 // serialize tunnel bridge config
79 if (node.tunBridge() != null) {
80 result.put(TUNNEL_BRIDGE, node.tunBridge().toString());
81 }
82
Jian Licc01e452020-12-21 01:44:05 +090083 // serialize data IP only if it presents
84 if (node.dataIp() != null) {
85 result.put(DATA_IP, node.dataIp().toString());
86 }
87
88 // serialize physical interfaces, it is valid only if any of physical interface presents
89 if (node.phyIntfs() != null && !node.phyIntfs().isEmpty()) {
90 ArrayNode phyIntfs = context.mapper().createArrayNode();
91 node.phyIntfs().forEach(phyIntf -> {
92 ObjectNode phyIntfJson =
93 context.codec(KubevirtPhyInterface.class).encode(phyIntf, context);
94 phyIntfs.add(phyIntfJson);
95 });
96 result.set(PHYSICAL_INTERFACES, phyIntfs);
97 }
98
Daniel Park515f5f32021-02-22 17:12:20 +090099 // serialize external bridge if exist
100 if (node.gatewayBridgeName() != null) {
101 result.put(GATEWAY_BRIDGE_NAME, node.gatewayBridgeName());
102 }
103
Daniel Park734b5532022-09-26 15:13:59 +0900104 //serialize elb bridge and ip address if exist
105 if (node.elbBridgeName() != null) {
106 result.put(ELB_BRIDGE_NAME, node.elbBridgeName());
107 }
108
109 if (node.elbIp() != null) {
110 result.put(ELB_IP, node.elbIp().toString());
111 }
112
113 if (node.elbGwIp() != null) {
114 result.put(ELB_GW_IP, node.elbGwIp().toString());
115 }
116
117 if (node.elbGwMac() != null) {
118 result.put(ELB_GW_MAC, node.elbGwMac().toString());
119 }
120
Jian Licc01e452020-12-21 01:44:05 +0900121 return result;
122 }
123
124 @Override
125 public KubevirtNode decode(ObjectNode json, CodecContext context) {
126 if (json == null || !json.isObject()) {
127 return null;
128 }
129
130 String hostname = nullIsIllegal(json.get(HOST_NAME).asText(),
131 HOST_NAME + MISSING_MESSAGE);
132 String type = nullIsIllegal(json.get(TYPE).asText(),
133 TYPE + MISSING_MESSAGE);
134 String mIp = nullIsIllegal(json.get(MANAGEMENT_IP).asText(),
135 MANAGEMENT_IP + MISSING_MESSAGE);
136
137 KubevirtNode.Builder nodeBuilder = DefaultKubevirtNode.builder()
138 .hostname(hostname)
139 .type(KubevirtNode.Type.valueOf(type))
140 .state(KubevirtNodeState.INIT)
141 .managementIp(IpAddress.valueOf(mIp));
142
143 if (json.get(DATA_IP) != null) {
144 nodeBuilder.dataIp(IpAddress.valueOf(json.get(DATA_IP).asText()));
145 }
146
147 JsonNode intBridgeJson = json.get(INTEGRATION_BRIDGE);
148 if (intBridgeJson != null) {
149 nodeBuilder.intgBridge(DeviceId.deviceId(intBridgeJson.asText()));
150 }
151
Jian Li4fe40e52021-01-06 03:29:58 +0900152 JsonNode tunBridgeJson = json.get(TUNNEL_BRIDGE);
153 if (tunBridgeJson != null) {
154 nodeBuilder.tunBridge(DeviceId.deviceId(tunBridgeJson.asText()));
155 }
156
Jian Licc01e452020-12-21 01:44:05 +0900157 // parse physical interfaces
158 List<KubevirtPhyInterface> phyIntfs = new ArrayList<>();
159 JsonNode phyIntfsJson = json.get(PHYSICAL_INTERFACES);
160 if (phyIntfsJson != null) {
161 final JsonCodec<KubevirtPhyInterface>
162 phyIntfCodec = context.codec(KubevirtPhyInterface.class);
163
164 IntStream.range(0, phyIntfsJson.size()).forEach(i -> {
165 ObjectNode intfJson = get(phyIntfsJson, i);
166 phyIntfs.add(phyIntfCodec.decode(intfJson, context));
167 });
168 }
169 nodeBuilder.phyIntfs(phyIntfs);
170
Daniel Park515f5f32021-02-22 17:12:20 +0900171 JsonNode externalBridgeJson = json.get(GATEWAY_BRIDGE_NAME);
172 if (externalBridgeJson != null) {
173 nodeBuilder.gatewayBridgeName(externalBridgeJson.asText());
174 }
175
Daniel Park734b5532022-09-26 15:13:59 +0900176 JsonNode elbBridgeJson = json.get(ELB_BRIDGE_NAME);
177 if (elbBridgeJson != null) {
178 nodeBuilder.elbBridgeName(elbBridgeJson.asText());
179 }
180
181 JsonNode elbIpJson = json.get(ELB_IP);
182 if (elbIpJson != null) {
183 nodeBuilder.elbIp(IpAddress.valueOf(elbIpJson.asText()));
184 }
185
186 JsonNode elbGwIpJson = json.get(ELB_GW_IP);
187 if (elbIpJson != null) {
188 nodeBuilder.elbGwIp(IpAddress.valueOf(elbGwIpJson.asText()));
189 }
190
191 JsonNode elbGwMacJson = json.get(ELB_GW_MAC);
192 if (elbIpJson != null) {
193 nodeBuilder.elbGwMac(MacAddress.valueOf(elbGwMacJson.asText()));
194 }
195
196 log.trace("node is {}", nodeBuilder.build());
Jian Licc01e452020-12-21 01:44:05 +0900197
198 return nodeBuilder.build();
199 }
200}