blob: 25f57401d4e2852ac00baa69eee46bb54e4e6d22 [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.onosproject.xosclient.api.OpenStackAccess;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070023import org.onosproject.xosclient.api.VtnServiceApi;
24import org.onosproject.xosclient.api.XosAccess;
Hyunsun Moon4c396632016-05-13 04:17:53 -070025import org.onosproject.xosclient.api.VtnService;
26import org.onosproject.xosclient.api.VtnServiceId;
27
Hyunsun Moone0f3e282016-05-13 18:58:35 -070028import org.openstack4j.api.OSClient;
Hyunsun Moond0bfe672016-06-30 10:55:10 -070029import org.openstack4j.api.exceptions.AuthenticationException;
Hyunsun Moone0f3e282016-05-13 18:58:35 -070030import org.openstack4j.model.network.Network;
31import org.openstack4j.model.network.Subnet;
32import org.openstack4j.openstack.OSFactory;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070033import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
35
36import java.io.IOException;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070037import java.util.Set;
38
Hyunsun Moon7ad92202016-04-20 10:36:02 -070039import static com.google.common.base.Preconditions.checkNotNull;
Hyunsun Moone0f3e282016-05-13 18:58:35 -070040import static com.google.common.base.Preconditions.checkArgument;
Hyunsun Moonf1c03462016-06-21 18:06:01 -070041import static org.onosproject.xosclient.api.VtnServiceApi.NetworkType.*;
42import static org.onosproject.xosclient.api.VtnServiceApi.ServiceType.*;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070043
44/**
45 * Provides CORD VTN service and service dependency APIs.
46 */
47public final class DefaultVtnServiceApi extends XosApi implements VtnServiceApi {
48
49 private final Logger log = LoggerFactory.getLogger(getClass());
50
Hyunsun Moon7ad92202016-04-20 10:36:02 -070051 /**
52 * Default constructor.
Hyunsun Moon4c396632016-05-13 04:17:53 -070053 *
54 * @param baseUrl base url
55 * @param access xos access
Hyunsun Moon7ad92202016-04-20 10:36:02 -070056 */
Hyunsun Moon4c396632016-05-13 04:17:53 -070057 public DefaultVtnServiceApi(String baseUrl, XosAccess access) {
Hyunsun Moon7ad92202016-04-20 10:36:02 -070058 super(baseUrl, access);
59 }
60
Hyunsun Moon7ad92202016-04-20 10:36:02 -070061 @Override
Hyunsun Moon4c396632016-05-13 04:17:53 -070062 public Set<VtnServiceId> services() {
Hyunsun Moon7ad92202016-04-20 10:36:02 -070063 String response = restGet(EMPTY_STRING);
64 log.trace("Get services {}", response);
65
66 ObjectMapper mapper = new ObjectMapper();
Hyunsun Moon4c396632016-05-13 04:17:53 -070067 Set<VtnServiceId> services = Sets.newHashSet();
68
Hyunsun Moon7ad92202016-04-20 10:36:02 -070069 try {
70 JsonNode nodes = mapper.readTree(response);
Hyunsun Moon4c396632016-05-13 04:17:53 -070071 nodes.fieldNames().forEachRemaining(id -> services.add(VtnServiceId.of(id)));
Hyunsun Moon7ad92202016-04-20 10:36:02 -070072 } catch (IOException e) {
73 log.warn("Failed to get service list");
Hyunsun Moon7ad92202016-04-20 10:36:02 -070074 }
Hyunsun Moon4c396632016-05-13 04:17:53 -070075 return services;
Hyunsun Moon7ad92202016-04-20 10:36:02 -070076 }
77
78 @Override
Hyunsun Moon4c396632016-05-13 04:17:53 -070079 public VtnService service(VtnServiceId serviceId) {
80 // TODO implement this when XOS provides this API
81 return null;
82 }
83
84 @Override
85 public Set<VtnServiceId> providerServices(VtnServiceId tServiceId) {
Hyunsun Moon7ad92202016-04-20 10:36:02 -070086 checkNotNull(tServiceId);
87
Hyunsun Moon4c396632016-05-13 04:17:53 -070088 String response = restGet(tServiceId.id());
Hyunsun Moon7ad92202016-04-20 10:36:02 -070089 log.trace("Get provider services {}", response);
90
91 ObjectMapper mapper = new ObjectMapper();
Hyunsun Moon4c396632016-05-13 04:17:53 -070092 Set<VtnServiceId> pServices = Sets.newHashSet();
Hyunsun Moon7ad92202016-04-20 10:36:02 -070093
94 try {
95 JsonNode nodes = mapper.readTree(response);
Hyunsun Moon4c396632016-05-13 04:17:53 -070096 nodes.forEach(node -> pServices.add(VtnServiceId.of(node.asText())));
Hyunsun Moon7ad92202016-04-20 10:36:02 -070097 } catch (IOException e) {
98 log.warn("Failed to get service dependency");
99 }
100 return pServices;
101 }
102
103 @Override
Hyunsun Moon4c396632016-05-13 04:17:53 -0700104 public Set<VtnServiceId> tenantServices(VtnServiceId tServiceId) {
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700105 checkNotNull(tServiceId);
106
107 String response = restGet(EMPTY_STRING);
108 log.trace("Get tenant services {}", response);
109
110 ObjectMapper mapper = new ObjectMapper();
Hyunsun Moon4c396632016-05-13 04:17:53 -0700111 Set<VtnServiceId> tServices = Sets.newHashSet();
112
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700113 try {
114 JsonNode nodes = mapper.readTree(response);
Hyunsun Moon4c396632016-05-13 04:17:53 -0700115 nodes.fields().forEachRemaining(entry -> entry.getValue().forEach(
116 pService -> {
117 if (pService.asText().equals(tServiceId.id())) {
118 tServices.add(VtnServiceId.of(entry.getKey()));
119 }
120 }));
Hyunsun Moon7ad92202016-04-20 10:36:02 -0700121 } catch (IOException e) {
122 log.warn("Failed to get service list");
123 }
124 return tServices;
125 }
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700126
127 @Override
128 // TODO remove this when XOS provides this information
129 public VtnService service(VtnServiceId serviceId, OpenStackAccess osAccess) {
130 checkNotNull(osAccess);
131
132 OSClient osClient = getOpenStackClient(osAccess);
133 Network osNet = osClient.networking().network().get(serviceId.id());
134 if (osNet == null) {
135 log.warn("Failed to get OpenStack network {}", serviceId);
136 return null;
137 }
138
139 // assumes all cord service networks has single subnet
140 Subnet osSubnet = osNet.getNeutronSubnets().stream()
141 .findFirst().orElse(null);
142 if (osSubnet == null) {
143 log.warn("Failed to get OpenStack subnet of network {}", serviceId);
144 return null;
145 }
146
Hyunsun Moon65040992016-07-27 18:41:34 -0700147 return VtnService.build()
148 .id(serviceId)
149 .name(osNet.getName())
150 .serviceType(serviceType(osNet.getName()))
151 .networkType(networkType(osNet.getName()))
152 .vni(osNet.getProviderSegID())
153 .subnet(osSubnet.getCidr())
154 .serviceIp(osSubnet.getGateway())
155 .providerServices(providerServices(serviceId))
156 .tenantServices(tenantServices(serviceId))
157 .build();
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700158 }
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) {
Hyunsun Moon65040992016-07-27 18:41:34 -0700180 checkArgument(!Strings.isNullOrEmpty(netName), "VTN network name cannot be null");
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700181
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) {
Hyunsun Moon65040992016-07-27 18:41:34 -0700196 checkArgument(!Strings.isNullOrEmpty(netName), "VTN network name cannot be null");
Hyunsun Moone0f3e282016-05-13 18:58:35 -0700197
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}