diff options
Diffstat (limited to 'app/src/main/java/org/onap/portal/history/configuration')
7 files changed, 376 insertions, 0 deletions
diff --git a/app/src/main/java/org/onap/portal/history/configuration/BeansConfig.java b/app/src/main/java/org/onap/portal/history/configuration/BeansConfig.java new file mode 100644 index 0000000..9a60681 --- /dev/null +++ b/app/src/main/java/org/onap/portal/history/configuration/BeansConfig.java @@ -0,0 +1,50 @@ +/* + * + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + * + */ + +package org.onap.portal.history.configuration; + + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.zalando.problem.jackson.ProblemModule; + +import java.time.Clock; + +@Configuration +public class BeansConfig { + @Bean + Clock clock() { + return Clock.systemUTC(); + } + + @Bean + public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) { + return builder + .modules(new ProblemModule(), new JavaTimeModule()) + .build() + .setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + +} diff --git a/app/src/main/java/org/onap/portal/history/configuration/Errorhandler.java b/app/src/main/java/org/onap/portal/history/configuration/Errorhandler.java new file mode 100644 index 0000000..583420b --- /dev/null +++ b/app/src/main/java/org/onap/portal/history/configuration/Errorhandler.java @@ -0,0 +1,94 @@ +/* + * + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + * + */ + +package org.onap.portal.history.configuration; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.onap.portal.history.exception.ProblemException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; +import org.springframework.core.io.buffer.DataBufferFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.server.ServerWebExchange; +import org.zalando.problem.Problem; +import org.zalando.problem.Status; +import reactor.core.publisher.Mono; + +@Component +public class Errorhandler implements ErrorWebExceptionHandler { + + @Autowired + ObjectMapper objectMapper; + + /** + * Override the handle methode to implement custom error handling + * Set response status code to BAD REQUEST, set header content-type and fill the body with the Problem object along the API model + */ + @Override + public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) { + ServerHttpResponse httpResponse = exchange.getResponse(); + setResponseStatus(httpResponse, ex); + httpResponse.getHeaders().add("Content-Type", "application/problem+json"); + return httpResponse.writeWith(Mono.fromSupplier(() -> { + DataBufferFactory bufferFactory = httpResponse.bufferFactory(); + try { + return + (httpResponse.getStatusCode() == HttpStatus.INTERNAL_SERVER_ERROR) + ? httpResponse.bufferFactory().wrap(objectMapper.writeValueAsBytes(setProblemException(httpResponse, ex.getMessage()))) + : httpResponse.bufferFactory().wrap(objectMapper.writeValueAsBytes(ex)); + } catch (JsonProcessingException e) { + return bufferFactory.wrap(new byte[0]); + } + })); + } + + /** + * Set the response status + * @param httpResponse response which status code should be set + * @param ex throwable exception to identify the Problem class + */ + private void setResponseStatus(ServerHttpResponse httpResponse, Throwable ex) { + if (ex instanceof Problem) { + httpResponse.setStatusCode(HttpStatus.BAD_REQUEST); + } else { + httpResponse.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + /** + * Build a problem exception and set the response status code to BAD REQUEST for every response + * @param httpResponse response which status code should be set + * @param message for the detail of the problem exception + * @return problem exception instance + */ + private ProblemException setProblemException(ServerHttpResponse httpResponse, String message){ + httpResponse.setStatusCode(HttpStatus.BAD_REQUEST); + return ProblemException.builder() + .status(Status.INTERNAL_SERVER_ERROR) + .title(Status.INTERNAL_SERVER_ERROR.getReasonPhrase()) + .detail(message) + .build(); + + } +} diff --git a/app/src/main/java/org/onap/portal/history/configuration/LogInterceptor.java b/app/src/main/java/org/onap/portal/history/configuration/LogInterceptor.java new file mode 100644 index 0000000..113aad8 --- /dev/null +++ b/app/src/main/java/org/onap/portal/history/configuration/LogInterceptor.java @@ -0,0 +1,62 @@ +/* + * + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + * + */ + +package org.onap.portal.history.configuration; + +import org.onap.portal.history.util.Logger; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.reactive.ServerWebExchangeContextFilter; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; +import reactor.core.publisher.Mono; + +import java.util.List; + +@Component +public class LogInterceptor implements WebFilter { + public static final String EXCHANGE_CONTEXT_ATTRIBUTE = + ServerWebExchangeContextFilter.class.getName() + ".EXCHANGE_CONTEXT"; + + public static final String X_REQUEST_ID = "X-Request-Id"; + + /** + * Override a web filter to write log entries for every request and response and add header in response with X_REQUEST_ID + */ + @Override + public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { + List<String> xRequestIdList = exchange.getRequest().getHeaders().get(X_REQUEST_ID); + if (xRequestIdList != null && !xRequestIdList.isEmpty()) { + String xRequestId = xRequestIdList.get(0); + Logger.requestLog( xRequestId, exchange.getRequest().getMethod(), exchange.getRequest().getURI()); + + exchange.getResponse().getHeaders().add(X_REQUEST_ID, xRequestId); + exchange.getResponse().beforeCommit(() -> { + Logger.responseLog(xRequestId,exchange.getResponse().getStatusCode()); + return Mono.empty(); + }); + } + + return chain + .filter(exchange) + .contextWrite(cxt -> cxt.put(EXCHANGE_CONTEXT_ATTRIBUTE, exchange)); + } +} diff --git a/app/src/main/java/org/onap/portal/history/configuration/PortalHistoryConfig.java b/app/src/main/java/org/onap/portal/history/configuration/PortalHistoryConfig.java new file mode 100644 index 0000000..85304b9 --- /dev/null +++ b/app/src/main/java/org/onap/portal/history/configuration/PortalHistoryConfig.java @@ -0,0 +1,37 @@ +/* + * + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + * + */ + +package org.onap.portal.history.configuration; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.ConstructorBinding; + +import javax.validation.constraints.NotBlank; + +@Data +@ConstructorBinding +@ConfigurationProperties("portal-history") +public class PortalHistoryConfig { + + @NotBlank + private final Integer saveInterval; +} diff --git a/app/src/main/java/org/onap/portal/history/configuration/SchedulerConfig.java b/app/src/main/java/org/onap/portal/history/configuration/SchedulerConfig.java new file mode 100644 index 0000000..529cbc3 --- /dev/null +++ b/app/src/main/java/org/onap/portal/history/configuration/SchedulerConfig.java @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + * + */ + +package org.onap.portal.history.configuration; + +import org.onap.portal.history.services.ActionsService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@EnableScheduling +public class SchedulerConfig { + + private final ActionsService actionsService; + private final PortalHistoryConfig portalHistoryConfig; + + @Autowired + public SchedulerConfig(ActionsService actionsService, PortalHistoryConfig portalHistoryConfig){ + this.actionsService = actionsService; + this.portalHistoryConfig = portalHistoryConfig; + } + + /** + * This method will be trigger by Spring Boot scheduler. + * The cron execution time is configured in the application properties as well as the save interval. + */ + @Scheduled(cron="${portal-history.delete-interval}") + public void runDeleteActions(){ + actionsService.deleteActions(portalHistoryConfig.getSaveInterval()); + log.info("Delete actions in scheduled job"); + } +} diff --git a/app/src/main/java/org/onap/portal/history/configuration/SecurityConfig.java b/app/src/main/java/org/onap/portal/history/configuration/SecurityConfig.java new file mode 100644 index 0000000..e825295 --- /dev/null +++ b/app/src/main/java/org/onap/portal/history/configuration/SecurityConfig.java @@ -0,0 +1,53 @@ +/* + * + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + * + */ + +package org.onap.portal.history.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.web.server.SecurityWebFilterChain; + +/** + * Configures the access control of the API endpoints. + */ +// https://hantsy.github.io/spring-reactive-sample/security/config.html +@EnableWebFluxSecurity +@Configuration +public class SecurityConfig { + + @Bean + public SecurityWebFilterChain springSecurityWebFilterChain(ServerHttpSecurity http) { + return http.httpBasic().disable() + .formLogin().disable() + .csrf().disable() + .cors() + .and() + .authorizeExchange() + .pathMatchers(HttpMethod.GET, "/actuator/**").permitAll() + .anyExchange().authenticated() + .and() + .oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::jwt) + .build(); + } +} diff --git a/app/src/main/java/org/onap/portal/history/configuration/package-info.java b/app/src/main/java/org/onap/portal/history/configuration/package-info.java new file mode 100644 index 0000000..ccaa303 --- /dev/null +++ b/app/src/main/java/org/onap/portal/history/configuration/package-info.java @@ -0,0 +1,25 @@ +/* + * + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + * + */ + +@ParametersAreNonnullByDefault +package org.onap.portal.history.configuration; + +import javax.annotation.ParametersAreNonnullByDefault; |