blob: 1f83c2160dbb494698d3393cfc10917472348212 [file] [log] [blame]
Hyunsun Moon7ad92202016-04-20 10:36:02 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
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.xosclient.impl;
17
18import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.ObjectMapper;
Hyunsun Moone0f3e282016-05-13 18:58:35 -070020import com.google.common.base.Strings;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070021import com.google.common.collect.Sets;
Hyunsun Moone0f3e282016-05-13 18:58:35 -070022import org.onlab.packet.IpAddress;
23import org.onlab.packet.IpPrefix;
24import org.onosproject.xosclient.api.OpenStackAccess;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070025import org.onosproject.xosclient.api.VtnServiceApi;
26import org.onosproject.xosclient.api.XosAccess;
Hyunsun Moon4c396632016-05-13 04:17:53 -070027import org.onosproject.xosclient.api.VtnService;
28import org.onosproject.xosclient.api.VtnServiceId;
29
Hyunsun Moone0f3e282016-05-13 18:58:35 -070030import org.openstack4j.api.OSClient;
31import org.openstack4j.model.network.Network;
32import org.openstack4j.model.network.Subnet;
33import org.openstack4j.openstack.OSFactory;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070034import org.slf4j.Logger;
35import org.slf4j.LoggerFactory;
36
37import java.io.IOException;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070038import java.util.Set;
39
Hyunsun Moon7ad92202016-04-20 10:36:02 -070040import static com.google.common.base.Preconditions.checkNotNull;
Hyunsun Moone0f3e282016-05-13 18:58:35 -070041import static com.google.common.base.Preconditions.checkArgument;
Hyunsun Moonf1c03462016-06-21 18:06:01 -070042import static org.onosproject.xosclient.api.VtnServiceApi.NetworkType.*;
43import static org.onosproject.xosclient.api.VtnServiceApi.ServiceType.*;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070044
45/**
46 * Provides CORD VTN service and service dependency APIs.
47 */
48public final class DefaultVtnServiceApi extends XosApi implements VtnServiceApi {
49
50 private final Logger log = LoggerFactory.getLogger(getClass());
51
Hyunsun Moon7ad92202016-04-20 10:36:02 -070052 /**
53 * Default constructor.
Hyunsun Moon4c396632016-05-13 04:17:53 -070054 *
55 * @param baseUrl base url
56 * @param access xos access
Hyunsun Moon7ad92202016-04-20 10:36:02 -070057 */
Hyunsun Moon4c396632016-05-13 04:17:53 -070058 public DefaultVtnServiceApi(String baseUrl, XosAccess access) {
Hyunsun Moon7ad92202016-04-20 10:36:02 -070059 super(baseUrl, access);
60 }
61
Hyunsun Moon7ad92202016-04-20 10:36:02 -070062 @Override
Hyunsun Moon4c396632016-05-13 04:17:53 -070063 public Set<VtnServiceId> services() {
Hyunsun Moon7ad92202016-04-20 10:36:02 -070064 String response = restGet(EMPTY_STRING);
65 log.trace("Get services {}", response);
66
67 ObjectMapper mapper = new ObjectMapper();
Hyunsun Moon4c396632016-05-13 04:17:53 -070068 Set<VtnServiceId> services = Sets.newHashSet();
69
Hyunsun Moon7ad92202016-04-20 10:36:02 -070070 try {
71 JsonNode nodes = mapper.readTree(response);
Hyunsun Moon4c396632016-05-13 04:17:53 -070072 nodes.fieldNames().forEachRemaining(id -> services.add(VtnServiceId.of(id)));
Hyunsun Moon7ad92202016-04-20 10:36:02 -070073 } catch (IOException e) {
74 log.warn("Failed to get service list");
Hyunsun Moon7ad92202016-04-20 10:36:02 -070075 }
Hyunsun Moon4c396632016-05-13 04:17:53 -070076 return services;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070077 }
78
79 @Override
Hyunsun Moon4c396632016-05-13 04:17:53 -070080 public VtnService service(VtnServiceId serviceId) {
81 // TODO implement this when XOS provides this API
82 return null;
83 }
84
85 @Override
86 public Set<VtnServiceId> providerServices(VtnServiceId tServiceId) {
Hyunsun Moon7ad92202016-04-20 10:36:02 -070087 checkNotNull(tServiceId);
88
Hyunsun Moon4c396632016-05-13 04:17:53 -070089 String response = restGet(tServiceId.id());
Hyunsun Moon7ad92202016-04-20 10:36:02 -070090 log.trace("Get provider services {}", response);
91
92 ObjectMapper mapper = new ObjectMapper();
Hyunsun Moon4c396632016-05-13 04:17:53 -070093 Set<VtnServiceId> pServices = Sets.newHashSet();
Hyunsun Moon7ad92202016-04-20 10:36:02 -070094
95 try {
96 JsonNode nodes = mapper.readTree(response);
Hyunsun Moon4c396632016-05-13 04:17:53 -070097 nodes.forEach(node -> pServices.add(VtnServiceId.of(node.asText())));
Hyunsun Moon7ad92202016-04-20 10:36:02 -070098 } catch (IOException e) {
99 log.warn("Failed to get service dependency");
100 }
101 return pServices;
102 }
103
104 @Override
Hyunsun Moon4c396632016-05-13 04:17:53 -0700105 public Set<VtnServiceId> tenantServices(VtnServiceId tServiceId) {
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700106 checkNotNull(tServiceId);
107
108 String response = restGet(EMPTY_STRING);
109 log.trace("Get tenant services {}", response);
110
111 ObjectMapper mapper = new ObjectMapper();
Hyunsun Moon4c396632016-05-13 04:17:53 -0700112 Set<VtnServiceId> tServices = Sets.newHashSet();
113
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700114 try {
115 JsonNode nodes = mapper.readTree(response);
Hyunsun Moon4c396632016-05-13 04:17:53 -0700116 nodes.fields().forEachRemaining(entry -> entry.getValue().forEach(
117 pService -> {
118 if (pService.asText().equals(tServiceId.id())) {
119 tServices.add(VtnServiceId.of(entry.getKey()));
120 }
121 }));
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700122 } catch (IOException e) {
123 log.warn("Failed to get service list");
124 }
125 return tServices;
126 }
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700127
128 @Override
129 // TODO remove this when XOS provides this information
130 public VtnService service(VtnServiceId serviceId, OpenStackAccess osAccess) {
131 checkNotNull(osAccess);
132
133 OSClient osClient = getOpenStackClient(osAccess);
134 Network osNet = osClient.networking().network().get(serviceId.id());
135 if (osNet == null) {
136 log.warn("Failed to get OpenStack network {}", serviceId);
137 return null;
138 }
139
140 // assumes all cord service networks has single subnet
141 Subnet osSubnet = osNet.getNeutronSubnets().stream()
142 .findFirst().orElse(null);
143 if (osSubnet == null) {
144 log.warn("Failed to get OpenStack subnet of network {}", serviceId);
145 return null;
146 }
147
148 return new VtnService(serviceId,
149 osNet.getName(),
150 serviceType(osNet.getName()),
151 networkType(osNet.getName()),
152 Long.parseLong(osNet.getProviderSegID()),
153 IpPrefix.valueOf(osSubnet.getCidr()),
154 IpAddress.valueOf(osSubnet.getGateway()),
155 providerServices(serviceId),
156 tenantServices(serviceId));
157 }
158
159 // TODO remove this when XOS provides this information
160 private OSClient getOpenStackClient(OpenStackAccess osAccess) {
161 checkNotNull(osAccess);
162
163 // creating a client every time must be inefficient, but this method
164 // will be removed once XOS provides equivalent APIs
165 return OSFactory.builder()
166 .endpoint(osAccess.endpoint())
167 .credentials(osAccess.user(), osAccess.password())
168 .tenantName(osAccess.tenant())
169 .authenticate();
170 }
171
172 // TODO remove this when XOS provides this information
173 private NetworkType networkType(String netName) {
174 checkArgument(!Strings.isNullOrEmpty(netName));
175
176 String name = netName.toUpperCase();
Hyunsun Moon91ba41a2016-06-10 16:52:39 -0700177 if (name.contains(PUBLIC.name())) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700178 return PUBLIC;
Hyunsun Moonf1c03462016-06-21 18:06:01 -0700179 } else if (name.contains(MANAGEMENT_HOSTS.name())) {
180 return MANAGEMENT_HOSTS;
181 } else if (name.contains("MANAGEMENT")) {
182 return MANAGEMENT_LOCAL;
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700183 } else {
184 return PRIVATE;
185 }
186 }
187
188 // TODO remove this when XOS provides this information
189 private ServiceType serviceType(String netName) {
190 checkArgument(!Strings.isNullOrEmpty(netName));
191
192 String name = netName.toUpperCase();
Hyunsun Moon91ba41a2016-06-10 16:52:39 -0700193 if (name.contains(VSG.name())) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700194 return VSG;
Hyunsun Moonf1c03462016-06-21 18:06:01 -0700195 } else if (name.contains(ACCESS_AGENT.name())) {
196 return ACCESS_AGENT;
Hyunsun Moon91ba41a2016-06-10 16:52:39 -0700197 } else if (name.contains(ServiceType.MANAGEMENT.name())) {
198 return ServiceType.MANAGEMENT;
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700199 } else {
Hyunsun Moon91ba41a2016-06-10 16:52:39 -0700200 return DEFAULT;
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700201 }
202 }
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700203}