diff options
author | FrancescoFioraEst <francesco.fiora@est.tech> | 2021-07-05 10:36:42 +0100 |
---|---|---|
committer | FrancescoFioraEst <francesco.fiora@est.tech> | 2021-07-09 17:54:37 +0100 |
commit | d5fb4e04527f47f78e9116e3573c21dd75ff8abb (patch) | |
tree | d9b784ef679123c199e1e7aea5220b42f1a9cfea /runtime-controlloop/src/main | |
parent | 8c802e778db60e269e2e66c7a6609bf905f6ad79 (diff) |
Convert controlloop runtime to springboot framework
Issue-ID: POLICY-3355
Change-Id: Ie1667b749eed28b7e526cd4695f45d8ed736c4e7
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
Diffstat (limited to 'runtime-controlloop/src/main')
30 files changed, 1042 insertions, 969 deletions
diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/Application.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/Application.java new file mode 100644 index 000000000..a2b6f62d4 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/Application.java @@ -0,0 +1,32 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningHandler.java deleted file mode 100644 index 74975e768..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningHandler.java +++ /dev/null @@ -1,78 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * 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 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.runtime.commissioning; - -import java.io.IOException; -import java.util.Set; -import javax.ws.rs.core.Response; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.runtime.commissioning.rest.CommissioningController; -import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; -import org.onap.policy.common.utils.services.Registry; -import org.onap.policy.models.base.PfModelRuntimeException; - -/** - * This class handles commissioning of control loop definitions. - */ -public final class CommissioningHandler extends ControlLoopHandler { - - @Getter - private CommissioningProvider provider; - - /** - * Gets the CommissioningHandler. - * - * @return CommissioningHandler - */ - public static CommissioningHandler getInstance() { - return Registry.get(CommissioningHandler.class.getName()); - } - - /** - * Create a handler. - * - * @param controlLoopParameters the parameters for access to the database - */ - public CommissioningHandler(ClRuntimeParameterGroup controlLoopParameters) { - super(controlLoopParameters.getDatabaseProviderParameters()); - } - - @Override - public Set<Class<?>> getProviderClasses() { - return Set.of(CommissioningController.class); - } - - @Override - public void startProviders() { - provider = new CommissioningProvider(getDatabaseProviderParameters()); - } - - @Override - public void stopProviders() { - try { - provider.close(); - } catch (IOException e) { - throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, - "an error has occured while stopping commissioning providers", e); - } - } -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java index 5bbf6a079..22809e8c0 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java @@ -31,21 +31,23 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.provider.PolicyModelsProvider; import org.onap.policy.models.provider.PolicyModelsProviderFactory; -import org.onap.policy.models.provider.PolicyModelsProviderParameters; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplates; import org.onap.policy.models.tosca.authorative.concepts.ToscaTypedEntityFilter; +import org.springframework.stereotype.Component; /** * This class provides the create, read and delete actions on Commissioning of Control Loop concepts in the database to * the callers. */ +@Component public class CommissioningProvider implements Closeable { public static final String CONTROL_LOOP_NODE_TYPE = "org.onap.policy.clamp.controlloop.ControlLoop"; @@ -56,19 +58,20 @@ public class CommissioningProvider implements Closeable { /** * Create a commissioning provider. - * @param databaseProviderParameters parameters for database access + * + * @param controlLoopParameters the parameters for access to the database * @throws PfModelRuntimeException on errors creating the database provider */ - public CommissioningProvider(PolicyModelsProviderParameters databaseProviderParameters) { + public CommissioningProvider(ClRuntimeParameterGroup controlLoopParameters) { try { modelsProvider = new PolicyModelsProviderFactory() - .createPolicyModelsProvider(databaseProviderParameters); + .createPolicyModelsProvider(controlLoopParameters.getDatabaseProviderParameters()); } catch (PfModelException e) { throw new PfModelRuntimeException(e); } try { - clProvider = new ControlLoopProvider(databaseProviderParameters); + clProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters()); } catch (PfModelException e) { throw new PfModelRuntimeException(e); } @@ -78,6 +81,7 @@ public class CommissioningProvider implements Closeable { public void close() throws IOException { try { modelsProvider.close(); + clProvider.close(); } catch (PfModelException e) { throw new IOException("error closing modelsProvider", e); } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/AafConfiguration.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/AafConfiguration.java new file mode 100644 index 000000000..4483fbd1b --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/AafConfiguration.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP CLAMP + * ================================================================================ + * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights + * reserved. + * ================================================================================ + * 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. + * ============LICENSE_END============================================ + * =================================================================== + * + */ + +package org.onap.policy.clamp.controlloop.runtime.config; + +import javax.servlet.Filter; +import org.onap.policy.clamp.controlloop.runtime.main.web.ControlLoopAafFilter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +@Configuration +@Profile("clamp-aaf-authentication") +public class AafConfiguration { + + /** + * Method to return Aaf filter. + * + * @return Filter + */ + @Bean + public Filter aafFilter() { + return new ControlLoopAafFilter(); + } + +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ActivatorConfig.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ActivatorConfig.java new file mode 100644 index 000000000..1d6b92e77 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ActivatorConfig.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.config; + +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +import org.onap.policy.clamp.controlloop.runtime.main.startstop.ClRuntimeActivator; +import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ActivatorConfig { + + /** + * Create and start ClRuntimeActivator. + * + * @param clRuntimeParameterGroup the parameters for the control loop runtime service + * @param supervisionHandler the SupervisionHandler + * @return ClRuntimeActivator + */ + @Bean + public ClRuntimeActivator clRuntimeActivator(ClRuntimeParameterGroup clRuntimeParameterGroup, + SupervisionHandler supervisionHandler) { + var clRuntimeActivator = new ClRuntimeActivator(clRuntimeParameterGroup, supervisionHandler); + clRuntimeActivator.start(); + return clRuntimeActivator; + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/CoderHttpMesageConverter.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/CoderHttpMesageConverter.java new file mode 100644 index 000000000..cdd6ea73b --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/CoderHttpMesageConverter.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.config; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import javax.ws.rs.core.Response; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.StandardYamlCoder; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.AbstractHttpMessageConverter; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.converter.HttpMessageNotWritableException; + +public class CoderHttpMesageConverter<T> extends AbstractHttpMessageConverter<T> { + + private Coder coder; + + public CoderHttpMesageConverter(String type) { + super(new MediaType("application", type, StandardCharsets.UTF_8)); + this.coder = "json".equals(type) ? new StandardCoder() : new StandardYamlCoder(); + } + + @Override + protected boolean supports(Class<?> clazz) { + return true; + } + + @Override + protected T readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage) + throws IOException, HttpMessageNotReadableException { + try (var is = new InputStreamReader(inputMessage.getBody(), StandardCharsets.UTF_8)) { + return coder.decode(is, clazz); + } catch (CoderException e) { + throw new ControlLoopRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); + } + } + + @Override + protected void writeInternal(T t, HttpOutputMessage outputMessage) + throws IOException, HttpMessageNotWritableException { + try (var writer = new OutputStreamWriter(outputMessage.getBody(), StandardCharsets.UTF_8)) { + coder.encode(writer, t); + } catch (CoderException e) { + throw new ControlLoopRuntimeException(Response.Status.BAD_REQUEST, e.getMessage(), e); + } + } + +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ConverterConfiguration.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ConverterConfiguration.java new file mode 100644 index 000000000..ee0461994 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/ConverterConfiguration.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.config; + +import java.util.List; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class ConverterConfiguration implements WebMvcConfigurer { + + @Override + public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { + converters.add(new CoderHttpMesageConverter<>("yaml")); + converters.add(new CoderHttpMesageConverter<>("json")); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/FilterConfig.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/FilterConfig.java new file mode 100644 index 000000000..d58553ae4 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/FilterConfig.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.config; + +import org.onap.policy.clamp.controlloop.runtime.main.web.RequestResponseLoggingFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FilterConfig { + + /** + * Logging Filter configuration. + * + * @return FilterRegistrationBean + */ + @Bean + public FilterRegistrationBean<RequestResponseLoggingFilter> loggingFilter() { + FilterRegistrationBean<RequestResponseLoggingFilter> registrationBean = new FilterRegistrationBean<>(); + + registrationBean.setFilter(new RequestResponseLoggingFilter()); + registrationBean.addUrlPatterns("/onap/controlloop/v2/*"); + + return registrationBean; + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/PropertiesConfig.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/PropertiesConfig.java new file mode 100644 index 000000000..04bd35da3 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/PropertiesConfig.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.config; + +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterHandler; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class PropertiesConfig { + + @Bean + public ClRuntimeParameterGroup clRuntimeParameterGroup(@Value("${runtime.file}") String file) + throws ControlLoopException { + return new ClRuntimeParameterHandler().getParameters(file); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SecurityConfig.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SecurityConfig.java new file mode 100644 index 000000000..846944ea2 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SecurityConfig.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${security.enable-csrf:true}") + private boolean csrfEnabled = true; + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.authorizeRequests() + .antMatchers().authenticated() + .anyRequest().authenticated() + .and().httpBasic(); + // @formatter:on + + if (!csrfEnabled) { + http.csrf().disable(); + } + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SpringFoxConfig.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SpringFoxConfig.java new file mode 100644 index 000000000..d8c703397 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/config/SpringFoxConfig.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.config; + +import org.onap.policy.clamp.controlloop.runtime.main.rest.MonitoringQueryController; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +@Configuration +public class SpringFoxConfig { + + /** + * Docket Spring Fox Config. + * + * @return Docket + */ + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2).select() + .apis(RequestHandlerSelectors.basePackage(MonitoringQueryController.class.getPackageName())) + .paths(PathSelectors.any()).build(); + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java index f458d7c51..c01a0b989 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java @@ -39,6 +39,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.ObjectValidationResult; @@ -46,29 +47,35 @@ import org.onap.policy.common.parameters.ValidationResult; import org.onap.policy.common.parameters.ValidationStatus; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.provider.PolicyModelsProviderParameters; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.springframework.stereotype.Component; /** * This class is dedicated to the Instantiation of Commissioned control loop. */ +@Component public class ControlLoopInstantiationProvider implements Closeable { private final ControlLoopProvider controlLoopProvider; private final CommissioningProvider commissioningProvider; + private final SupervisionHandler supervisionHandler; private static final Object lockit = new Object(); /** * Create a instantiation provider. * - * @param databaseProviderParameters the parameters for database access + * @param controlLoopParameters the parameters for access to the database + * @param commissioningProvider CommissioningProvider + * @param supervisionHandler SupervisionHandler * @throws PfModelRuntimeException on errors creating a provider */ - public ControlLoopInstantiationProvider(PolicyModelsProviderParameters databaseProviderParameters) { + public ControlLoopInstantiationProvider(ClRuntimeParameterGroup controlLoopParameters, + CommissioningProvider commissioningProvider, SupervisionHandler supervisionHandler) { + this.commissioningProvider = commissioningProvider; + this.supervisionHandler = supervisionHandler; try { - controlLoopProvider = new ControlLoopProvider(databaseProviderParameters); - commissioningProvider = new CommissioningProvider(databaseProviderParameters); + controlLoopProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters()); } catch (PfModelException e) { throw new PfModelRuntimeException(e); } @@ -93,7 +100,7 @@ public class ControlLoopInstantiationProvider implements Closeable { var checkControlLoop = controlLoopProvider.getControlLoop(controlLoop.getKey().asIdentifier()); if (checkControlLoop != null) { throw new PfModelException(Response.Status.BAD_REQUEST, - controlLoop.getKey().asIdentifier() + " already defined"); + controlLoop.getKey().asIdentifier() + " already defined"); } } BeanValidationResult validationResult = validateControlLoops(controlLoops); @@ -105,7 +112,7 @@ public class ControlLoopInstantiationProvider implements Closeable { var response = new InstantiationResponse(); response.setAffectedControlLoops(controlLoops.getControlLoopList().stream() - .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList())); + .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList())); return response; } @@ -128,7 +135,7 @@ public class ControlLoopInstantiationProvider implements Closeable { var response = new InstantiationResponse(); response.setAffectedControlLoops(controlLoops.getControlLoopList().stream() - .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList())); + .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList())); return response; } @@ -148,18 +155,18 @@ public class ControlLoopInstantiationProvider implements Closeable { var subResult = new BeanValidationResult("entry " + controlLoop.getDefinition().getName(), controlLoop); List<ToscaNodeTemplate> toscaNodeTemplates = commissioningProvider.getControlLoopDefinitions( - controlLoop.getDefinition().getName(), controlLoop.getDefinition().getVersion()); + controlLoop.getDefinition().getName(), controlLoop.getDefinition().getVersion()); if (toscaNodeTemplates.isEmpty()) { subResult.addResult(new ObjectValidationResult("ControlLoop", controlLoop.getDefinition().getName(), - ValidationStatus.INVALID, "Commissioned control loop definition not FOUND")); + ValidationStatus.INVALID, "Commissioned control loop definition not FOUND")); } else if (toscaNodeTemplates.size() > 1) { subResult.addResult(new ObjectValidationResult("ControlLoop", controlLoop.getDefinition().getName(), - ValidationStatus.INVALID, "Commissioned control loop definition not VALID")); + ValidationStatus.INVALID, "Commissioned control loop definition not VALID")); } else { List<ToscaNodeTemplate> clElementDefinitions = - commissioningProvider.getControlLoopElementDefinitions(toscaNodeTemplates.get(0)); + commissioningProvider.getControlLoopElementDefinitions(toscaNodeTemplates.get(0)); // @formatter:off Map<String, ToscaConceptIdentifier> definitions = clElementDefinitions @@ -185,7 +192,7 @@ public class ControlLoopInstantiationProvider implements Closeable { * @return the validation result */ private ValidationResult validateDefinition(Map<String, ToscaConceptIdentifier> definitions, - ToscaConceptIdentifier definition) { + ToscaConceptIdentifier definition) { var result = new BeanValidationResult("entry " + definition.getName(), definition); ToscaConceptIdentifier identifier = definitions.get(definition.getName()); if (identifier == null) { @@ -214,12 +221,12 @@ public class ControlLoopInstantiationProvider implements Closeable { for (ControlLoop controlLoop : controlLoops) { if (!ControlLoopState.UNINITIALISED.equals(controlLoop.getState())) { throw new PfModelException(Response.Status.BAD_REQUEST, - "Control Loop State is still " + controlLoop.getState()); + "Control Loop State is still " + controlLoop.getState()); } } response.setAffectedControlLoops(Collections - .singletonList(controlLoopProvider.deleteControlLoop(name, version).getKey().asIdentifier())); + .singletonList(controlLoopProvider.deleteControlLoop(name, version).getKey().asIdentifier())); } return response; } @@ -248,7 +255,7 @@ public class ControlLoopInstantiationProvider implements Closeable { * @throws ControlLoopException on ordered state invalid */ public InstantiationResponse issueControlLoopCommand(InstantiationCommand command) - throws ControlLoopException, PfModelException { + throws ControlLoopException, PfModelException { if (command.getOrderedState() == null) { throw new ControlLoopException(Status.BAD_REQUEST, "ordered state invalid or not specified on command"); @@ -264,7 +271,6 @@ public class ControlLoopInstantiationProvider implements Closeable { controlLoopProvider.updateControlLoops(controlLoops); } - var supervisionHandler = SupervisionHandler.getInstance(); supervisionHandler.triggerControlLoopSupervision(command.getControlLoopIdentifierList()); var response = new InstantiationResponse(); response.setAffectedControlLoops(command.getControlLoopIdentifierList()); diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationHandler.java deleted file mode 100644 index 67fd9455e..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationHandler.java +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * 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 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.runtime.instantiation; - -import java.io.IOException; -import java.util.Set; -import javax.ws.rs.core.Response; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.runtime.instantiation.rest.InstantiationController; -import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; -import org.onap.policy.common.utils.services.Registry; -import org.onap.policy.models.base.PfModelRuntimeException; - -/** - * This class handles instantiation of control loop instances. - * - * <p/>It is effectively a singleton that is started at system start - */ -public final class InstantiationHandler extends ControlLoopHandler { - - @Getter - private ControlLoopInstantiationProvider controlLoopInstantiationProvider; - - /** - * Gets the InstantiationHandler. - * - * @return InstantiationHandler - */ - public static InstantiationHandler getInstance() { - return Registry.get(InstantiationHandler.class.getName()); - } - - /** - * Create a handler. - * - * @param controlLoopParameters the parameters for access to the database - */ - public InstantiationHandler(ClRuntimeParameterGroup controlLoopParameters) { - super(controlLoopParameters.getDatabaseProviderParameters()); - } - - @Override - public Set<Class<?>> getProviderClasses() { - return Set.of(InstantiationController.class); - } - - @Override - public void startProviders() { - controlLoopInstantiationProvider = new ControlLoopInstantiationProvider(getDatabaseProviderParameters()); - } - - @Override - public void stopProviders() { - try { - controlLoopInstantiationProvider.close(); - } catch (IOException e) { - throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); - } - } -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ClRuntimeParameterHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ClRuntimeParameterHandler.java index a463ad171..bcf1124d2 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ClRuntimeParameterHandler.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/parameters/ClRuntimeParameterHandler.java @@ -23,7 +23,6 @@ package org.onap.policy.clamp.controlloop.runtime.main.parameters; import java.io.File; import javax.ws.rs.core.Response; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.runtime.main.startstop.ClRuntimeCommandLineArguments; import org.onap.policy.common.parameters.ValidationResult; import org.onap.policy.common.utils.coder.Coder; import org.onap.policy.common.utils.coder.CoderException; @@ -39,37 +38,33 @@ public class ClRuntimeParameterHandler { /** * Read the parameters from the parameter file. * - * @param arguments the arguments passed to control loop runtime + * @param path the path passed to control loop runtime * @return the parameters read from the configuration file * @throws ControlLoopException on parameter exceptions */ - public ClRuntimeParameterGroup getParameters(final ClRuntimeCommandLineArguments arguments) - throws ControlLoopException { + public ClRuntimeParameterGroup getParameters(final String path) throws ControlLoopException { ClRuntimeParameterGroup clRuntimeParameterGroup = null; // Read the parameters try { // Read the parameters from JSON - File file = new File(arguments.getFullConfigurationFilePath()); + File file = new File(path); clRuntimeParameterGroup = CODER.decode(file, ClRuntimeParameterGroup.class); } catch (final CoderException e) { - throw new ControlLoopException( - Response.Status.NOT_ACCEPTABLE, "error reading parameters from \"" - + arguments.getConfigurationFilePath() + "\"\n" + "(" + e.getClass().getSimpleName() + ")", - e); + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + "error reading parameters from \"" + path + "\"\n" + "(" + e.getClass().getSimpleName() + ")", e); } // The JSON processing returns null if there is an empty file if (clRuntimeParameterGroup == null) { - throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, - "no parameters found in \"" + arguments.getConfigurationFilePath() + "\""); + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, "no parameters found in \"" + path + "\""); } // validate the parameters final ValidationResult validationResult = clRuntimeParameterGroup.validate(); if (!validationResult.isValid()) { - throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, "validation error(s) on parameters from \"" - + arguments.getConfigurationFilePath() + "\"\n" + validationResult.getResult()); + throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, + "validation error(s) on parameters from \"" + path + "\"\n" + validationResult.getResult()); } return clRuntimeParameterGroup; diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java index ebfbbd5ee..a03254272 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningController.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/CommissioningController.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.controlloop.runtime.commissioning.rest; +package org.onap.policy.clamp.controlloop.runtime.main.rest; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -30,39 +30,43 @@ import io.swagger.annotations.ExtensionProperty; import io.swagger.annotations.ResponseHeader; import java.util.List; import java.util.UUID; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse; -import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningHandler; import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider; -import org.onap.policy.clamp.controlloop.runtime.main.rest.RestController; +import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; /** * Class to provide REST end points for creating, deleting, querying commissioned control loops. */ -public class CommissioningController extends RestController { +@RestController +public class CommissioningController extends AbstractRestController { private static final Logger LOGGER = LoggerFactory.getLogger(CommissioningController.class); private final CommissioningProvider provider; /** - * create Commissioning Controller. + * Create Commissioning Controller. + * + * @param provider the CommissioningProvider */ - public CommissioningController() { - this.provider = CommissioningHandler.getInstance().getProvider(); + public CommissioningController(CommissioningProvider provider) { + this.provider = provider; } /** @@ -73,8 +77,9 @@ public class CommissioningController extends RestController { * @return a response */ // @formatter:off - @POST - @Path("/commission") + @PostMapping(value = "/commission", + consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}, + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation( value = "Commissions control loop definitions", notes = "Commissions control loop definitions, returning the commissioned control loop definition IDs", @@ -118,19 +123,19 @@ public class CommissioningController extends RestController { } ) // @formatter:on - public Response create(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Entity Body of Control Loop", required = true) ToscaServiceTemplate body) { - + public ResponseEntity<CommissioningResponse> create( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Entity Body of Control Loop", required = true) @RequestBody ToscaServiceTemplate body) { try { - CommissioningResponse response = provider.createControlLoopDefinitions(body); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); + return ResponseEntity.ok().body(provider.createControlLoopDefinitions(body)); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("Commissioning of the control loops failed", e); var resp = new CommissioningResponse(); resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return returnResponse(e.getErrorResponse().getResponseCode(), requestId, resp); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); } } @@ -144,8 +149,8 @@ public class CommissioningController extends RestController { * @return a response */ // @formatter:off - @DELETE - @Path("/commission") + @DeleteMapping(value = "/commission", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Delete a commissioned control loop", notes = "Deletes a Commissioned Control Loop, returning optional error details", response = CommissioningResponse.class, @@ -187,20 +192,24 @@ public class CommissioningController extends RestController { } ) // @formatter:on - public Response delete(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop definition name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Control Loop definition version", required = true) @QueryParam("version") String version) { + public ResponseEntity<CommissioningResponse> delete( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = true) @RequestParam( + value = "name") String name, + @ApiParam( + value = "Control Loop definition version", + required = true) @RequestParam("version") String version) { try { - CommissioningResponse response = provider.deleteControlLoopDefinition(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); + return ResponseEntity.ok().body(provider.deleteControlLoopDefinition(name, version)); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("Decommisssioning of control loop failed", e); var resp = new CommissioningResponse(); resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return returnResponse(e.getErrorResponse().getResponseCode(), requestId, resp); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); } } @@ -214,8 +223,8 @@ public class CommissioningController extends RestController { * @return the control loop definitions */ // @formatter:off - @GET - @Path("/commission") + @GetMapping(value = "/commission", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of the requested commissioned control loop definitions", notes = "Queries details of the requested commissioned control loop definitions, " + "returning all control loop details", @@ -251,20 +260,25 @@ public class CommissioningController extends RestController { } ) // @formatter:on - public Response query(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop definition name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Control Loop definition version", required = true) @QueryParam("version") String version) { + public ResponseEntity<?> query( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = false) @RequestParam( + value = "name", + required = false) String name, + @ApiParam(value = "Control Loop definition version", required = false) @RequestParam( + value = "version", + required = false) String version) { try { - List<ToscaNodeTemplate> response = provider.getControlLoopDefinitions(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); + return ResponseEntity.ok().body(provider.getControlLoopDefinitions(name, version)); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("Get of control loop definitions failed", e); var resp = new CommissioningResponse(); resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return returnResponse(e.getErrorResponse().getResponseCode(), requestId, resp); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); } } @@ -278,8 +292,8 @@ public class CommissioningController extends RestController { * @return the specified tosca service template */ // @formatter:off - @GET - @Path("/commission/toscaservicetemplate") + @GetMapping(value = "/commission/toscaservicetemplate", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of the requested tosca service templates", notes = "Queries details of the requested commissioned tosca service template, " + "returning all tosca service template details", @@ -315,21 +329,25 @@ public class CommissioningController extends RestController { } ) // @formatter:on - public Response queryToscaServiceTemplate( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Tosca service template name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Tosca service template version", required = true) @QueryParam("version") String version) { + public ResponseEntity<?> queryToscaServiceTemplate( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Tosca service template name", required = false) @RequestParam( + value = "name", + required = false) String name, + @ApiParam(value = "Tosca service template version", required = true) @RequestParam( + value = "version", + required = false) String version) { try { - var response = provider.getToscaServiceTemplate(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); + return ResponseEntity.ok().body(provider.getToscaServiceTemplate(name, version)); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("Get of tosca service template failed", e); var resp = new CommissioningResponse(); resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return returnResponse(e.getErrorResponse().getResponseCode(), requestId, resp); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); } } @@ -343,8 +361,8 @@ public class CommissioningController extends RestController { * @return the control loop element definitions */ // @formatter:off - @GET - @Path("/commission/elements") + @GetMapping(value = "/commission/elements", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of the requested commissioned control loop element definitions", notes = "Queries details of the requested commissioned control loop element definitions, " + "returning all control loop elements' details", @@ -380,9 +398,16 @@ public class CommissioningController extends RestController { } ) // @formatter:on - public Response queryElements(@HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop definition name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Control Loop definition version", required = true) @QueryParam("version") String version) { + public ResponseEntity<?> queryElements( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = false) @RequestParam( + value = "name", + required = false) String name, + @ApiParam(value = "Control Loop definition version", required = true) @RequestParam( + value = "version", + required = false) String version) { try { List<ToscaNodeTemplate> nodeTemplate = provider.getControlLoopDefinitions(name, version); @@ -390,23 +415,18 @@ public class CommissioningController extends RestController { if (nodeTemplate.size() > 1) { var resp = new CommissioningResponse(); resp.setErrorDetails("Multiple ControlLoops are not supported"); - return returnResponse(Response.Status.NOT_ACCEPTABLE, requestId, resp); + return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).body(resp); } List<ToscaNodeTemplate> response = provider.getControlLoopElementDefinitions(nodeTemplate.get(0)); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); + return ResponseEntity.ok().body(response); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("Get of control loop element definitions failed", e); var resp = new CommissioningResponse(); resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return returnResponse(e.getErrorResponse().getResponseCode(), requestId, resp); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); } } - - private Response returnResponse(Response.Status status, UUID requestId, CommissioningResponse resp) { - return addLoggingHeaders(addVersionControlHeaders(Response.status(status)), requestId).entity(resp).build(); - } } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java index ea36c71fb..aba585e29 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationController.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/InstantiationController.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.controlloop.runtime.instantiation.rest; +package org.onap.policy.clamp.controlloop.runtime.main.rest; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -29,32 +29,33 @@ import io.swagger.annotations.Extension; import io.swagger.annotations.ExtensionProperty; import io.swagger.annotations.ResponseHeader; import java.util.UUID; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; import org.onap.policy.clamp.controlloop.runtime.instantiation.ControlLoopInstantiationProvider; -import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationHandler; -import org.onap.policy.clamp.controlloop.runtime.main.rest.RestController; +import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.errors.concepts.ErrorResponseInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; /** * Class to provide REST end points for creating, deleting, query and commanding a control loop definition. */ -public class InstantiationController extends RestController { +@RestController +public class InstantiationController extends AbstractRestController { private static final Logger LOGGER = LoggerFactory.getLogger(InstantiationController.class); @@ -62,10 +63,12 @@ public class InstantiationController extends RestController { private final ControlLoopInstantiationProvider provider; /** - * create Instantiation Controller. + * Create Instantiation Controller. + * + * @param provider the ControlLoopInstantiationProvider */ - public InstantiationController() { - this.provider = InstantiationHandler.getInstance().getControlLoopInstantiationProvider(); + public InstantiationController(ControlLoopInstantiationProvider provider) { + this.provider = provider; } /** @@ -76,8 +79,9 @@ public class InstantiationController extends RestController { * @return a response */ // @formatter:off - @POST - @Path("/instantiation") + @PostMapping(value = "/instantiation", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}, + consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation( value = "Commissions control loop definitions", notes = "Commissions control loop definitions, returning the control loop IDs", @@ -121,18 +125,18 @@ public class InstantiationController extends RestController { } ) // @formatter:on - public Response create( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Entity Body of Control Loop", required = true) ControlLoops controlLoops) { + public ResponseEntity<InstantiationResponse> create( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Entity Body of Control Loop", required = true) + @RequestBody ControlLoops controlLoops) { try { - InstantiationResponse response = provider.createControlLoops(controlLoops); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); + return ResponseEntity.ok().body(provider.createControlLoops(controlLoops)); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("creation of control loop failed", e); - return createInstantiationErrorResponse(e, requestId); + return createInstantiationErrorResponse(e); } } @@ -145,8 +149,8 @@ public class InstantiationController extends RestController { * @return the control loops */ // @formatter:off - @GET - @Path("/instantiation") + @GetMapping(value = "/instantiation", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of the requested control loops", notes = "Queries details of the requested control loops, returning all control loop details", response = ControlLoops.class, @@ -183,20 +187,20 @@ public class InstantiationController extends RestController { } ) // @formatter:on - public Response query( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop definition name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Control Loop definition version", - required = true) @QueryParam("version") String version) { + public ResponseEntity<?> query( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = false) + @RequestParam(value = "name", required = false) String name, + @ApiParam(value = "Control Loop definition version", required = false) + @RequestParam(value = "version", required = false) String version) { try { - var response = provider.getControlLoops(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); + return ResponseEntity.ok().body(provider.getControlLoops(name, version)); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("commisssioning of control loop failed", e); - return createInstantiationErrorResponse(e, requestId); + return createInstantiationErrorResponse(e); } } @@ -209,8 +213,9 @@ public class InstantiationController extends RestController { * @return a response */ // @formatter:off - @PUT - @Path("/instantiation") + @PutMapping(value = "/instantiation", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}, + consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation( value = "Updates control loop definitions", notes = "Updates control loop definitions, returning the updated control loop definition IDs", @@ -256,18 +261,18 @@ public class InstantiationController extends RestController { } ) // @formatter:on - public Response update( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Entity Body of Control Loop", required = true) ControlLoops controlLoops) { + public ResponseEntity<InstantiationResponse> update( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Entity Body of Control Loop", required = true) + @RequestBody ControlLoops controlLoops) { try { - InstantiationResponse response = provider.updateControlLoops(controlLoops); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); + return ResponseEntity.ok().body(provider.updateControlLoops(controlLoops)); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("update of control loops failed", e); - return createInstantiationErrorResponse(e, requestId); + return createInstantiationErrorResponse(e); } } @@ -280,8 +285,8 @@ public class InstantiationController extends RestController { * @return a response */ // @formatter:off - @DELETE - @Path("/instantiation") + @DeleteMapping(value = "/instantiation", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Delete a control loop", notes = "Deletes a control loop, returning optional error details", response = InstantiationResponse.class, @@ -326,20 +331,20 @@ public class InstantiationController extends RestController { ) // @formatter:on - public Response delete( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop definition name", required = true) @QueryParam("name") String name, - @ApiParam(value = "Control Loop definition version", required = true) - @QueryParam("version") String version) { + public ResponseEntity<InstantiationResponse> delete( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop definition name", required = true) + @RequestParam("name") String name, + @ApiParam(value = "Control Loop definition version") + @RequestParam(value = "version", required = false) String version) { try { - InstantiationResponse response = provider.deleteControlLoop(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.OK)), requestId).entity(response) - .build(); + return ResponseEntity.ok().body(provider.deleteControlLoop(name, version)); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("delete of control loop failed", e); - return createInstantiationErrorResponse(e, requestId); + return createInstantiationErrorResponse(e); } } @@ -351,8 +356,9 @@ public class InstantiationController extends RestController { * @return the control loop definitions */ // @formatter:off - @PUT - @Path("/instantiation/command") + @PutMapping(value = "/instantiation/command", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}, + consumes = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Issue a command to the requested control loops", notes = "Issues a command to a control loop, ordering a state change on the control loop", response = InstantiationResponse.class, @@ -389,32 +395,30 @@ public class InstantiationController extends RestController { } ) // @formatter:on - public Response issueControlLoopCommand( - @HeaderParam(REQUEST_ID_NAME) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Entity Body of control loop command", required = true) InstantiationCommand command) { + public ResponseEntity<InstantiationResponse> issueControlLoopCommand( + @RequestHeader(name = REQUEST_ID_NAME, required = false) + @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Entity Body of control loop command", required = true) + @RequestBody InstantiationCommand command) { try { - InstantiationResponse response = provider.issueControlLoopCommand(command); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Status.ACCEPTED)), requestId) - .entity(response).build(); + return ResponseEntity.accepted().body(provider.issueControlLoopCommand(command)); } catch (PfModelRuntimeException | PfModelException | ControlLoopException e) { LOGGER.warn("creation of control loop failed", e); - return createInstantiationErrorResponse(e, requestId); + return createInstantiationErrorResponse(e); } } /** * create a Instantiation Response from an exception. + * * @param e the error - * @param requestId request ID used in ONAP logging * @return the Instantiation Response */ - private Response createInstantiationErrorResponse(ErrorResponseInfo e, UUID requestId) { + private ResponseEntity<InstantiationResponse> createInstantiationErrorResponse(ErrorResponseInfo e) { var resp = new InstantiationResponse(); resp.setErrorDetails(e.getErrorResponse().getErrorMessage()); - return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), - requestId).entity(resp).build(); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).body(resp); } } - diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/MonitoringQueryController.java index 7fde5fba3..86531597a 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryController.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/MonitoringQueryController.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.controlloop.runtime.monitoring.rest; +package org.onap.policy.clamp.controlloop.runtime.main.rest; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -30,38 +30,39 @@ import io.swagger.annotations.ExtensionProperty; import io.swagger.annotations.ResponseHeader; import java.time.Instant; import java.util.UUID; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; -import javax.ws.rs.Path; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Response; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList; import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatisticsList; -import org.onap.policy.clamp.controlloop.runtime.main.rest.RestController; -import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringHandler; +import org.onap.policy.clamp.controlloop.runtime.main.web.AbstractRestController; import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; /** * This class handles REST endpoints for CL Statistics monitoring. */ -public class MonitoringQueryController extends RestController { +@RestController +public class MonitoringQueryController extends AbstractRestController { private static final Logger LOGGER = LoggerFactory.getLogger(MonitoringQueryController.class); private final MonitoringProvider provider; /** * Create Monitoring Controller. + * + * @param provider the MonitoringProvider */ - public MonitoringQueryController() { - this.provider = MonitoringHandler.getInstance().getMonitoringProvider(); + public MonitoringQueryController(MonitoringProvider provider) { + this.provider = provider; } - /** * Queries details of control loop participants statistics. * @@ -74,8 +75,8 @@ public class MonitoringQueryController extends RestController { * @return the participant statistics */ // @formatter:off - @GET - @Path("/monitoring/participant") + @GetMapping(value = "/monitoring/participant", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of the requested participant stats", notes = "Queries details of the requested participant stats, returning all participant stats", response = ParticipantStatisticsList.class, @@ -112,18 +113,26 @@ public class MonitoringQueryController extends RestController { } ) // @formatter:on - public Response queryParticipantStatistics(@HeaderParam(REQUEST_ID_NAME) - @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop participant name", required = true) - @QueryParam("name") final String name, - @ApiParam(value = "Control Loop participant version", required = true) - @QueryParam("version") final String version, - @ApiParam(value = "Record count", required = false) @DefaultValue("0") - @QueryParam("recordCount") final int recordCount, - @ApiParam(value = "start time", required = false) - @QueryParam("startTime") final String startTime, - @ApiParam(value = "end time", required = false) - @QueryParam("endTime") final String endTime) { + public ResponseEntity<ParticipantStatisticsList> queryParticipantStatistics( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop participant name") @RequestParam( + value = "name", + required = false) final String name, + @ApiParam(value = "Control Loop participant version", required = false) @RequestParam( + value = "version", + required = false) final String version, + @ApiParam(value = "Record count", required = false) @RequestParam( + value = "recordCount", + required = false, + defaultValue = "0") final int recordCount, + @ApiParam(value = "start time", required = false) @RequestParam( + value = "startTime", + required = false) final String startTime, + @ApiParam(value = "end time", required = false) @RequestParam( + value = "endTime", + required = false) final String endTime) { try { Instant startTimestamp = null; @@ -135,16 +144,12 @@ public class MonitoringQueryController extends RestController { if (endTime != null) { endTimestamp = Instant.parse(endTime); } - ParticipantStatisticsList response = provider.fetchFilteredParticipantStatistics(name, version, recordCount, - startTimestamp, endTimestamp); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) - .entity(response) - .build(); + return ResponseEntity.ok().body(provider.fetchFilteredParticipantStatistics(name, version, recordCount, + startTimestamp, endTimestamp)); } catch (PfModelRuntimeException e) { LOGGER.warn("Monitoring of participants statistics failed", e); - return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), - requestId).build(); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).build(); } } @@ -158,8 +163,8 @@ public class MonitoringQueryController extends RestController { * @return the control loop element statistics */ // @formatter:off - @GET - @Path("/monitoring/participants/controlloop") + @GetMapping(value = "/monitoring/participants/controlloop", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of all the participant stats in a control loop", notes = "Queries details of the participant stats, returning all participant stats", response = ClElementStatisticsList.class, @@ -195,29 +200,27 @@ public class MonitoringQueryController extends RestController { } ) // @formatter:on - public Response queryParticipantStatisticsPerControlLoop(@HeaderParam(REQUEST_ID_NAME) - @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop name", required = true) - @QueryParam("name") final String name, - @ApiParam(value = "Control Loop version", required = true) - @QueryParam("version") final String version) { + public ResponseEntity<ParticipantStatisticsList> queryParticipantStatisticsPerControlLoop( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop name", required = true) @RequestParam( + value = "name", + required = false) final String name, + @ApiParam(value = "Control Loop version", required = true) @RequestParam( + value = "version", + required = false) final String version) { try { - ParticipantStatisticsList response = provider.fetchParticipantStatsPerControlLoop(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) - .entity(response) - .build(); + return ResponseEntity.ok().body(provider.fetchParticipantStatsPerControlLoop(name, version)); } catch (PfModelRuntimeException e) { LOGGER.warn("Monitoring of Cl participant statistics failed", e); - return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), - requestId).build(); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).build(); } } - - /** * Queries details of all control loop element statistics per control loop. * @@ -227,8 +230,8 @@ public class MonitoringQueryController extends RestController { * @return the control loop element statistics */ // @formatter:off - @GET - @Path("/monitoring/clelements/controlloop") + @GetMapping(value = "/monitoring/clelements/controlloop", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of the requested cl element stats in a control loop", notes = "Queries details of the requested cl element stats, returning all clElement stats", response = ClElementStatisticsList.class, @@ -264,30 +267,27 @@ public class MonitoringQueryController extends RestController { } ) // @formatter:on - public Response queryElementStatisticsPerControlLoop(@HeaderParam(REQUEST_ID_NAME) - @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Control Loop name", required = true) - @QueryParam("name") final String name, - @ApiParam(value = "Control Loop version", required = true) - @QueryParam("version") final String version) { + public ResponseEntity<ClElementStatisticsList> queryElementStatisticsPerControlLoop( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Control Loop name", required = true) @RequestParam( + value = "name", + required = false) final String name, + @ApiParam(value = "Control Loop version", required = true) @RequestParam( + value = "version", + required = false) final String version) { try { - ClElementStatisticsList response = provider.fetchClElementStatsPerControlLoop(name, version); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) - .entity(response) - .build(); + return ResponseEntity.ok().body(provider.fetchClElementStatsPerControlLoop(name, version)); } catch (PfModelRuntimeException e) { LOGGER.warn("Monitoring of Cl Element statistics failed", e); - return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), - requestId).build(); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).build(); } } - - - /** * Queries details of all control loop element statistics per control loop. * @@ -301,8 +301,8 @@ public class MonitoringQueryController extends RestController { * @return the control loop element statistics */ // @formatter:off - @GET - @Path("/monitoring/clelement") + @GetMapping(value = "/monitoring/clelement", + produces = {MediaType.APPLICATION_JSON_VALUE, APPLICATION_YAML}) @ApiOperation(value = "Query details of the requested cl element stats", notes = "Queries details of the requested cl element stats, returning all clElement stats", response = ClElementStatisticsList.class, @@ -338,20 +338,29 @@ public class MonitoringQueryController extends RestController { } ) // @formatter:on - public Response queryElementStatistics(@HeaderParam(REQUEST_ID_NAME) - @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, - @ApiParam(value = "Participant name", required = true) - @QueryParam("name") final String name, - @ApiParam(value = "Participant version", required = true) - @QueryParam("version") final String version, - @ApiParam(value = "Record count", required = false) - @DefaultValue("0") @QueryParam("recordCount") final int recordCount, - @ApiParam(value = "Control Loop element id", required = false) - @QueryParam("id") final String id, - @ApiParam(value = "start time", required = false) - @QueryParam("startTime") final String startTime, - @ApiParam(value = "end time", required = false) - @QueryParam("endTime") final String endTime) { + public ResponseEntity<ClElementStatisticsList> queryElementStatistics( + @RequestHeader( + name = REQUEST_ID_NAME, + required = false) @ApiParam(REQUEST_ID_PARAM_DESCRIPTION) UUID requestId, + @ApiParam(value = "Participant name", required = true) @RequestParam( + value = "name", + required = false) final String name, + @ApiParam(value = "Participant version", required = true) @RequestParam( + value = "version", + required = false) final String version, + @ApiParam(value = "Record count", required = false) @RequestParam( + value = "recordCount", + required = false, + defaultValue = "0") final int recordCount, + @ApiParam(value = "Control Loop element id", required = false) @RequestParam( + value = "id", + required = false) final String id, + @ApiParam(value = "start time", required = false) @RequestParam( + value = "startTime", + required = false) final String startTime, + @ApiParam(value = "end time", required = false) @RequestParam( + value = "endTime", + required = false) final String endTime) { try { Instant startTimestamp = null; @@ -363,16 +372,12 @@ public class MonitoringQueryController extends RestController { if (endTime != null) { endTimestamp = Instant.parse(endTime); } - ClElementStatisticsList response = provider.fetchFilteredClElementStatistics(name, version, id, - startTimestamp, endTimestamp, recordCount); - return addLoggingHeaders(addVersionControlHeaders(Response.status(Response.Status.OK)), requestId) - .entity(response) - .build(); + return ResponseEntity.ok().body(provider.fetchFilteredClElementStatistics(name, version, id, startTimestamp, + endTimestamp, recordCount)); } catch (PfModelRuntimeException | PfModelException e) { LOGGER.warn("Monitoring of Cl Element statistics failed", e); - return addLoggingHeaders(addVersionControlHeaders(Response.status(e.getErrorResponse().getResponseCode())), - requestId).build(); + return ResponseEntity.status(e.getErrorResponse().getResponseCode().getStatusCode()).build(); } } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java index 957f53600..323f76178 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java @@ -20,36 +20,30 @@ package org.onap.policy.clamp.controlloop.runtime.main.startstop; -import java.util.HashSet; +import java.io.Closeable; +import java.io.IOException; import java.util.List; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; import javax.ws.rs.core.Response.Status; +import lombok.Getter; import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningHandler; -import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationHandler; import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; -import org.onap.policy.clamp.controlloop.runtime.main.rest.ControlLoopAafFilter; -import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringHandler; import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; import org.onap.policy.common.endpoints.event.comm.TopicSink; import org.onap.policy.common.endpoints.event.comm.TopicSource; -import org.onap.policy.common.endpoints.http.server.RestServer; import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; -import org.onap.policy.common.parameters.ParameterService; import org.onap.policy.common.utils.services.ServiceManagerContainer; /** * This class activates the control loop runtime component as a complete service together with all its controllers, * listeners & handlers. */ -public class ClRuntimeActivator extends ServiceManagerContainer { +public class ClRuntimeActivator extends ServiceManagerContainer implements Closeable { // Name of the message type for messages on topics private static final String[] MSG_TYPE_NAMES = {"messageType"}; - private final ClRuntimeParameterGroup clRuntimeParameterGroup; + @Getter + private final ClRuntimeParameterGroup parameterGroup; // Topics from which the application receives and to which the application sends messages private List<TopicSink> topicSinks; @@ -64,15 +58,12 @@ public class ClRuntimeActivator extends ServiceManagerContainer { * Instantiate the activator for the control loop runtime as a complete service. * * @param clRuntimeParameterGroup the parameters for the control loop runtime service + * @param supervisionHandler SupervisionHandler * @throws ControlLoopRuntimeException if the activator does not start */ - public ClRuntimeActivator(final ClRuntimeParameterGroup clRuntimeParameterGroup) { - - if (clRuntimeParameterGroup == null || !clRuntimeParameterGroup.isValid()) { - throw new ControlLoopRuntimeException(Status.INTERNAL_SERVER_ERROR, "ParameterGroup not valid"); - } - - this.clRuntimeParameterGroup = clRuntimeParameterGroup; + public ClRuntimeActivator(final ClRuntimeParameterGroup clRuntimeParameterGroup, + SupervisionHandler supervisionHandler) { + this.parameterGroup = clRuntimeParameterGroup; topicSinks = TopicEndpointManager.getManager() .addTopicSinks(clRuntimeParameterGroup.getTopicParameterGroup().getTopicSinks()); @@ -87,77 +78,22 @@ public class ClRuntimeActivator extends ServiceManagerContainer { "topic message dispatcher failed to start", e); } - final AtomicReference<ControlLoopHandler> commissioningHandler = new AtomicReference<>(); - final AtomicReference<ControlLoopHandler> instantiationHandler = new AtomicReference<>(); - final AtomicReference<ControlLoopHandler> supervisionHandler = new AtomicReference<>(); - final AtomicReference<ControlLoopHandler> monitoringHandler = new AtomicReference<>(); - final AtomicReference<RestServer> restServer = new AtomicReference<>(); - // @formatter:off - addAction("Control loop runtime parameters", - () -> ParameterService.register(clRuntimeParameterGroup), - () -> ParameterService.deregister(clRuntimeParameterGroup.getName())); - addAction("Topic endpoint management", () -> TopicEndpointManager.getManager().start(), () -> TopicEndpointManager.getManager().shutdown()); - addAction("Commissioning Handler", - () -> commissioningHandler.set(new CommissioningHandler(clRuntimeParameterGroup)), - () -> commissioningHandler.get().close()); - - addAction("Instantiation Handler", - () -> instantiationHandler.set(new InstantiationHandler(clRuntimeParameterGroup)), - () -> instantiationHandler.get().close()); - - addAction("Supervision Handler", - () -> supervisionHandler.set(new SupervisionHandler(clRuntimeParameterGroup)), - () -> supervisionHandler.get().close()); - - addAction("Monitoring Handler", - () -> monitoringHandler.set(new MonitoringHandler(clRuntimeParameterGroup)), - () -> monitoringHandler.get().close()); - - addHandlerActions("Commissioning", commissioningHandler); - addHandlerActions("Instantiation", instantiationHandler); - addHandlerActions("Supervision", supervisionHandler); - addHandlerActions("Monitoring", monitoringHandler); + addAction("Supervision Providers", () -> supervisionHandler.startProviders(), + () -> supervisionHandler.stopProviders()); + addAction("Supervision Listeners", () -> supervisionHandler.startAndRegisterListeners(msgDispatcher), + () -> supervisionHandler.stopAndUnregisterListeners(msgDispatcher)); + addAction("Supervision Publishers", () -> supervisionHandler.startAndRegisterPublishers(topicSinks), + () -> supervisionHandler.stopAndUnregisterPublishers()); addAction("Topic Message Dispatcher", this::registerMsgDispatcher, this::unregisterMsgDispatcher); - - clRuntimeParameterGroup.getRestServerParameters().setName(clRuntimeParameterGroup.getName()); - - addAction("REST server", - () -> { - Set<Class<?>> providerClasses = new HashSet<>(); - providerClasses.addAll(commissioningHandler.get().getProviderClasses()); - providerClasses.addAll(instantiationHandler.get().getProviderClasses()); - providerClasses.addAll(supervisionHandler.get().getProviderClasses()); - providerClasses.addAll(monitoringHandler.get().getProviderClasses()); - - var server = new RestServer(clRuntimeParameterGroup.getRestServerParameters(), - ControlLoopAafFilter.class, - providerClasses.toArray(new Class<?>[providerClasses.size()])); - - restServer.set(server); - restServer.get().start(); - }, - () -> restServer.get().stop()); // @formatter:on } - private void addHandlerActions(final String name, final AtomicReference<ControlLoopHandler> handler) { - addAction(name + " Providers", - () -> handler.get().startProviders(), - () -> handler.get().stopProviders()); - addAction(name + " Listeners", - () -> handler.get().startAndRegisterListeners(msgDispatcher), - () -> handler.get().stopAndUnregisterListeners(msgDispatcher)); - addAction(name + " Publishers", - () -> handler.get().startAndRegisterPublishers(topicSinks), - () -> handler.get().stopAndUnregisterPublishers()); - } - /** * Registers the dispatcher with the topic source(s). */ @@ -176,12 +112,10 @@ public class ClRuntimeActivator extends ServiceManagerContainer { } } - /** - * Get the parameters used by the activator. - * - * @return the parameters of the activator - */ - public ClRuntimeParameterGroup getParameterGroup() { - return clRuntimeParameterGroup; + @Override + public void close() throws IOException { + if (isAlive()) { + stop(); + } } } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeCommandLineArguments.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeCommandLineArguments.java deleted file mode 100644 index 54167e8a6..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeCommandLineArguments.java +++ /dev/null @@ -1,132 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * 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 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.runtime.main.startstop; - -import java.util.Arrays; -import javax.ws.rs.core.Response; -import lombok.Getter; -import lombok.Setter; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.common.startstop.CommonCommandLineArguments; -import org.onap.policy.common.utils.resources.ResourceUtils; - -/** - * This class reads and handles command line parameters for the control loop runtime service. - */ -public class ClRuntimeCommandLineArguments { - private final Options options; - private final CommonCommandLineArguments commonCommandLineArguments; - - @Getter - @Setter - private String configurationFilePath = null; - - /** - * Construct the options for the control loop runtime component. - */ - public ClRuntimeCommandLineArguments() { - options = new Options(); - commonCommandLineArguments = new CommonCommandLineArguments(options); - } - - /** - * Construct the options for the CLI editor and parse in the given arguments. - * - * @param args The command line arguments - * @throws ControlLoopRuntimeException if the arguments are invalid - */ - public ClRuntimeCommandLineArguments(final String[] args) { - // Set up the options with the default constructor - this(); - - // Parse the arguments - try { - parse(args); - } catch (final ControlLoopException e) { - throw new ControlLoopRuntimeException(Response.Status.NOT_ACCEPTABLE, - "parse error on control loop runtime parameters", e); - } - } - - /** - * Parse the command line options. - * - * @param args The command line arguments - * @return a string with a message for help and version, or null if there is no message - * @throws ControlLoopException on command argument errors - */ - public String parse(final String[] args) throws ControlLoopException { - // Clear all our arguments - setConfigurationFilePath(null); - CommandLine commandLine = null; - try { - commandLine = new DefaultParser().parse(options, args); - } catch (final ParseException e) { - throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, - "invalid command line arguments specified : " + e.getMessage()); - } - - // Arguments left over after Commons CLI does its stuff - final String[] remainingArgs = commandLine.getArgs(); - - if (remainingArgs.length > 0) { - throw new ControlLoopException(Response.Status.NOT_ACCEPTABLE, - "too many command line arguments specified : " + Arrays.toString(args)); - } - - if (commandLine.hasOption('h')) { - return commonCommandLineArguments.help(Main.class.getName(), options); - } - - if (commandLine.hasOption('v')) { - return commonCommandLineArguments.version(); - } - - if (commandLine.hasOption('c')) { - setConfigurationFilePath(commandLine.getOptionValue('c')); - } - - return null; - } - - /** - * Validate the command line options. - * - * @throws ControlLoopException on command argument validation errors - */ - public void validate() throws ControlLoopException { - commonCommandLineArguments.validate(configurationFilePath); - } - - /** - * Gets the full expanded configuration file path. - * - * @return the configuration file path - */ - public String getFullConfigurationFilePath() { - return ResourceUtils.getFilePath4Resource(getConfigurationFilePath()); - } -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/Main.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/Main.java deleted file mode 100644 index de1ce6f5d..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/Main.java +++ /dev/null @@ -1,159 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * 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 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.runtime.main.startstop; - -import java.util.Arrays; -import javax.ws.rs.core.Response; -import org.onap.policy.clamp.controlloop.common.ControlLoopConstants; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; -import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; -import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; -import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterHandler; -import org.onap.policy.common.utils.resources.MessageConstants; -import org.onap.policy.common.utils.services.Registry; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * This class initiates ONAP Policy Framework Control Loop runtime component. - */ -public class Main { - - private static final Logger LOGGER = LoggerFactory.getLogger(Main.class); - - private ClRuntimeActivator activator; - private ClRuntimeParameterGroup parameterGroup; - - /** - * Instantiates the control loop runtime service. - * - * @param args the command line arguments - * @throws ControlLoopRuntimeException if the CLAMP runtime fails to start - */ - public Main(final String[] args) { - final var argumentString = Arrays.toString(args); - LOGGER.info("Starting the control loop runtime service with arguments - {}", argumentString); - - // Check the arguments - final var arguments = new ClRuntimeCommandLineArguments(); - try { - // The arguments return a string if there is a message to print and we should exit - final String argumentMessage = arguments.parse(args); - if (argumentMessage != null) { - LOGGER.info(argumentMessage); - return; - } - // Validate that the arguments are sane - arguments.validate(); - - // Read the parameters - parameterGroup = new ClRuntimeParameterHandler().getParameters(arguments); - - // Now, create the activator for the service - activator = new ClRuntimeActivator(parameterGroup); - Registry.register(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR, activator); - - // Start the activator - activator.start(); - } catch (Exception exp) { - if (null != activator) { - Registry.unregister(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR); - } - throw new ControlLoopRuntimeException(Response.Status.BAD_REQUEST, - String.format(MessageConstants.START_FAILURE_MSG, MessageConstants.POLICY_CLAMP), exp); - } - - // Add a shutdown hook to shut everything down in an orderly manner - Runtime.getRuntime().addShutdownHook(new ClRuntimeShutdownHookClass()); - var successMsg = String.format(MessageConstants.START_SUCCESS_MSG, MessageConstants.POLICY_CLAMP); - LOGGER.info(successMsg); - } - - /** - * Check if main is running. - * - * @return true if the CLAMP runtime is running - */ - public boolean isRunning() { - return activator != null && activator.isAlive(); - } - - /** - * Get the parameters specified in JSON. - * - * @return the parameters - */ - public ClRuntimeParameterGroup getParameters() { - return parameterGroup; - } - - /** - * Shut down Execution. - * - * @throws ControlLoopException on shutdown errors - */ - public void shutdown() throws ControlLoopException { - // clear the parameterGroup variable - parameterGroup = null; - - // clear the cl runtime activator - if (activator != null) { - activator.stop(); - } - } - - /** - * The Class ClRuntimeShutdownHookClass terminates the control loop runtime service when its run method is called. - */ - private class ClRuntimeShutdownHookClass extends Thread { - /* - * (non-Javadoc) - * - * @see java.lang.Runnable#run() - */ - @Override - public void run() { - if (!activator.isAlive()) { - return; - } - - try { - // Shutdown the control loop runtime service and wait for everything to stop - activator.stop(); - } catch (final RuntimeException e) { - LOGGER.warn("error occured during shut down of the control loop runtime service", e); - } - } - } - - /** - * The main method. - * - * @param args the arguments - */ - public static void main(final String[] args) { // NOSONAR - /* - * NOTE: arguments are validated by the constructor, thus sonar is disabled. - */ - - new Main(args); - } -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/AbstractRestController.java index 4955e4a2f..7d279ba67 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestController.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/AbstractRestController.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.controlloop.runtime.main.rest; +package org.onap.policy.clamp.controlloop.runtime.main.web; import io.swagger.annotations.Api; import io.swagger.annotations.BasicAuthDefinition; @@ -27,30 +27,26 @@ import io.swagger.annotations.SecurityDefinition; import io.swagger.annotations.SwaggerDefinition; import io.swagger.annotations.Tag; import java.net.HttpURLConnection; -import java.util.UUID; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response.ResponseBuilder; +import org.springframework.web.bind.annotation.RequestMapping; /** - * Common superclass to provide REST endpoints for the control loop service. + * Common superclass to provide REST endpoints for the participant simulator. */ // @formatter:off -@Path("/onap/controlloop/v2") -@Api(value = "Control Loop API") -@Produces({MediaType.APPLICATION_JSON, RestController.APPLICATION_YAML}) +@RequestMapping(value = "/v2", produces = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML}) +@Api(value = "Control Loop Commissioning API") @SwaggerDefinition( - info = @Info(description = - "Control Loop Service", version = "v1.0", - title = "Control Loop"), - consumes = {MediaType.APPLICATION_JSON, RestController.APPLICATION_YAML}, - produces = {MediaType.APPLICATION_JSON, RestController.APPLICATION_YAML}, - schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS}, - tags = {@Tag(name = "controlloop", description = "Control Loop Service")}, - securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")})) + info = @Info(description = + "Control Loop Service", version = "v1.0", + title = "Control Loop"), + consumes = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML}, + produces = {MediaType.APPLICATION_JSON, AbstractRestController.APPLICATION_YAML}, + schemes = {SwaggerDefinition.Scheme.HTTP, SwaggerDefinition.Scheme.HTTPS}, + tags = {@Tag(name = "controlloop", description = "Control Loop Service")}, + securityDefinition = @SecurityDefinition(basicAuthDefinitions = {@BasicAuthDefinition(key = "basicAuth")})) // @formatter:on -public class RestController { +public abstract class AbstractRestController { public static final String APPLICATION_YAML = "application/yaml"; public static final String EXTENSION_NAME = "interface info"; @@ -63,12 +59,12 @@ public class RestController { public static final String VERSION_MINOR_NAME = "X-MinorVersion"; public static final String VERSION_MINOR_DESCRIPTION = - "Used to request or communicate a MINOR version back from the client" - + " to the server, and from the server back to the client"; + "Used to request or communicate a MINOR version back from the client" + + " to the server, and from the server back to the client"; public static final String VERSION_PATCH_NAME = "X-PatchVersion"; public static final String VERSION_PATCH_DESCRIPTION = "Used only to communicate a PATCH version in a response for" - + " troubleshooting purposes only, and will not be provided by" + " the client on request"; + + " troubleshooting purposes only, and will not be provided by" + " the client on request"; public static final String VERSION_LATEST_NAME = "X-LatestVersion"; public static final String VERSION_LATEST_DESCRIPTION = "Used only to communicate an API's latest version"; @@ -88,29 +84,8 @@ public class RestController { public static final String SERVER_ERROR_MESSAGE = "Internal Server Error"; /** - * Adds version headers to the response. - * - * @param respBuilder response builder - * @return the response builder, with version headers + * Constructor. */ - public ResponseBuilder addVersionControlHeaders(ResponseBuilder respBuilder) { - return respBuilder.header(VERSION_MINOR_NAME, "0").header(VERSION_PATCH_NAME, "0").header(VERSION_LATEST_NAME, - API_VERSION); - } - - /** - * Adds logging headers to the response. - * - * @param respBuilder response builder - * @param requestId unique ID for this request - * @return the response builder, with version logging - */ - public ResponseBuilder addLoggingHeaders(ResponseBuilder respBuilder, UUID requestId) { - if (requestId == null) { - // Generate a random uuid if client does not embed requestId in rest request - return respBuilder.header(REQUEST_ID_NAME, UUID.randomUUID()); - } - - return respBuilder.header(REQUEST_ID_NAME, requestId); + protected AbstractRestController() { } } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/ControlLoopAafFilter.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/ControlLoopAafFilter.java index f166de5d6..739a691c9 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/rest/ControlLoopAafFilter.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/ControlLoopAafFilter.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.controlloop.runtime.main.rest; +package org.onap.policy.clamp.controlloop.runtime.main.web; import org.onap.policy.common.endpoints.http.server.aaf.AafGranularAuthFilter; import org.onap.policy.common.utils.resources.MessageConstants; diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RequestResponseLoggingFilter.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RequestResponseLoggingFilter.java new file mode 100644 index 000000000..eb08391a9 --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RequestResponseLoggingFilter.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.main.web; + +import java.io.IOException; +import java.util.UUID; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +@Component +@Order(2) +public class RequestResponseLoggingFilter implements Filter { + + private static final String VERSION_MINOR_NAME = "X-MinorVersion"; + private static final String VERSION_PATCH_NAME = "X-PatchVersion"; + private static final String VERSION_LATEST_NAME = "X-LatestVersion"; + public static final String API_VERSION = "1.0.0"; + public static final String REQUEST_ID_NAME = "X-ONAP-RequestID"; + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + + + HttpServletResponse res = (HttpServletResponse) response; + HttpServletRequest req = (HttpServletRequest) request; + + String requestId = req.getHeader(REQUEST_ID_NAME); + res.addHeader(REQUEST_ID_NAME, requestId != null ? requestId : UUID.randomUUID().toString()); + + res.addHeader(VERSION_MINOR_NAME, "0"); + res.addHeader(VERSION_PATCH_NAME, "0"); + res.addHeader(VERSION_LATEST_NAME, API_VERSION); + + chain.doFilter(request, response); + } + +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RuntimeErrorController.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RuntimeErrorController.java new file mode 100644 index 000000000..2dc7a6b8e --- /dev/null +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/web/RuntimeErrorController.java @@ -0,0 +1,102 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * 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 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.main.web; + +import io.swagger.v3.oas.annotations.Hidden; +import java.util.Map; +import javax.servlet.RequestDispatcher; +import javax.servlet.http.HttpServletRequest; +import org.onap.policy.clamp.controlloop.models.messages.rest.SimpleResponse; +import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.error.ErrorAttributeOptions; +import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.context.request.ServletWebRequest; + +@Controller +@Hidden +public class RuntimeErrorController implements ErrorController { + + private static final Logger LOGGER = LoggerFactory.getLogger(RuntimeErrorController.class); + + private final ErrorAttributes errorAttributes; + + @Value("${server.error.path}") + private String path; + + /** + * Constructor. + * + * @param errorAttributes ErrorAttributes + */ + public RuntimeErrorController(ErrorAttributes errorAttributes) { + this.errorAttributes = errorAttributes; + } + + protected HttpStatus getStatus(HttpServletRequest request) { + Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); + if (statusCode == null) { + return HttpStatus.INTERNAL_SERVER_ERROR; + } + try { + return HttpStatus.valueOf(statusCode); + } catch (Exception ex) { + LOGGER.error("statusCode {} Not Valid", statusCode, ex); + return HttpStatus.INTERNAL_SERVER_ERROR; + } + } + + /** + * Handle Errors not handled to GlobalControllerExceptionHandler. + * + * @param request HttpServletRequest + * @return ResponseEntity + */ + @RequestMapping(value = "${server.error.path}", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity<TypedSimpleResponse<SimpleResponse>> handleError(HttpServletRequest request) { + Map<String, Object> map = this.errorAttributes.getErrorAttributes(new ServletWebRequest(request), + ErrorAttributeOptions.defaults()); + + StringBuilder sb = new StringBuilder(); + final Object error = map.get("error"); + if (error != null) { + sb.append(error.toString()).append(" "); + } + final Object message = map.get("message"); + if (message != null) { + sb.append(message.toString()); + } + + TypedSimpleResponse<SimpleResponse> resp = new TypedSimpleResponse<>(); + resp.setErrorDetails(sb.toString()); + + return ResponseEntity.status(getStatus(request)).body(resp); + + } +} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java deleted file mode 100644 index 1584766f1..000000000 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021 Nordix Foundation. - * ================================================================================ - * 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 - * ============LICENSE_END========================================================= - */ - -package org.onap.policy.clamp.controlloop.runtime.monitoring; - -import java.io.IOException; -import java.util.Set; -import javax.ws.rs.core.Response; -import lombok.Getter; -import org.onap.policy.clamp.controlloop.common.handler.ControlLoopHandler; -import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; -import org.onap.policy.clamp.controlloop.runtime.monitoring.rest.MonitoringQueryController; -import org.onap.policy.common.utils.services.Registry; -import org.onap.policy.models.base.PfModelRuntimeException; - -/** - * This class handles monitoring of control loop definitions, - * so only one object of this type should be built at a time. - * - * <p/> - * It is effectively a singleton that is started at system start. - */ -public class MonitoringHandler extends ControlLoopHandler { - - @Getter - private MonitoringProvider monitoringProvider; - - /** - * Gets the Monitoring Handler. - * - * @return MonitoringHandler - */ - public static MonitoringHandler getInstance() { - return Registry.get(MonitoringHandler.class.getName()); - } - - /** - * Create a handler. - * - * @param controlLoopParameters the parameters for access to the database - */ - public MonitoringHandler(ClRuntimeParameterGroup controlLoopParameters) { - super(controlLoopParameters.getDatabaseProviderParameters()); - } - - @Override - public Set<Class<?>> getProviderClasses() { - return Set.of(MonitoringQueryController.class); - } - - @Override - public void startProviders() { - monitoringProvider = new MonitoringProvider(getDatabaseProviderParameters()); - } - - @Override - public void stopProviders() { - try { - monitoringProvider.close(); - } catch (IOException e) { - throw new PfModelRuntimeException(Response.Status.INTERNAL_SERVER_ERROR, "Cannot stop provider", e); - } - } -} diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java index 1bc1312e7..a68505877 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java @@ -36,14 +36,16 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.base.PfModelRuntimeException; -import org.onap.policy.models.provider.PolicyModelsProviderParameters; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.springframework.stereotype.Component; /** * This class provides information about statistics data of CL elements and CL Participants in database to callers. */ +@Component public class MonitoringProvider implements Closeable { private static final String DESC_ORDER = "DESC"; @@ -54,15 +56,17 @@ public class MonitoringProvider implements Closeable { /** * Create a Monitoring provider. * - * @param parameters parameters for accessing the database for monitoring + * @param controlLoopParameters the parameters for access to the database * @throws PfModelRuntimeException on errors creating the provider */ - public MonitoringProvider(PolicyModelsProviderParameters parameters) { + public MonitoringProvider(ClRuntimeParameterGroup controlLoopParameters) { try { - participantStatisticsProvider = new ParticipantStatisticsProvider(parameters); - clElementStatisticsProvider = new ClElementStatisticsProvider(parameters); - controlLoopProvider = new ControlLoopProvider(parameters); + participantStatisticsProvider = + new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters()); + clElementStatisticsProvider = + new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters()); + controlLoopProvider = new ControlLoopProvider(controlLoopParameters.getDatabaseProviderParameters()); } catch (PfModelException e) { throw new PfModelRuntimeException(e); } @@ -83,10 +87,10 @@ public class MonitoringProvider implements Closeable { * @throws PfModelException on creation errors */ public ParticipantStatisticsList createParticipantStatistics(List<ParticipantStatistics> participantStatistics) - throws PfModelException { + throws PfModelException { var participantStatisticsList = new ParticipantStatisticsList(); participantStatisticsList - .setStatisticsList(participantStatisticsProvider.createParticipantStatistics(participantStatistics)); + .setStatisticsList(participantStatisticsProvider.createParticipantStatistics(participantStatistics)); return participantStatisticsList; } @@ -99,10 +103,10 @@ public class MonitoringProvider implements Closeable { * @throws PfModelException on creation errors */ public ClElementStatisticsList createClElementStatistics(List<ClElementStatistics> clElementStatisticsList) - throws PfModelException { + throws PfModelException { var elementStatisticsList = new ClElementStatisticsList(); elementStatisticsList - .setClElementStatistics(clElementStatisticsProvider.createClElementStatistics(clElementStatisticsList)); + .setClElementStatistics(clElementStatisticsProvider.createClElementStatistics(clElementStatisticsList)); return elementStatisticsList; } @@ -118,13 +122,13 @@ public class MonitoringProvider implements Closeable { * @return the participant found */ public ParticipantStatisticsList fetchFilteredParticipantStatistics(@NonNull final String name, - final String version, int recordCount, Instant startTime, Instant endTime) { + final String version, int recordCount, Instant startTime, Instant endTime) { var participantStatisticsList = new ParticipantStatisticsList(); // Additional parameters can be added in filterMap for filtering data. Map<String, Object> filterMap = null; participantStatisticsList.setStatisticsList(participantStatisticsProvider.getFilteredParticipantStatistics(name, - version, startTime, endTime, filterMap, DESC_ORDER, recordCount)); + version, startTime, endTime, filterMap, DESC_ORDER, recordCount)); return participantStatisticsList; } @@ -138,16 +142,16 @@ public class MonitoringProvider implements Closeable { * @throws PfModelRuntimeException on errors getting participant statistics */ public ParticipantStatisticsList fetchParticipantStatsPerControlLoop(@NonNull final String controlLoopName, - @NonNull final String controlLoopVersion) { + @NonNull final String controlLoopVersion) { var statisticsList = new ParticipantStatisticsList(); List<ParticipantStatistics> participantStatistics = new ArrayList<>(); try { // Fetch all participantIds for a specific control loop List<ToscaConceptIdentifier> participantIds = - getAllParticipantIdsPerControlLoop(controlLoopName, controlLoopVersion); + getAllParticipantIdsPerControlLoop(controlLoopName, controlLoopVersion); for (ToscaConceptIdentifier id : participantIds) { - participantStatistics.addAll(participantStatisticsProvider - .getFilteredParticipantStatistics(id.getName(), id.getVersion(), null, null, null, DESC_ORDER, 0)); + participantStatistics.addAll(participantStatisticsProvider.getFilteredParticipantStatistics( + id.getName(), id.getVersion(), null, null, null, DESC_ORDER, 0)); } statisticsList.setStatisticsList(participantStatistics); } catch (PfModelException e) { @@ -169,7 +173,7 @@ public class MonitoringProvider implements Closeable { * @throws PfModelException on errors getting control loop statistics */ public ClElementStatisticsList fetchFilteredClElementStatistics(@NonNull final String name, final String version, - final String id, Instant startTime, Instant endTime, int recordCount) throws PfModelException { + final String id, Instant startTime, Instant endTime, int recordCount) throws PfModelException { var clElementStatisticsList = new ClElementStatisticsList(); Map<String, Object> filterMap = new HashMap<>(); // Adding UUID in filter if present @@ -177,7 +181,7 @@ public class MonitoringProvider implements Closeable { filterMap.put("localName", id); } clElementStatisticsList.setClElementStatistics(clElementStatisticsProvider.getFilteredClElementStatistics(name, - version, startTime, endTime, filterMap, DESC_ORDER, recordCount)); + version, startTime, endTime, filterMap, DESC_ORDER, recordCount)); return clElementStatisticsList; } @@ -191,7 +195,7 @@ public class MonitoringProvider implements Closeable { * @throws PfModelRuntimeException on errors getting control loop statistics */ public ClElementStatisticsList fetchClElementStatsPerControlLoop(@NonNull final String name, - @NonNull final String version) { + @NonNull final String version) { var clElementStatisticsList = new ClElementStatisticsList(); List<ClElementStatistics> clElementStats = new ArrayList<>(); try { @@ -203,8 +207,8 @@ public class MonitoringProvider implements Closeable { // Collect control loop element statistics for each cl element. for (ControlLoopElement clElement : clElements) { clElementStats.addAll(fetchFilteredClElementStatistics(clElement.getParticipantId().getName(), - clElement.getParticipantId().getVersion(), clElement.getId().toString(), null, null, 0) - .getClElementStatistics()); + clElement.getParticipantId().getVersion(), clElement.getId().toString(), null, null, 0) + .getClElementStatistics()); } } clElementStatisticsList.setClElementStatistics(clElementStats); @@ -224,7 +228,7 @@ public class MonitoringProvider implements Closeable { * @throws PfModelException on errors */ public List<ToscaConceptIdentifier> getAllParticipantIdsPerControlLoop(String name, String version) - throws PfModelException { + throws PfModelException { List<ToscaConceptIdentifier> participantIds = new ArrayList<>(); var controlLoop = controlLoopProvider.getControlLoop(new ToscaConceptIdentifier(name, version)); if (controlLoop != null) { @@ -245,7 +249,7 @@ public class MonitoringProvider implements Closeable { * @throws PfModelException on errors */ public Map<String, ToscaConceptIdentifier> getAllClElementsIdPerControlLoop(String name, String version) - throws PfModelException { + throws PfModelException { Map<String, ToscaConceptIdentifier> clElementId = new HashMap<>(); var controlLoop = controlLoopProvider.getControlLoop(new ToscaConceptIdentifier(name, version)); if (controlLoop != null) { diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java index 511185da1..e1b4be48b 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java @@ -38,9 +38,8 @@ import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.Parti import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopUpdate; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType; import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus; -import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningHandler; +import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider; import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; -import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringHandler; import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider; import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantControlLoopStateChangePublisher; import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantControlLoopUpdatePublisher; @@ -48,19 +47,20 @@ import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantSta import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantStatusListener; import org.onap.policy.common.endpoints.event.comm.TopicSink; import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher; -import org.onap.policy.common.utils.services.Registry; import org.onap.policy.common.utils.services.ServiceManager; import org.onap.policy.common.utils.services.ServiceManagerException; import org.onap.policy.models.base.PfModelException; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; /** * This class handles supervision of control loop instances, so only one object of this type should be built at a time. * * <p/> It is effectively a singleton that is started at system start. */ +@Component public class SupervisionHandler extends ControlLoopHandler { private static final Logger LOGGER = LoggerFactory.getLogger(SupervisionHandler.class); @@ -71,7 +71,8 @@ public class SupervisionHandler extends ControlLoopHandler { private ControlLoopProvider controlLoopProvider; private ParticipantProvider participantProvider; - private MonitoringProvider monitoringProvider; + private final MonitoringProvider monitoringProvider; + private final CommissioningProvider commissioningProvider; // Publishers for participant communication private ParticipantStateChangePublisher stateChangePublisher; @@ -93,21 +94,18 @@ public class SupervisionHandler extends ControlLoopHandler { private ServiceManager publisherManager; /** - * Gets the SupervisionHandler. - * - * @return SupervisionHandler - */ - public static SupervisionHandler getInstance() { - return Registry.get(SupervisionHandler.class.getName()); - } - - /** * Create a handler. * * @param clRuntimeParameterGroup the parameters for the control loop runtime + * @param monitoringProvider the MonitoringProvider + * @param commissioningProvider the CommissioningProvider */ - public SupervisionHandler(ClRuntimeParameterGroup clRuntimeParameterGroup) { + public SupervisionHandler(ClRuntimeParameterGroup clRuntimeParameterGroup, MonitoringProvider monitoringProvider, + CommissioningProvider commissioningProvider) { super(clRuntimeParameterGroup.getDatabaseProviderParameters()); + this.monitoringProvider = monitoringProvider; + this.commissioningProvider = commissioningProvider; + // @formatter:off this.manager = new ServiceManager() .addAction("ControlLoop Provider", @@ -128,7 +126,8 @@ public class SupervisionHandler extends ControlLoopHandler { /** * Supervision trigger called when a command is issued on control loops. * - * </p> Causes supervision to start or continue supervision on the control loops in question. + * <p/> + * Causes supervision to start or continue supervision on the control loops in question. * * @param controlLoopIdentifierList the control loops for which the supervision command has been issued * @throws ControlLoopException on supervision triggering exceptions @@ -158,7 +157,7 @@ public class SupervisionHandler extends ControlLoopHandler { @Override public void startAndRegisterListeners(MessageTypeDispatcher msgDispatcher) { - msgDispatcher.register(ParticipantMessageType.PARTICIPANT_STATUS.name(), new ParticipantStatusListener()); + msgDispatcher.register(ParticipantMessageType.PARTICIPANT_STATUS.name(), new ParticipantStatusListener(this)); } @Override @@ -250,7 +249,7 @@ public class SupervisionHandler extends ControlLoopHandler { default: exceptionOccured(Response.Status.NOT_ACCEPTABLE, - "A control loop cannot be commanded to go into state " + controlLoop.getOrderedState().name()); + "A control loop cannot be commanded to go into state " + controlLoop.getOrderedState().name()); } } @@ -346,7 +345,6 @@ public class SupervisionHandler extends ControlLoopHandler { pclu.setControlLoop(controlLoop); // TODO: We should look up the correct TOSCA node template here for the control loop // Tiny hack implemented to return the tosca service template entry from the database and be passed onto dmaap - var commissioningProvider = CommissioningHandler.getInstance().getProvider(); pclu.setControlLoopDefinition(commissioningProvider.getToscaServiceTemplate(null, null)); controlLoopUpdatePublisher.send(pclu); } @@ -388,7 +386,6 @@ public class SupervisionHandler extends ControlLoopHandler { participantProvider.updateParticipants(participantList); } - monitoringProvider = MonitoringHandler.getInstance().getMonitoringProvider(); monitoringProvider.createParticipantStatistics(List.of(participantStatusMessage.getParticipantStatistics())); } @@ -401,14 +398,14 @@ public class SupervisionHandler extends ControlLoopHandler { for (ControlLoop controlLoop : participantStatusMessage.getControlLoops().getControlLoopList()) { if (controlLoop == null) { exceptionOccured(Response.Status.NOT_FOUND, - "PARTICIPANT_STATUS message references unknown control loop: " + controlLoop); + "PARTICIPANT_STATUS message references unknown control loop: " + controlLoop); } var dbControlLoop = controlLoopProvider .getControlLoop(new ToscaConceptIdentifier(controlLoop.getName(), controlLoop.getVersion())); if (dbControlLoop == null) { exceptionOccured(Response.Status.NOT_FOUND, - "PARTICIPANT_STATUS control loop not found in database: " + controlLoop); + "PARTICIPANT_STATUS control loop not found in database: " + controlLoop); } for (ControlLoopElement element : controlLoop.getElements().values()) { @@ -425,7 +422,6 @@ public class SupervisionHandler extends ControlLoopHandler { controlLoopProvider.updateControlLoop(dbControlLoop); } - monitoringProvider = MonitoringHandler.getInstance().getMonitoringProvider(); for (ControlLoop controlLoop : participantStatusMessage.getControlLoops().getControlLoopList()) { monitoringProvider.createClElementStatistics(controlLoop.getControlLoopElementStatisticsList(controlLoop)); } diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantStatusListener.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantStatusListener.java index a05f4aa20..88b838613 100644 --- a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantStatusListener.java +++ b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantStatusListener.java @@ -25,7 +25,6 @@ import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; import org.onap.policy.common.endpoints.listeners.ScoListener; import org.onap.policy.common.utils.coder.StandardCoderObject; -import org.onap.policy.common.utils.services.Registry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,13 +34,14 @@ import org.slf4j.LoggerFactory; public class ParticipantStatusListener extends ScoListener<ParticipantStatus> { private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantStatusListener.class); - private final SupervisionHandler supervisionHandler = Registry.get(SupervisionHandler.class.getName()); + private final SupervisionHandler supervisionHandler; /** * Constructs the object. */ - public ParticipantStatusListener() { + public ParticipantStatusListener(SupervisionHandler supervisionHandler) { super(ParticipantStatus.class); + this.supervisionHandler = supervisionHandler; } @Override diff --git a/runtime-controlloop/src/main/resources/application.yaml b/runtime-controlloop/src/main/resources/application.yaml new file mode 100644 index 000000000..af9966d40 --- /dev/null +++ b/runtime-controlloop/src/main/resources/application.yaml @@ -0,0 +1,22 @@ +spring: + security: + user: + name: healthcheck + password: zb!XztG34 + http: + converters: + preferred-json-mapper: gson + +security: + enable-csrf: false + +server: + port: 6969 + servlet: + context-path: /onap/controlloop + error: + path: /error + + +runtime: + file: src/main/resources/parameters/ClRuntimeParameters.json diff --git a/runtime-controlloop/src/main/resources/parameters/ClRuntimeParameters.json b/runtime-controlloop/src/main/resources/parameters/ClRuntimeParameters.json new file mode 100644 index 000000000..a6c19837e --- /dev/null +++ b/runtime-controlloop/src/main/resources/parameters/ClRuntimeParameters.json @@ -0,0 +1,63 @@ +{ + "name": "ControlLoopRuntimeGroup", + "supervisionScannerIntervalSec": 1000, + "participantStateChangeIntervalSec": 1000, + "participantClUpdateIntervalSec": 1000, + "participantClStateChangeIntervalSec": 1000, + "restServerParameters": { + "host": "0.0.0.0", + "port": 6969, + "userName": "healthcheck", + "password": "zb!XztG34", + "https": false, + "aaf": false + }, + "participantParameters": { + "heartBeatMs": 120000, + "updateParameters": { + "maxRetryCount": 1, + "maxWaitMs": 30000 + }, + "stateChangeParameters": { + "maxRetryCount": 1, + "maxWaitMs": 30000 + } + }, + "databaseProviderParameters": { + "name": "PolicyProviderParameterGroup", + "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl", + "databaseDriver": "org.mariadb.jdbc.Driver", + "databaseUrl": "jdbc:mariadb://mariadb:3306/controlloop", + "databaseUser": "policy", + "databasePassword": "P01icY", + "persistenceUnit": "CommissioningMariaDb" + }, + "topicParameterGroup": { + "topicSources": [ + { + "topic": "POLICY-CLRUNTIME-PARTICIPANT", + "servers": [ + "message-router" + ], + "topicCommInfrastructure": "dmaap", + "fetchTimeout": 15000 + } + ], + "topicSinks": [ + { + "topic": "POLICY-CLRUNTIME-PARTICIPANT", + "servers": [ + "message-router" + ], + "topicCommInfrastructure": "dmaap" + }, + { + "topic": "POLICY-NOTIFICATION", + "servers": [ + "message-router" + ], + "topicCommInfrastructure": "dmaap" + } + ] + } +} |