2 * ========================LICENSE_START=================================
4 * ======================================================================
5 * Copyright (C) 2019-2020 Nordix Foundation. All rights reserved.
6 * ======================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ========================LICENSE_END===================================
21 package org.oransc.enrichment.controllers.consumer;
23 import com.google.gson.Gson;
24 import com.google.gson.GsonBuilder;
25 import com.google.gson.JsonObject;
27 import io.swagger.annotations.Api;
28 import io.swagger.annotations.ApiOperation;
29 import io.swagger.annotations.ApiParam;
30 import io.swagger.annotations.ApiResponse;
31 import io.swagger.annotations.ApiResponses;
33 import java.lang.invoke.MethodHandles;
34 import java.util.ArrayList;
35 import java.util.List;
37 import org.oransc.enrichment.clients.ProducerCallbacks;
38 import org.oransc.enrichment.configuration.ApplicationConfig;
39 import org.oransc.enrichment.controllers.ErrorResponse;
40 import org.oransc.enrichment.repository.EiJob;
41 import org.oransc.enrichment.repository.EiJobs;
42 import org.oransc.enrichment.repository.EiType;
43 import org.oransc.enrichment.repository.EiTypes;
44 import org.oransc.enrichment.repository.ImmutableEiJob;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.springframework.beans.factory.annotation.Autowired;
48 import org.springframework.http.HttpStatus;
49 import org.springframework.http.MediaType;
50 import org.springframework.http.ResponseEntity;
51 import org.springframework.web.bind.annotation.DeleteMapping;
52 import org.springframework.web.bind.annotation.GetMapping;
53 import org.springframework.web.bind.annotation.PathVariable;
54 import org.springframework.web.bind.annotation.PutMapping;
55 import org.springframework.web.bind.annotation.RequestBody;
56 import org.springframework.web.bind.annotation.RestController;
58 @SuppressWarnings("java:S3457") // No need to call "toString()" method as formatting and string ..
59 @RestController("ConsumerController")
60 @Api(tags = {ConsumerConsts.CONSUMER_API_NAME})
61 public class ConsumerController {
63 private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
66 ApplicationConfig applicationConfig;
69 private EiJobs eiJobs;
72 private EiTypes eiTypes;
75 ProducerCallbacks producerCallbacks;
77 private static Gson gson = new GsonBuilder() //
81 @GetMapping(path = ConsumerConsts.API_ROOT + "/eitypes", produces = MediaType.APPLICATION_JSON_VALUE)
82 @ApiOperation(value = "Query EI type identifiers", notes = "DETAILS TBD")
87 message = "EI type identifiers",
88 response = String.class,
89 responseContainer = "List"), //
91 public ResponseEntity<Object> getEiTypeIdentifiers( //
93 List<String> result = new ArrayList<>();
94 for (EiType eiType : this.eiTypes.getAllEiTypes()) {
95 result.add(eiType.getId());
98 return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
101 @GetMapping(path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}", produces = MediaType.APPLICATION_JSON_VALUE)
102 @ApiOperation(value = "Definitions for an individual EI Type", notes = "Query EI type")
105 @ApiResponse(code = 200, message = "EI type", response = ConsumerEiTypeInfo.class), //
108 message = "Enrichment Information type is not found",
109 response = ErrorResponse.ErrorInfo.class)})
110 public ResponseEntity<Object> getEiType( //
111 @PathVariable("eiTypeId") String eiTypeId) {
113 EiType t = this.eiTypes.getType(eiTypeId);
114 ConsumerEiTypeInfo info = toEiTypeInfo(t);
115 return new ResponseEntity<>(gson.toJson(info), HttpStatus.OK);
116 } catch (Exception e) {
117 return ErrorResponse.create(e, HttpStatus.NOT_FOUND);
122 path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}/eijobs",
123 produces = MediaType.APPLICATION_JSON_VALUE)
124 @ApiOperation(value = "Query EI job identifiers", notes = "Returns the EI Job identifiers for an EI Type")
129 message = "EI job identifiers",
130 response = String.class,
131 responseContainer = "List"), //
134 message = "Enrichment Information type is not found",
135 response = ErrorResponse.ErrorInfo.class)})
136 public ResponseEntity<Object> getEiJobIds( //
137 @PathVariable("eiTypeId") String eiTypeId, //
139 name = ConsumerConsts.OWNER_PARAM,
141 value = ConsumerConsts.OWNER_PARAM_DESCRIPTION) //
144 this.eiTypes.getType(eiTypeId); // Just to check that the type exists
145 List<String> result = new ArrayList<>();
146 for (EiJob job : this.eiJobs.getJobsForType(eiTypeId)) {
147 result.add(job.id());
149 return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
150 } catch (Exception e) {
151 return ErrorResponse.create(e, HttpStatus.NOT_FOUND);
156 path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}/eijobs/{eiJobId}",
157 produces = MediaType.APPLICATION_JSON_VALUE)
158 @ApiOperation(value = "Individual EI Job", notes = "")
161 @ApiResponse(code = 200, message = "EI Job", response = ConsumerEiJobInfo.class), //
164 message = "Enrichment Information type or job is not found",
165 response = ErrorResponse.ErrorInfo.class)})
166 public ResponseEntity<Object> getIndividualEiJob( //
167 @PathVariable("eiTypeId") String eiTypeId, //
168 @PathVariable("eiJobId") String eiJobId) {
170 this.eiTypes.getType(eiTypeId); // Just to check that the type exists
171 EiJob job = this.eiJobs.getJob(eiJobId);
172 return new ResponseEntity<>(gson.toJson(toEiJobInfo(job)), HttpStatus.OK);
173 } catch (Exception e) {
174 return ErrorResponse.create(e, HttpStatus.NOT_FOUND);
179 path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}/eijobs/{eiJobId}/status",
180 produces = MediaType.APPLICATION_JSON_VALUE)
181 @ApiOperation(value = "EI Job status", notes = "")
184 @ApiResponse(code = 200, message = "EI Job status", response = ConsumerEiJobStatus.class), //
187 message = "Enrichment Information type or job is not found",
188 response = ErrorResponse.ErrorInfo.class)})
189 public ResponseEntity<Object> getEiJobStatus( //
190 @PathVariable("eiTypeId") String eiTypeId, //
191 @PathVariable("eiJobId") String eiJobId) {
193 this.eiTypes.getType(eiTypeId); // Just to check that the type exists
194 EiJob job = this.eiJobs.getJob(eiJobId);
195 return new ResponseEntity<>(gson.toJson(toEiJobStatus(job)), HttpStatus.OK);
196 } catch (Exception e) {
197 return ErrorResponse.create(e, HttpStatus.NOT_FOUND);
201 private ConsumerEiJobStatus toEiJobStatus(EiJob job) {
203 return new ConsumerEiJobStatus(ConsumerEiJobStatus.OperationalState.ENABLED);
207 path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}/eijobs/{eiJobId}",
208 produces = MediaType.APPLICATION_JSON_VALUE)
209 @ApiOperation(value = "Individual EI Job", notes = "Delete EI job")
212 @ApiResponse(code = 200, message = "Not used", response = void.class),
213 @ApiResponse(code = 204, message = "Job deleted", response = void.class),
216 message = "Enrichment Information type or job is not found",
217 response = ErrorResponse.ErrorInfo.class)})
218 public ResponseEntity<Object> deleteIndividualEiJob( //
219 @PathVariable("eiTypeId") String eiTypeId, //
220 @PathVariable("eiJobId") String eiJobId) {
222 EiJob job = this.eiJobs.getJob(eiJobId);
223 this.eiJobs.remove(job);
224 this.producerCallbacks.notifyProducersJobDeleted(job);
225 return new ResponseEntity<>(HttpStatus.NO_CONTENT);
226 } catch (Exception e) {
227 return ErrorResponse.create(e, HttpStatus.NOT_FOUND);
232 path = ConsumerConsts.API_ROOT + "/eitypes/{eiTypeId}/eijobs/{eiJobId}", //
233 produces = MediaType.APPLICATION_JSON_VALUE, //
234 consumes = MediaType.APPLICATION_JSON_VALUE)
235 @ApiOperation(value = "Individual EI Job", notes = "Create or update an EI Job")
238 @ApiResponse(code = 201, message = "Job created", response = void.class), //
239 @ApiResponse(code = 200, message = "Job updated", response = void.class), // ,
242 message = "Enrichment Information type is not found",
243 response = ErrorResponse.ErrorInfo.class)})
244 public ResponseEntity<Object> putIndividualEiJob( //
245 @PathVariable("eiTypeId") String eiTypeId, //
246 @PathVariable("eiJobId") String eiJobId, //
247 @RequestBody ConsumerEiJobInfo eiJobInfo) {
249 EiType eiType = this.eiTypes.getType(eiTypeId);
250 validateJobData(eiType.getJobDataSchema(), eiJobInfo.jobData);
251 final boolean newJob = this.eiJobs.get(eiJobId) == null;
252 EiJob eiJob = toEiJob(eiJobInfo, eiJobId, eiType);
253 this.eiJobs.put(eiJob);
254 this.producerCallbacks.notifyProducersJobCreated(eiJob);
255 return new ResponseEntity<>(newJob ? HttpStatus.CREATED : HttpStatus.OK);
256 } catch (Exception e) {
257 return ErrorResponse.create(e, HttpStatus.NOT_FOUND);
261 private void validateJobData(Object schemaObj, Object json) {
262 if (schemaObj instanceof JsonObject) {
263 JsonObject schema = (JsonObject) schemaObj;
264 logger.debug("schema {} json {}", schema, json);
270 private EiJob toEiJob(ConsumerEiJobInfo info, String id, EiType type) {
271 return ImmutableEiJob.builder() //
274 .owner(info.owner) //
275 .jobData(info.jobData) //
279 private ConsumerEiTypeInfo toEiTypeInfo(EiType t) {
280 return new ConsumerEiTypeInfo(t.getJobDataSchema());
283 private ConsumerEiJobInfo toEiJobInfo(EiJob s) {
284 return new ConsumerEiJobInfo(s.jobData(), s.owner());