4615d69c4cef01a898223fc8394b882507c9444b
[nonrtric.git] / r-app-catalogue / src / main / java / org / oransc / rappcatalogue / api / ServicesApiDelegateImpl.java
1 /*-
2  * ========================LICENSE_START=================================
3  * Copyright (C) 2020 Nordix Foundation. All rights reserved.
4  * ======================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  * ========================LICENSE_END===================================
17  */
18
19 package org.oransc.rappcatalogue.api;
20
21 import java.io.IOException;
22 import java.sql.Date;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Optional;
26 import java.util.concurrent.ConcurrentHashMap;
27
28 import javax.servlet.http.HttpServletRequest;
29 import javax.servlet.http.HttpServletResponse;
30
31 import org.oransc.rappcatalogue.exception.HeaderException;
32 import org.oransc.rappcatalogue.exception.InvalidServiceException;
33 import org.oransc.rappcatalogue.exception.ServiceNotFoundException;
34 import org.oransc.rappcatalogue.model.InputService;
35 import org.oransc.rappcatalogue.model.Service;
36 import org.springframework.beans.factory.annotation.Autowired;
37 import org.springframework.http.HttpStatus;
38 import org.springframework.http.ResponseEntity;
39 import org.springframework.web.context.request.NativeWebRequest;
40
41 @org.springframework.stereotype.Service
42 public class ServicesApiDelegateImpl implements ServicesApiDelegate {
43
44     private static final String LOCATION_HEADER = "Location";
45
46     @Autowired
47     private NativeWebRequest nativeWebRequest;
48
49     private ConcurrentHashMap<String, Service> registeredServices = new ConcurrentHashMap<>();
50
51     ServicesApiDelegateImpl(NativeWebRequest nativeWebRequest) {
52         this.nativeWebRequest = nativeWebRequest;
53     }
54
55     @Override
56     public Optional<NativeWebRequest> getRequest() {
57         return Optional.of(nativeWebRequest);
58     }
59
60     @Override
61     public ResponseEntity<Service> getIndividualService(String serviceName) throws ServiceNotFoundException {
62         Service service = registeredServices.get(serviceName);
63         if (service != null) {
64             return ResponseEntity.ok(service);
65         } else {
66             throw new ServiceNotFoundException(serviceName);
67         }
68     }
69
70     @Override
71     public ResponseEntity<List<Service>> getServices() {
72         return ResponseEntity.ok(new ArrayList<>(registeredServices.values()));
73     }
74
75     @Override
76     public ResponseEntity<Void> putIndividualService(String serviceName, InputService inputService)
77         throws InvalidServiceException, HeaderException {
78         if (isServiceValid(inputService)) {
79             if (registeredServices.put(serviceName, createService(serviceName, inputService)) == null) {
80                 try {
81                     Optional<NativeWebRequest> request = getRequest();
82                     if (request.isPresent()) {
83                         addLocationHeaderToResponse(serviceName, request.get());
84                     }
85                 } catch (HeaderException e) {
86                     registeredServices.remove(serviceName);
87                     throw e;
88                 }
89                 return new ResponseEntity<>(HttpStatus.CREATED);
90             } else {
91                 return new ResponseEntity<>(HttpStatus.OK);
92             }
93         } else {
94             throw new InvalidServiceException();
95         }
96     }
97
98     private void addLocationHeaderToResponse(String serviceName, NativeWebRequest request) throws HeaderException {
99         try {
100             HttpServletRequest nativeRequest = request.getNativeRequest(HttpServletRequest.class);
101             HttpServletResponse nativeResponse = request.getNativeResponse(HttpServletResponse.class);
102             if (nativeRequest != null && nativeResponse != null) {
103                 StringBuffer requestURL = nativeRequest.getRequestURL();
104                 nativeResponse.addHeader(LOCATION_HEADER, requestURL.toString());
105                 nativeResponse.getWriter().print("");
106             } else {
107                 throw new HeaderException(LOCATION_HEADER, serviceName,
108                     new Exception("Native Request or Response missing"));
109             }
110         } catch (IOException e) {
111             throw new HeaderException(LOCATION_HEADER, serviceName, e);
112         }
113     }
114
115     @Override
116     public ResponseEntity<Void> deleteIndividualService(String serviceName) {
117         registeredServices.remove(serviceName);
118         return new ResponseEntity<>(HttpStatus.NO_CONTENT);
119     }
120
121     /*
122      * java:S2589: Boolean expressions should not be gratuitous. Even though the
123      * version property is marked as @NotNull, it might be null coming from the
124      * client, hence the null check is needed.
125      */
126     @SuppressWarnings("java:S2589")
127     private boolean isServiceValid(InputService service) {
128         String version = service.getVersion();
129         return version != null && !version.isBlank();
130     }
131
132     private Service createService(String serviceName, InputService inputService) {
133         Service service = new Service();
134         service.setName(serviceName);
135         service.setDescription(inputService.getDescription());
136         service.setDisplayName(inputService.getDisplayName());
137         service.setVersion(inputService.getVersion());
138         service.setRegistrationDate(getTodaysDate());
139         return service;
140     }
141
142     private String getTodaysDate() {
143         long millis = System.currentTimeMillis();
144         Date date = new Date(millis);
145         return date.toString();
146     }
147 }