blob: 84c366f6b690ab77288aaf1f799e3181a147eb32 [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;
Hyunsun Moond0bfe672016-06-30 10:55:10 -070031import org.openstack4j.api.exceptions.AuthenticationException;
Hyunsun Moone0f3e282016-05-13 18:58:35 -070032import org.openstack4j.model.network.Network;
33import org.openstack4j.model.network.Subnet;
34import org.openstack4j.openstack.OSFactory;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070035import org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
37
38import java.io.IOException;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070039import java.util.Set;
40
Hyunsun Moon7ad92202016-04-20 10:36:02 -070041import static com.google.common.base.Preconditions.checkNotNull;
Hyunsun Moone0f3e282016-05-13 18:58:35 -070042import static com.google.common.base.Preconditions.checkArgument;
Hyunsun Moonf1c03462016-06-21 18:06:01 -070043import static org.onosproject.xosclient.api.VtnServiceApi.NetworkType.*;
44import static org.onosproject.xosclient.api.VtnServiceApi.ServiceType.*;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070045
46/**
47 * Provides CORD VTN service and service dependency APIs.
48 */
49public final class DefaultVtnServiceApi extends XosApi implements VtnServiceApi {
50
51 private final Logger log = LoggerFactory.getLogger(getClass());
52
Hyunsun Moon7ad92202016-04-20 10:36:02 -070053 /**
54 * Default constructor.
Hyunsun Moon4c396632016-05-13 04:17:53 -070055 *
56 * @param baseUrl base url
57 * @param access xos access
Hyunsun Moon7ad92202016-04-20 10:36:02 -070058 */
Hyunsun Moon4c396632016-05-13 04:17:53 -070059 public DefaultVtnServiceApi(String baseUrl, XosAccess access) {
Hyunsun Moon7ad92202016-04-20 10:36:02 -070060 super(baseUrl, access);
61 }
62
Hyunsun Moon7ad92202016-04-20 10:36:02 -070063 @Override
Hyunsun Moon4c396632016-05-13 04:17:53 -070064 public Set<VtnServiceId> services() {
Hyunsun Moon7ad92202016-04-20 10:36:02 -070065 String response = restGet(EMPTY_STRING);
66 log.trace("Get services {}", response);
67
68 ObjectMapper mapper = new ObjectMapper();
Hyunsun Moon4c396632016-05-13 04:17:53 -070069 Set<VtnServiceId> services = Sets.newHashSet();
70
Hyunsun Moon7ad92202016-04-20 10:36:02 -070071 try {
72 JsonNode nodes = mapper.readTree(response);
Hyunsun Moon4c396632016-05-13 04:17:53 -070073 nodes.fieldNames().forEachRemaining(id -> services.add(VtnServiceId.of(id)));
Hyunsun Moon7ad92202016-04-20 10:36:02 -070074 } catch (IOException e) {
75 log.warn("Failed to get service list");
Hyunsun Moon7ad92202016-04-20 10:36:02 -070076 }
Hyunsun Moon4c396632016-05-13 04:17:53 -070077 return services;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070078 }
79
80 @Override
Hyunsun Moon4c396632016-05-13 04:17:53 -070081 public VtnService service(VtnServiceId serviceId) {
82 // TODO implement this when XOS provides this API
83 return null;
84 }
85
86 @Override
87 public Set<VtnServiceId> providerServices(VtnServiceId tServiceId) {
Hyunsun Moon7ad92202016-04-20 10:36:02 -070088 checkNotNull(tServiceId);
89
Hyunsun Moon4c396632016-05-13 04:17:53 -070090 String response = restGet(tServiceId.id());
Hyunsun Moon7ad92202016-04-20 10:36:02 -070091 log.trace("Get provider services {}", response);
92
93 ObjectMapper mapper = new ObjectMapper();
Hyunsun Moon4c396632016-05-13 04:17:53 -070094 Set<VtnServiceId> pServices = Sets.newHashSet();
Hyunsun Moon7ad92202016-04-20 10:36:02 -070095
96 try {
97 JsonNode nodes = mapper.readTree(response);
Hyunsun Moon4c396632016-05-13 04:17:53 -070098 nodes.forEach(node -> pServices.add(VtnServiceId.of(node.asText())));
Hyunsun Moon7ad92202016-04-20 10:36:02 -070099 } catch (IOException e) {
100 log.warn("Failed to get service dependency");
101 }
102 return pServices;
103 }
104
105 @Override
Hyunsun Moon4c396632016-05-13 04:17:53 -0700106 public Set<VtnServiceId> tenantServices(VtnServiceId tServiceId) {
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700107 checkNotNull(tServiceId);
108
109 String response = restGet(EMPTY_STRING);
110 log.trace("Get tenant services {}", response);
111
112 ObjectMapper mapper = new ObjectMapper();
Hyunsun Moon4c396632016-05-13 04:17:53 -0700113 Set<VtnServiceId> tServices = Sets.newHashSet();
114
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700115 try {
116 JsonNode nodes = mapper.readTree(response);
Hyunsun Moon4c396632016-05-13 04:17:53 -0700117 nodes.fields().forEachRemaining(entry -> entry.getValue().forEach(
118 pService -> {
119 if (pService.asText().equals(tServiceId.id())) {
120 tServices.add(VtnServiceId.of(entry.getKey()));
121 }
122 }));
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700123 } catch (IOException e) {
124 log.warn("Failed to get service list");
125 }
126 return tServices;
127 }
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700128
129 @Override
130 // TODO remove this when XOS provides this information
131 public VtnService service(VtnServiceId serviceId, OpenStackAccess osAccess) {
132 checkNotNull(osAccess);
133
134 OSClient osClient = getOpenStackClient(osAccess);
135 Network osNet = osClient.networking().network().get(serviceId.id());
136 if (osNet == null) {
137 log.warn("Failed to get OpenStack network {}", serviceId);
138 return null;
139 }
140
141 // assumes all cord service networks has single subnet
142 Subnet osSubnet = osNet.getNeutronSubnets().stream()
143 .findFirst().orElse(null);
144 if (osSubnet == null) {
145 log.warn("Failed to get OpenStack subnet of network {}", serviceId);
146 return null;
147 }
148
149 return new VtnService(serviceId,
150 osNet.getName(),
151 serviceType(osNet.getName()),
152 networkType(osNet.getName()),
153 Long.parseLong(osNet.getProviderSegID()),
154 IpPrefix.valueOf(osSubnet.getCidr()),
155 IpAddress.valueOf(osSubnet.getGateway()),
156 providerServices(serviceId),
157 tenantServices(serviceId));
158 }
159
160 // TODO remove this when XOS provides this information
161 private OSClient getOpenStackClient(OpenStackAccess osAccess) {
162 checkNotNull(osAccess);
163
164 // creating a client every time must be inefficient, but this method
165 // will be removed once XOS provides equivalent APIs
Hyunsun Moond0bfe672016-06-30 10:55:10 -0700166 try {
167 return OSFactory.builder()
168 .endpoint(osAccess.endpoint())
169 .credentials(osAccess.user(), osAccess.password())
170 .tenantName(osAccess.tenant())
171 .authenticate();
172 } catch (AuthenticationException e) {
173 log.warn("Failed to authenticate OpenStack API with {}", osAccess);
174 return null;
175 }
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700176 }
177
178 // TODO remove this when XOS provides this information
179 private NetworkType networkType(String netName) {
180 checkArgument(!Strings.isNullOrEmpty(netName));
181
182 String name = netName.toUpperCase();
Hyunsun Moon91ba41a2016-06-10 16:52:39 -0700183 if (name.contains(PUBLIC.name())) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700184 return PUBLIC;
Hyunsun Moonf1c03462016-06-21 18:06:01 -0700185 } else if (name.contains(MANAGEMENT_HOSTS.name())) {
186 return MANAGEMENT_HOSTS;
187 } else if (name.contains("MANAGEMENT")) {
188 return MANAGEMENT_LOCAL;
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700189 } else {
190 return PRIVATE;
191 }
192 }
193
194 // TODO remove this when XOS provides this information
195 private ServiceType serviceType(String netName) {
196 checkArgument(!Strings.isNullOrEmpty(netName));
197
198 String name = netName.toUpperCase();
Hyunsun Moon91ba41a2016-06-10 16:52:39 -0700199 if (name.contains(VSG.name())) {
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700200 return VSG;
Hyunsun Moonf1c03462016-06-21 18:06:01 -0700201 } else if (name.contains(ACCESS_AGENT.name())) {
202 return ACCESS_AGENT;
Hyunsun Moon91ba41a2016-06-10 16:52:39 -0700203 } else if (name.contains(ServiceType.MANAGEMENT.name())) {
204 return ServiceType.MANAGEMENT;
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700205 } else {
Hyunsun Moon91ba41a2016-06-10 16:52:39 -0700206 return DEFAULT;
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700207 }
208 }
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700209}