blob: 711182072808ac988922b8e15d2373bf0c0dd877 [file] [log] [blame]
Jian Li091d8d22018-02-20 10:42:06 +09001/*
2 * Copyright 2018-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.openstacknetworking.util;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.ObjectMapper;
Jian Lieb9f77d2018-02-20 11:25:45 +090020import com.fasterxml.jackson.databind.node.ObjectNode;
Jian Li1064e4f2018-05-29 16:16:53 +090021import org.onosproject.net.DeviceId;
22import org.onosproject.openstacknode.api.OpenstackNode;
Jian Li091d8d22018-02-20 10:42:06 +090023import org.openstack4j.core.transport.ObjectMapperSingleton;
24import org.openstack4j.model.ModelEntity;
Daniel Parkc4d06402018-05-28 15:57:37 +090025import org.openstack4j.model.network.Port;
Jian Li091d8d22018-02-20 10:42:06 +090026import org.slf4j.Logger;
27import org.slf4j.LoggerFactory;
28
29import java.io.InputStream;
Jian Li1064e4f2018-05-29 16:16:53 +090030import java.util.HashMap;
31import java.util.Iterator;
32import java.util.Map;
33import java.util.Set;
34import java.util.TreeMap;
Jian Li091d8d22018-02-20 10:42:06 +090035
36import static com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT;
Daniel Parkc4d06402018-05-28 15:57:37 +090037import static org.onosproject.openstacknetworking.api.Constants.PCISLOT;
38import static org.onosproject.openstacknetworking.api.Constants.PCI_VENDOR_INFO;
39import static org.onosproject.openstacknetworking.api.Constants.PORT_NAME_PREFIX_MAP;
Jian Li091d8d22018-02-20 10:42:06 +090040
41/**
42 * An utility that used in openstack networking app.
43 */
Jian Lidea0fdb2018-04-02 19:02:48 +090044public final class OpenstackNetworkingUtil {
Jian Li091d8d22018-02-20 10:42:06 +090045
Jian Lidea0fdb2018-04-02 19:02:48 +090046 protected static final Logger log = LoggerFactory.getLogger(OpenstackNetworkingUtil.class);
Jian Li091d8d22018-02-20 10:42:06 +090047
Daniel Parkc4d06402018-05-28 15:57:37 +090048 private static final int HEX_RADIX = 16;
49 private static final int ZERO_FUNCTION_NUMBER = 0;
50 private static final String PREFIX_DEVICE_NUMBER = "s";
51 private static final String PREFIX_FUNCTION_NUMBER = "f";
52
Jian Li091d8d22018-02-20 10:42:06 +090053 /**
54 * Prevents object instantiation from external.
55 */
Jian Lidea0fdb2018-04-02 19:02:48 +090056 private OpenstackNetworkingUtil() {
Jian Li091d8d22018-02-20 10:42:06 +090057 }
58
59 /**
60 * Interprets JSON string to corresponding openstack model entity object.
61 *
62 * @param input JSON string
63 * @param entityClazz openstack model entity class
64 * @return openstack model entity object
65 */
66 public static ModelEntity jsonToModelEntity(InputStream input, Class entityClazz) {
67 ObjectMapper mapper = new ObjectMapper();
68 try {
69 JsonNode jsonTree = mapper.enable(INDENT_OUTPUT).readTree(input);
70 log.trace(new ObjectMapper().writeValueAsString(jsonTree));
71 return ObjectMapperSingleton.getContext(entityClazz)
72 .readerFor(entityClazz)
73 .readValue(jsonTree);
74 } catch (Exception e) {
75 throw new IllegalArgumentException();
76 }
77 }
Jian Lieb9f77d2018-02-20 11:25:45 +090078
79 /**
80 * Converts openstack model entity object into JSON object.
81 *
82 * @param entity openstack model entity object
83 * @param entityClazz openstack model entity class
84 * @return JSON object
85 */
86 public static ObjectNode modelEntityToJson(ModelEntity entity, Class entityClazz) {
87 ObjectMapper mapper = new ObjectMapper();
88 try {
89 String strModelEntity = ObjectMapperSingleton.getContext(entityClazz)
90 .writerFor(entityClazz)
91 .writeValueAsString(entity);
92 log.trace(strModelEntity);
93 return (ObjectNode) mapper.readTree(strModelEntity.getBytes());
94 } catch (Exception e) {
95 throw new IllegalStateException();
96 }
97 }
Jian Li1064e4f2018-05-29 16:16:53 +090098
99 /**
100 * Obtains the gateway node by device in compute node. Note that the gateway
101 * node is determined by device's device identifier.
102 *
103 * @param gws a collection of gateway nodes
104 * @param deviceId device identifier
105 * @return a gateway node
106 */
107 public static OpenstackNode getGwByComputeDevId(Set<OpenstackNode> gws, DeviceId deviceId) {
108 int numOfGw = gws.size();
109
110 if (numOfGw == 0) {
111 return null;
112 }
113
114 int gwIndex = Math.abs(deviceId.hashCode()) % numOfGw;
115
116 return getGwByIndex(gws, gwIndex);
117 }
118
119 private static OpenstackNode getGwByIndex(Set<OpenstackNode> gws, int index) {
120 Map<String, OpenstackNode> hashMap = new HashMap<>();
121 gws.forEach(gw -> hashMap.put(gw.hostname(), gw));
122 TreeMap<String, OpenstackNode> treeMap = new TreeMap<>(hashMap);
123 Iterator<String> iteratorKey = treeMap.keySet().iterator();
124
125 int intIndex = 0;
126 OpenstackNode gw = null;
127 while (iteratorKey.hasNext()) {
128 String key = iteratorKey.next();
129
130 if (intIndex == index) {
131 gw = treeMap.get(key);
132 }
133 intIndex++;
134 }
135 return gw;
136 }
Daniel Parkc4d06402018-05-28 15:57:37 +0900137
138 /**
139 * Extract the interface name with the supplied port.
140 *
141 * @param port port
142 * @return interface name
143 */
144 public static String getIntfNameFromPciAddress(Port port) {
145 if (port.getProfile() != null && port.getProfile().get(PCISLOT) == null) {
146 log.error("Failed to retrieve the interface name because of no pci_slot information from the port");
147 return null;
148 }
149 String busNumHex = port.getProfile().get(PCISLOT).toString().split(":")[1];
150 String busNumDecimal = String.valueOf(Integer.parseInt(busNumHex, HEX_RADIX));
151
152 String deviceNumHex = port.getProfile().get(PCISLOT).toString()
153 .split(":")[2]
154 .split("\\.")[0];
155 String deviceNumDecimal = String.valueOf(Integer.parseInt(deviceNumHex, HEX_RADIX));
156
157 String functionNumHex = port.getProfile().get(PCISLOT).toString()
158 .split(":")[2]
159 .split("\\.")[1];
160 String functionNumDecimal = String.valueOf(Integer.parseInt(functionNumHex, HEX_RADIX));
161
162 String intfName;
163
164 String vendorInfoForPort = String.valueOf(port.getProfile().get(PCI_VENDOR_INFO));
165
166 if (vendorInfoForPort == null) {
167 log.error("Failed to retrieve the interface name because of no pci vendor information from the port");
168 return null;
169 }
170 String portNamePrefix = PORT_NAME_PREFIX_MAP.get(vendorInfoForPort);
171 if (vendorInfoForPort == null) {
172 log.error("Failed to retrieve the interface name because of no prefix information from the port");
173 return null;
174 }
175 if (functionNumDecimal.equals(ZERO_FUNCTION_NUMBER)) {
176 intfName = portNamePrefix + busNumDecimal + PREFIX_DEVICE_NUMBER + deviceNumDecimal;
177 } else {
178 intfName = portNamePrefix + busNumDecimal + PREFIX_DEVICE_NUMBER + deviceNumDecimal
179 + PREFIX_FUNCTION_NUMBER + functionNumDecimal;
180 }
181
182 return intfName;
183 }
Jian Li091d8d22018-02-20 10:42:06 +0900184}