Open Kilda Java Documentation
NorthboundServiceImpl.java
Go to the documentation of this file.
1 /* Copyright 2018 Telstra Open Source
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package org.openkilda.testing.service.northbound;
17 
40 
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43 import org.springframework.beans.factory.annotation.Autowired;
44 import org.springframework.beans.factory.annotation.Qualifier;
45 import org.springframework.http.HttpEntity;
46 import org.springframework.http.HttpHeaders;
47 import org.springframework.http.HttpMethod;
48 import org.springframework.http.HttpStatus;
49 import org.springframework.stereotype.Service;
50 import org.springframework.web.client.HttpClientErrorException;
51 import org.springframework.web.client.RestTemplate;
52 import org.springframework.web.util.UriComponentsBuilder;
53 
54 import java.util.Arrays;
55 import java.util.List;
56 import java.util.stream.Collectors;
57 import java.util.stream.Stream;
58 
59 @Service
60 public class NorthboundServiceImpl implements NorthboundService {
61 
62  private static final Logger LOGGER = LoggerFactory.getLogger(NorthboundServiceImpl.class);
63 
64  private static final String KILDA_CONTROLLER = "kilda";
65 
66  @Autowired
67  @Qualifier("northboundRestTemplate")
68  private RestTemplate restTemplate;
69 
70  @Override
72  return restTemplate.exchange("/api/v1/health-check", HttpMethod.GET,
73  new HttpEntity(buildHeadersWithCorrelationId()), HealthCheck.class).getBody();
74  }
75 
76  @Override
77  public FlowPayload getFlow(String flowId) {
78  try {
79  return restTemplate.exchange("/api/v1/flows/{flow_id}", HttpMethod.GET,
80  new HttpEntity(buildHeadersWithCorrelationId()), FlowPayload.class, flowId).getBody();
81  } catch (HttpClientErrorException ex) {
82  if (ex.getStatusCode() != HttpStatus.NOT_FOUND) {
83  throw ex;
84  }
85 
86  return null;
87  }
88  }
89 
90  @Override
91  public FlowPayload addFlow(FlowPayload payload) {
92  HttpEntity<FlowPayload> httpEntity = new HttpEntity<>(payload, buildHeadersWithCorrelationId());
93 
94  return restTemplate.exchange("/api/v1/flows", HttpMethod.PUT, httpEntity, FlowPayload.class).getBody();
95  }
96 
97  @Override
98  public FlowPayload updateFlow(String flowId, FlowPayload payload) {
99  HttpEntity<FlowPayload> httpEntity = new HttpEntity<>(payload, buildHeadersWithCorrelationId());
100 
101  return restTemplate.exchange("/api/v1/flows/{flow_id}", HttpMethod.PUT, httpEntity,
102  FlowPayload.class, flowId).getBody();
103  }
104 
105  @Override
106  public FlowPayload deleteFlow(String flowId) {
107  try {
108  return restTemplate.exchange("/api/v1/flows/{flow_id}", HttpMethod.DELETE,
109  new HttpEntity(buildHeadersWithCorrelationId()), FlowPayload.class, flowId).getBody();
110  } catch (HttpClientErrorException ex) {
111  if (ex.getStatusCode() != HttpStatus.NOT_FOUND) {
112  throw ex;
113  }
114 
115  return null;
116  }
117  }
118 
119  @Override
120  public List<FlowPayload> deleteAllFlows() {
121  HttpHeaders httpHeaders = buildHeadersWithCorrelationId();
122  httpHeaders.set(Utils.EXTRA_AUTH, String.valueOf(System.currentTimeMillis()));
123  FlowPayload[] deletedFlows = restTemplate.exchange("/api/v1/flows", HttpMethod.DELETE,
124  new HttpEntity(httpHeaders), FlowPayload[].class).getBody();
125  return Arrays.asList(deletedFlows);
126  }
127 
128  @Override
129  public FlowPathPayload getFlowPath(String flowId) {
130  return restTemplate.exchange("/api/v1/flows/{flow_id}/path/", HttpMethod.GET,
131  new HttpEntity(buildHeadersWithCorrelationId()), FlowPathPayload.class, flowId).getBody();
132  }
133 
134  @Override
135  public FlowIdStatusPayload getFlowStatus(String flowId) {
136  try {
137  return restTemplate.exchange("/api/v1/flows/status/{flow_id}", HttpMethod.GET,
138  new HttpEntity(buildHeadersWithCorrelationId()), FlowIdStatusPayload.class, flowId).getBody();
139  } catch (HttpClientErrorException ex) {
140  if (ex.getStatusCode() != HttpStatus.NOT_FOUND) {
141  throw ex;
142  }
143 
144  return null;
145  }
146  }
147 
148  @Override
149  public List<FlowPayload> getAllFlows() {
150  FlowPayload[] flows = restTemplate.exchange("/api/v1/flows", HttpMethod.GET,
151  new HttpEntity(buildHeadersWithCorrelationId()), FlowPayload[].class).getBody();
152  return Arrays.asList(flows);
153  }
154 
155  @Override
156  public List<Long> deleteSwitchRules(SwitchId switchId) {
157  HttpHeaders httpHeaders = buildHeadersWithCorrelationId();
158  httpHeaders.set(Utils.EXTRA_AUTH, String.valueOf(System.currentTimeMillis()));
159 
160  Long[] deletedRules = restTemplate.exchange(
161  "/api/v1/switches/{switch_id}/rules?delete-action=IGNORE_DEFAULTS", HttpMethod.DELETE,
162  new HttpEntity(httpHeaders), Long[].class, switchId).getBody();
163  return Arrays.asList(deletedRules);
164  }
165 
166  @Override
168  return restTemplate.exchange("/api/v1/switches/{switch_id}/rules/synchronize", HttpMethod.GET,
169  new HttpEntity(buildHeadersWithCorrelationId()), RulesSyncResult.class, switchId).getBody();
170  }
171 
172  @Override
173  public List<FlowValidationDto> validateFlow(String flowId) {
174  FlowValidationDto[] flowValidations = restTemplate.exchange("/api/v1/flows/{flow_id}/validate", HttpMethod.GET,
175  new HttpEntity(buildHeadersWithCorrelationId()), FlowValidationDto[].class, flowId).getBody();
176  return Arrays.asList(flowValidations);
177  }
178 
179  @Override
180  public FlowReroutePayload rerouteFlow(String flowId) {
181  return restTemplate.exchange("/api/v1/flows/{flowId}/reroute", HttpMethod.PATCH,
182  new HttpEntity(buildHeadersWithCorrelationId()), FlowReroutePayload.class, flowId).getBody();
183  }
184 
185  @Override
187  return restTemplate.exchange("/api/v1/switches/{switch_id}/rules", HttpMethod.GET,
188  new HttpEntity(buildHeadersWithCorrelationId()), SwitchFlowEntries.class, switchId).getBody();
189  }
190 
191  @Override
193  return restTemplate.exchange("/api/v1/switches/{switch_id}/rules/validate", HttpMethod.GET,
194  new HttpEntity(buildHeadersWithCorrelationId()), RulesValidationResult.class, switchId).getBody();
195  }
196 
197  @Override
198  public List<IslInfoData> getAllLinks() {
199  LinkDto[] links = restTemplate.exchange("/api/v1/links", HttpMethod.GET,
200  new HttpEntity(buildHeadersWithCorrelationId()), LinkDto[].class).getBody();
201 
202  return Stream.of(links)
203  .map(this::convertToIslInfoData)
204  .collect(Collectors.toList());
205  }
206 
207  @Override
208  public List<LinkPropsDto> getAllLinkProps() {
209  return getLinkProps(null, null, null, null);
210  }
211 
212  @Override
213  public List<LinkPropsDto> getLinkProps(SwitchId srcSwitch, Integer srcPort, SwitchId dstSwitch, Integer dstPort) {
214  UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString("/api/v1/link/props");
215  if (srcSwitch != null) {
216  uriBuilder.queryParam("src_switch", srcSwitch);
217  }
218  if (srcPort != null) {
219  uriBuilder.queryParam("src_port", srcPort);
220  }
221  if (dstSwitch != null) {
222  uriBuilder.queryParam("dst_switch", dstSwitch);
223  }
224  if (dstPort != null) {
225  uriBuilder.queryParam("dst_port", dstPort);
226  }
227  LinkPropsDto[] linkProps = restTemplate.exchange(uriBuilder.build().toString(), HttpMethod.GET,
228  new HttpEntity(buildHeadersWithCorrelationId()), LinkPropsDto[].class).getBody();
229  return Arrays.asList(linkProps);
230  }
231 
232  @Override
233  public BatchResults updateLinkProps(List<LinkPropsDto> keys) {
234  HttpEntity<List<LinkPropsDto>> httpEntity = new HttpEntity<>(keys, buildHeadersWithCorrelationId());
235  return restTemplate.exchange("/api/v1/link/props", HttpMethod.PUT, httpEntity,
236  BatchResults.class).getBody();
237  }
238 
239  @Override
240  public BatchResults deleteLinkProps(List<LinkPropsDto> keys) {
241  HttpEntity<List<LinkPropsDto>> httpEntity = new HttpEntity<>(keys, buildHeadersWithCorrelationId());
242  return restTemplate.exchange("/api/v1/link/props", HttpMethod.DELETE, httpEntity,
243  BatchResults.class).getBody();
244  }
245 
246  @Override
248  return restTemplate.exchange("/api/v1/features", HttpMethod.GET,
249  new HttpEntity(buildHeadersWithCorrelationId()), FeatureTogglePayload.class).getBody();
250  }
251 
252  @Override
254  HttpEntity<FeatureTogglePayload> httpEntity = new HttpEntity<>(request, buildHeadersWithCorrelationId());
255  return restTemplate.exchange("/api/v1/features", HttpMethod.POST, httpEntity,
256  FeatureTogglePayload.class).getBody();
257  }
258 
259  @Override
260  public List<SwitchInfoData> getAllSwitches() {
261  SwitchDto[] switches = restTemplate.exchange("/api/v1/switches", HttpMethod.GET,
262  new HttpEntity(buildHeadersWithCorrelationId()), SwitchDto[].class).getBody();
263  return Stream.of(switches)
264  .map(this::convertToSwitchInfoData)
265  .collect(Collectors.toList());
266  }
267 
268  @Override
269  public DeleteMeterResult deleteMeter(SwitchId switchId, Integer meterId) {
270  return restTemplate.exchange("/api/v1/switches/{switch_id}/meter/{meter_id}", HttpMethod.DELETE,
271  new HttpEntity(buildHeadersWithCorrelationId()), DeleteMeterResult.class, switchId, meterId).getBody();
272  }
273 
274  private HttpHeaders buildHeadersWithCorrelationId() {
275  HttpHeaders headers = new HttpHeaders();
276  headers.set(Utils.CORRELATION_ID, String.valueOf(System.currentTimeMillis()));
277  return headers;
278  }
279 
280  private IslInfoData convertToIslInfoData(LinkDto dto) {
281  List<PathNode> path = dto.getPath().stream()
282  .map(pathDto -> new PathNode(
283  new SwitchId(pathDto.getSwitchId()),
284  pathDto.getPortNo(),
285  pathDto.getSeqId(),
286  pathDto.getSegLatency()))
287  .collect(Collectors.toList());
288  return new IslInfoData(0, path, dto.getSpeed(), IslChangeType.from(dto.getState().toString()),
289  dto.getAvailableBandwidth());
290  }
291 
292  private SwitchInfoData convertToSwitchInfoData(SwitchDto dto) {
293  return new SwitchInfoData(
294  new SwitchId(dto.getSwitchId()),
295  SwitchState.from(dto.getState()),
296  dto.getAddress(),
297  dto.getHostname(),
298  dto.getDescription(),
299  KILDA_CONTROLLER);
300  }
301 }
FeatureTogglePayload toggleFeature(FeatureTogglePayload request)
List< LinkPropsDto > getLinkProps(SwitchId srcSwitch, Integer srcPort, SwitchId dstSwitch, Integer dstPort)
static final String CORRELATION_ID
Definition: Utils.java:43
static final String EXTRA_AUTH
Definition: Utils.java:47
FlowPayload updateFlow(String flowId, FlowPayload payload)
DeleteMeterResult deleteMeter(SwitchId switchId, Integer meterId)