diff options
author | Ajith Sreekumar <ajith.sreekumar@bell.ca> | 2020-08-10 14:33:18 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2020-08-10 14:33:18 +0000 |
commit | 864811238d7d44933df2c4f59f31947a83310587 (patch) | |
tree | 9e6bbf6894e040c20c5d5840fd1582a46ed73aae /gui-editors/gui-editor-apex/src/main/java | |
parent | 6b61be2310929f155dcd38478df13fe1a0d81fad (diff) | |
parent | d4dd779aa66be0e046ecb1938fb532312cfe7680 (diff) |
Merge "Upload policy feature"
Diffstat (limited to 'gui-editors/gui-editor-apex/src/main/java')
15 files changed, 1105 insertions, 8 deletions
diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/ApexEditor.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/ApexEditor.java index 4741346..d21e305 100644 --- a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/ApexEditor.java +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/ApexEditor.java @@ -23,6 +23,7 @@ package org.onap.policy.gui.editors.apex.rest; import org.glassfish.grizzly.http.server.HttpServer; import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory; +import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.server.ResourceConfig; import org.onap.policy.common.utils.validation.Assertions; import org.slf4j.ext.XLogger; @@ -59,6 +60,7 @@ public class ApexEditor { // Create a resource configuration that scans for JAX-RS resources and providers final ResourceConfig rc = new ResourceConfig().packages(parameters.getRestPackages()); + rc.register(MultiPartFeature.class); // create and start a new instance of grizzly http server // exposing the Jersey application at BASE_URI diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/ApexEditorMain.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/ApexEditorMain.java index 481f0af..9d88a2d 100644 --- a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/ApexEditorMain.java +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/ApexEditorMain.java @@ -22,6 +22,7 @@ package org.onap.policy.gui.editors.apex.rest; import java.io.PrintStream; +import org.onap.policy.common.parameters.ParameterService; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; @@ -85,7 +86,6 @@ public class ApexEditorMain { throw new ApexEditorParameterException(REST_ENDPOINT_PREFIX + this.toString() + ") parameter error, " + e.getMessage() + '\n' + parser.getHelp(ApexEditorMain.class.getName()), e); } - if (parameters.isHelpSet()) { throw new ApexEditorParameterException(parser.getHelp(ApexEditorMain.class.getName())); } @@ -97,6 +97,8 @@ public class ApexEditorMain { + validationMessage + '\n' + parser.getHelp(ApexEditorMain.class.getName())); } + ParameterService.register(new UploadPluginConfigParameters()); + state = EditorState.READY; } @@ -210,3 +212,4 @@ public class ApexEditorMain { } } } + diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/UploadPluginConfigParameters.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/UploadPluginConfigParameters.java new file mode 100644 index 0000000..e330af7 --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/UploadPluginConfigParameters.java @@ -0,0 +1,81 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest; + +import java.util.Optional; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.parameters.GroupValidationResult; +import org.onap.policy.common.parameters.ParameterGroup; +import org.onap.policy.common.parameters.ValidationStatus; +import org.onap.policy.gui.editors.apex.rest.handling.config.PolicyUploadPluginConfigKey; + +@Getter +public class UploadPluginConfigParameters implements ParameterGroup { + + public static final String GROUP_NAME = "UploadParameters"; + @Setter + private String name; + private boolean isEnabled; + private String url; + + public UploadPluginConfigParameters() { + this.name = GROUP_NAME; + initProperties(); + } + + private void initProperties() { + final String isEnabledProperty = System.getProperty(PolicyUploadPluginConfigKey.ENABLE.getKey()); + isEnabled = Boolean.parseBoolean(isEnabledProperty); + url = System.getProperty(PolicyUploadPluginConfigKey.URL.getKey()); + } + + @Override + public GroupValidationResult validate() { + final GroupValidationResult result = new GroupValidationResult(this); + if (isEnabled && StringUtils.isEmpty(url)) { + result.setResult("url", ValidationStatus.INVALID, + String.format("The URL for the upload endpoint must be provided as the java property '%s'", + PolicyUploadPluginConfigKey.URL.getKey())); + } + + return result; + } + + /** + * Gets a property value based on the key and type. + * + * @param <T> represents the class type + * @param key the property key + * @return the property value if it exists + */ + public <T> Optional<T> getValue(final PolicyUploadPluginConfigKey key) { + final Class<?> type = key.getType(); + if (key == PolicyUploadPluginConfigKey.URL && type.isInstance(url)) { + return (Optional<T>) Optional.of(type.cast(url)); + } + if (key == PolicyUploadPluginConfigKey.ENABLE && type.isInstance(isEnabled)) { + return (Optional<T>) Optional.of(type.cast(isEnabled)); + } + return Optional.empty(); + } + +} diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ApexEditorRestResource.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ApexEditorRestResource.java index ef5c57a..33aa04d 100644 --- a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ApexEditorRestResource.java +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ApexEditorRestResource.java @@ -22,6 +22,7 @@ package org.onap.policy.gui.editors.apex.rest.handling; import java.io.IOException; +import java.io.InputStream; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -32,9 +33,18 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; +import org.glassfish.jersey.media.multipart.FormDataParam; import org.onap.policy.apex.model.modelapi.ApexApiResult; import org.onap.policy.apex.model.modelapi.ApexApiResult.Result; +import org.onap.policy.common.parameters.ParameterService; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.YamlJsonTranslator; import org.onap.policy.common.utils.resources.TextFileUtils; +import org.onap.policy.gui.editors.apex.rest.UploadPluginConfigParameters; +import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ApexConfigProcessor; +import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter; +import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor; +import org.onap.policy.gui.editors.apex.rest.handling.plugin.upload.UploadPluginClient; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; @@ -61,15 +71,16 @@ import org.slf4j.ext.XLoggerFactory; @Path("editor/{session}") @Produces({MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_JSON}) - public class ApexEditorRestResource implements RestCommandHandler { + // Get a reference to the logger - private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEditorRestResource.class); + private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexEditorRestResource.class); // Location of the periodi event template - private static final String PERIODIC_EVENT_TEMPLATE = "src/main/resources/templates/PeriodicEventTemplate.json"; + private static final String PERIODIC_EVENT_TEMPLATE = "src/main/resources/templates/PeriodicEventTemplate.json"; // Recurring string constants + private static final String NAME = "name"; private static final String VERSION = "version"; private static final String REST_COMMAND_NOT_RECOGNISED = "REST command not recognised"; @@ -77,12 +88,12 @@ public class ApexEditorRestResource implements RestCommandHandler { private static final String NOT_OK = ": Not OK"; private static final String SESSION_CREATE = "Session/Create"; private static final String SESSION_CREATE_NOT_OK = "Session/Create: Not OK"; - // The session handler for sessions on the Apex editor - private static final RestSessionHandler SESSION_HANDLER = new RestSessionHandler(); + private static final RestSessionHandler SESSION_HANDLER = new RestSessionHandler(); // Handlers for the various parts of an Apex model //@formatter:off + private static final ModelHandler MODEL_HANDLER = new ModelHandler(); private static final KeyInfoHandler KEY_INFO_HANDLER = new KeyInfoHandler(); private static final ContextSchemaHandler CONTEXT_SCHEMA_HANDLER = new ContextSchemaHandler(); @@ -90,13 +101,27 @@ public class ApexEditorRestResource implements RestCommandHandler { private static final EventHandler EVENT_HANDLER = new EventHandler(); private static final TaskHandler TASK_HANDLER = new TaskHandler(); private static final PolicyHandler POLICY_HANDLER = new PolicyHandler(); - //@formatter:on + private final PolicyUploadHandler policyUploadHandler; + //@formatter:on // The ID of this session. This gets injected from the URL. + @PathParam("session") private int sessionId = -1; /** + * Creates the ApexEditorRestResource instance. + */ + public ApexEditorRestResource() { + final StandardCoder standardCoder = new StandardCoder(); + policyUploadHandler = new PolicyUploadHandler( + new UploadPluginClient(), new PolicyToscaConverter(standardCoder, new YamlJsonTranslator()), + new ToscaTemplateProcessor(standardCoder), new ApexConfigProcessor(standardCoder), + ParameterService.get(UploadPluginConfigParameters.GROUP_NAME) + ); + } + + /** * Creates a new session. Always call this method with sessionID -1, whereby a new sessionID will be allocated. If * successful the new sessionID will be available in the first message in the result. * @@ -226,6 +251,27 @@ public class ApexEditorRestResource implements RestCommandHandler { } /** + * Uploads a Policy Model to a configured endpoint converting it to tosca based on the given apex config and tosca + * templates. + * + * @param toscaTemplateFileStream the tosca template file input stream + * @param apexConfigFileStream the apex config file input stream + * @return an ApexAPIResult that contains the operation status and success/error messages + */ + @POST + @Path("Model/Upload") + @Consumes({MediaType.MULTIPART_FORM_DATA}) + public ApexApiResult uploadModel(@FormDataParam("tosca-template-file") InputStream toscaTemplateFileStream, + @FormDataParam("apex-config-file") InputStream apexConfigFileStream) { + final ApexApiResult result = new ApexApiResult(); + final RestSession session = SESSION_HANDLER.getSession(sessionId, result); + if (session == null) { + return result; + } + return policyUploadHandler.doUpload(session.getApexModel(), toscaTemplateFileStream, apexConfigFileStream); + } + + /** * Delete the model for this session. * * @return an ApexAPIResult object. If successful then {@link ApexApiResult#isOk()} will return true. Any diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ConfigurationRestResource.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ConfigurationRestResource.java new file mode 100644 index 0000000..76af06e --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ConfigurationRestResource.java @@ -0,0 +1,83 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest.handling; + +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import org.onap.policy.apex.model.modelapi.ApexApiResult; +import org.onap.policy.apex.model.modelapi.ApexApiResult.Result; +import org.onap.policy.common.parameters.ParameterService; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.gui.editors.apex.rest.UploadPluginConfigParameters; +import org.onap.policy.gui.editors.apex.rest.handling.config.PolicyUploadPluginConfigKey; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Handles endpoints for the configuration properties. + */ +@Path("editor/config") +@Produces({MediaType.APPLICATION_JSON}) +@Consumes({MediaType.APPLICATION_JSON}) +public class ConfigurationRestResource { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationRestResource.class); + private static final StandardCoder STANDARD_CODER = new StandardCoder(); + + private final UploadPluginConfigParameters uploadConfigParam; + + public ConfigurationRestResource() { + uploadConfigParam = ParameterService.get(UploadPluginConfigParameters.GROUP_NAME); + } + + /** + * Gets the configured properties. + * + * @return the properties as JSON in the ApexApiResult messages list. + */ + @GET + @Path("") + public ApexApiResult show() { + final ApexApiResult result = new ApexApiResult(Result.SUCCESS); + + final Map<String, Object> configMap = Stream.of(PolicyUploadPluginConfigKey.values()) + .filter(key -> uploadConfigParam.getValue(key).isPresent()) + .collect(Collectors.toMap(PolicyUploadPluginConfigKey::getKey, + configKey -> uploadConfigParam.getValue(configKey).get())); + try { + final String encode = STANDARD_CODER.encode(configMap); + result.addMessage(encode); + } catch (final CoderException e) { + result.setResult(Result.FAILED); + final String errorMsg = "Could not parse configuration parameters as JSON"; + result.addMessage(errorMsg); + LOGGER.error(errorMsg, e); + } + return result; + } + +} diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ModelHandler.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ModelHandler.java index 667d771..3bedad2 100644 --- a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ModelHandler.java +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/ModelHandler.java @@ -389,7 +389,7 @@ public class ModelHandler implements RestCommandHandler { * * @param jsonObject the object to query * @param fieldTag the tag of the field to condition - * @param fieldValue the value of the field to condition + * @param value the default value of the field to condition * @return field read from the json */ private String readFieldFromJsonObject(final JsonObject jsonObject, final String fieldTag, final String value) { diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/PolicyUploadHandler.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/PolicyUploadHandler.java new file mode 100644 index 0000000..af8d9dd --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/PolicyUploadHandler.java @@ -0,0 +1,182 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest.handling; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Optional; +import javax.ws.rs.core.Response; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; +import org.onap.policy.apex.model.modelapi.ApexApiResult; +import org.onap.policy.apex.model.modelapi.ApexApiResult.Result; +import org.onap.policy.apex.model.modelapi.ApexModel; +import org.onap.policy.apex.model.policymodel.concepts.AxPolicyModel; +import org.onap.policy.gui.editors.apex.rest.UploadPluginConfigParameters; +import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ApexConfigProcessor; +import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter; +import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ProcessedTemplate; +import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor; +import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.exception.PolicyToscaConverterException; +import org.onap.policy.gui.editors.apex.rest.handling.plugin.upload.UploadPluginClient; +import org.onap.policy.gui.editors.apex.rest.handling.plugin.upload.UploadPolicyRequestDto; +import org.slf4j.ext.XLogger; +import org.slf4j.ext.XLoggerFactory; + +/** + * Handles the Policy Model upload. + */ +public class PolicyUploadHandler { + + private static final XLogger LOGGER = XLoggerFactory.getXLogger(PolicyUploadHandler.class); + private final PolicyToscaConverter policyToscaConverter; + private final ToscaTemplateProcessor toscaTemplateProcessor; + private final ApexConfigProcessor apexConfigProcessor; + private final UploadPluginClient uploadPluginClient; + private final UploadPluginConfigParameters uploadPluginConfigParameters; + + /** + * Creates the upload handler with its necessary dependencies. + * + * @param uploadPluginClient the UploadPluginClient instance + * @param policyToscaConverter the PolicyToscaConverter instance + * @param toscaTemplateProcessor the ToscaTemplateProcessor instance + * @param apexConfigProcessor the ApexConfigProcessor instance + * @param uploadPluginConfigParameters the Config instance + */ + public PolicyUploadHandler(final UploadPluginClient uploadPluginClient, + final PolicyToscaConverter policyToscaConverter, + final ToscaTemplateProcessor toscaTemplateProcessor, + final ApexConfigProcessor apexConfigProcessor, + final UploadPluginConfigParameters uploadPluginConfigParameters) { + this.uploadPluginClient = uploadPluginClient; + this.policyToscaConverter = policyToscaConverter; + this.toscaTemplateProcessor = toscaTemplateProcessor; + this.apexConfigProcessor = apexConfigProcessor; + this.uploadPluginConfigParameters = uploadPluginConfigParameters; + } + + /** + * Handles the policy model upload converting it to TOSCA with given template files. + * + * @param apexModel the apex model that contains the policy model + * @param toscaTemplateInputStream the tosca template input stream + * @param apexConfigInputStream the apex config input stream + * @return the result of the upload process + */ + public ApexApiResult doUpload(final ApexModel apexModel, final InputStream toscaTemplateInputStream, + final InputStream apexConfigInputStream) { + final ProcessedTemplate processedToscaTemplate; + try { + processedToscaTemplate = toscaTemplateProcessor.process(toscaTemplateInputStream); + } catch (final IOException e) { + final ApexApiResult result = new ApexApiResult(Result.FAILED); + result.addThrowable(e); + final String errorMsg = "Could not process the tosca template file"; + result.addMessage(errorMsg); + LOGGER.error(errorMsg, e); + return result; + } + if (!processedToscaTemplate.isValid()) { + return buildResponse(processedToscaTemplate); + } + + final ProcessedTemplate processedApexConfig; + try { + processedApexConfig = apexConfigProcessor.process(apexConfigInputStream); + } catch (final IOException e) { + final ApexApiResult result = new ApexApiResult(Result.FAILED); + result.addThrowable(e); + final String errorMsg = "Could not process the apex config file"; + result.addMessage(errorMsg); + LOGGER.error(errorMsg, e); + return result; + } + if (!processedApexConfig.isValid()) { + return buildResponse(processedApexConfig); + } + return doUpload(apexModel, processedToscaTemplate.getContent(), processedApexConfig.getContent()); + } + + private ApexApiResult doUpload(final ApexModel apexModel, final String toscaTemplate, final String apexConfig) { + LOGGER.entry(); + if (!isUploadPluginEnabled()) { + final ApexApiResult apexApiResult = new ApexApiResult(Result.FAILED); + apexApiResult.addMessage("Upload feature is disabled"); + return apexApiResult; + } + final AxPolicyModel policyModel = apexModel.getPolicyModel(); + final ApexApiResult result = apexModel.listModel(); + final UploadPolicyRequestDto uploadPolicyRequestDto = new UploadPolicyRequestDto(); + final AxArtifactKey policyKey = policyModel.getKeyInformation().getKey(); + final java.util.UUID uuid = policyModel.getKeyInformation().get(policyKey).getUuid(); + uploadPolicyRequestDto + .setFilename(String.format("%s.%s.%s", uuid, policyKey.getName(), policyKey.getVersion())); + final String apexPolicy = convert(result.getMessage(), toscaTemplate, apexConfig).orElse(null); + if (apexPolicy == null) { + final ApexApiResult apexApiResult = new ApexApiResult(Result.FAILED); + apexApiResult.addMessage( + String.format("An error has occurred while uploading the converting the Policy '%s' to YAML.", + policyModel.getId())); + LOGGER.exit("Model/Upload: NOT OK"); + return apexApiResult; + } + uploadPolicyRequestDto.setFileData( + Base64.getEncoder().encodeToString(apexPolicy.getBytes(StandardCharsets.UTF_8))); + final Response response = uploadPluginClient.upload(uploadPolicyRequestDto); + if (response.getStatus() == 201) { + final ApexApiResult apexApiResult = new ApexApiResult(Result.SUCCESS); + apexApiResult.addMessage(String.format("Policy '%s' uploaded successfully", policyModel.getId())); + LOGGER.exit("Model/Upload: OK"); + return apexApiResult; + } else { + final ApexApiResult apexApiResult = new ApexApiResult(Result.FAILED); + apexApiResult.addMessage( + String.format("An error has occurred while uploading the Policy '%s'. Status was %s", + policyModel.getId(), response.getStatus())); + LOGGER.exit("Model/Upload: NOT OK"); + return apexApiResult; + } + } + + private ApexApiResult buildResponse(final ProcessedTemplate processedTemplate) { + final ApexApiResult result = new ApexApiResult(Result.SUCCESS); + if (!processedTemplate.isValid()) { + result.setResult(Result.OTHER_ERROR); + processedTemplate.getErrorSet().forEach(result::addMessage); + } + return result; + } + + private boolean isUploadPluginEnabled() { + return uploadPluginConfigParameters.isEnabled(); + } + + private Optional<String> convert(final String apexPolicy, final String toscaTemplate, final String apexConfig) { + try { + return policyToscaConverter.convert(apexPolicy, apexConfig, toscaTemplate); + } catch (final PolicyToscaConverterException e) { + LOGGER.error("Could not convert policy to TOSCA", e); + } + + return Optional.empty(); + } +} diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/config/PolicyUploadPluginConfigKey.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/config/PolicyUploadPluginConfigKey.java new file mode 100644 index 0000000..02e23ff --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/config/PolicyUploadPluginConfigKey.java @@ -0,0 +1,40 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest.handling.config; + +import lombok.Getter; + +/** + * Represents properties related to the upload plugin. + */ +@Getter +public enum PolicyUploadPluginConfigKey { + URL("plugin.policy.upload.url", String.class), + ENABLE("plugin.policy.upload.enable", Boolean.class); + + private final String key; + private final Class<?> type; + + PolicyUploadPluginConfigKey(final String key, final Class<?> type) { + this.key = key; + this.type = type; + } + +} diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/ApexConfigProcessor.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/ApexConfigProcessor.java new file mode 100644 index 0000000..e05b833 --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/ApexConfigProcessor.java @@ -0,0 +1,117 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest.handling.converter.tosca; + +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ApexConfigProcessor.ErrorMessage.INVALID_APEX_CONFIG; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ApexConfigProcessor.ErrorMessage.INVALID_ENTRY; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ApexConfigProcessor.ErrorMessage.MISSING_ENTRY; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.ENGINE_SERVICE_PARAMETERS; + +import com.google.gson.JsonObject; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Set; +import lombok.AllArgsConstructor; +import org.apache.commons.io.IOUtils; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Process the Apex Config JSON template file. + */ +public class ApexConfigProcessor { + + private static final Logger LOGGER = LoggerFactory.getLogger(ApexConfigProcessor.class); + + private final StandardCoder standardCoder; + + public ApexConfigProcessor(final StandardCoder standardCoder) { + this.standardCoder = standardCoder; + } + + /** + * Process the Apex Config JSON template file. + * + * @param apexConfigInputStream the input stream for the Apex Config JSON template + * @return the result of the processing with the read JSON and its errors. + */ + public ProcessedTemplate process(final InputStream apexConfigInputStream) throws IOException { + final ProcessedTemplate processedTemplate = new ProcessedTemplate(); + final String templateAsString; + try (final InputStream inputStream = apexConfigInputStream) { + templateAsString = IOUtils.toString(inputStream, StandardCharsets.UTF_8); + } + final Set<String> errorSet = validate(templateAsString); + processedTemplate.setContent(templateAsString); + processedTemplate.addToErrors(errorSet); + + return processedTemplate; + } + + private Set<String> validate(final String apexConfig) { + final Set<String> errorSet = new HashSet<>(); + final JsonObject apexConfigJson; + try { + apexConfigJson = standardCoder.decode(apexConfig, JsonObject.class); + } catch (final CoderException e) { + LOGGER.debug(INVALID_APEX_CONFIG.getMessage(), e); + errorSet.add(INVALID_APEX_CONFIG.getMessage()); + return errorSet; + } + + final JsonObject topologyTemplate; + try { + topologyTemplate = apexConfigJson.getAsJsonObject(ENGINE_SERVICE_PARAMETERS.getKey()); + } catch (final Exception e) { + final String errorMsg = INVALID_ENTRY.getMessage(ENGINE_SERVICE_PARAMETERS.getKey()); + LOGGER.debug(errorMsg, e); + errorSet.add(errorMsg); + return errorSet; + } + + if (topologyTemplate == null) { + errorSet.add(MISSING_ENTRY.getMessage(ENGINE_SERVICE_PARAMETERS.getKey())); + return errorSet; + } + + return errorSet; + } + + /** + * Stores the possible error messages for the Apex Config template validation process. + */ + @AllArgsConstructor + public enum ErrorMessage { + MISSING_ENTRY("Missing '%s' entry"), + INVALID_ENTRY("Invalid entry '%s' provided"), + INVALID_APEX_CONFIG("Invalid apex config provided"); + + private final String messageFormat; + + public String getMessage(final String... params) { + return String.format(this.messageFormat, params); + } + } + +} diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/PolicyToscaConverter.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/PolicyToscaConverter.java new file mode 100644 index 0000000..0bacb24 --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/PolicyToscaConverter.java @@ -0,0 +1,168 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest.handling.converter.tosca; + +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.ENGINE_SERVICE_PARAMETERS; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.POLICIES; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.POLICY_TYPE_IMPL; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.PROPERTIES; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.TOPOLOGY_TEMPLATE; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.util.Map.Entry; +import java.util.Optional; +import lombok.Getter; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.YamlJsonTranslator; +import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.exception.PolicyToscaConverterException; + +/** + * Handles the conversion from policy JSON to policy YAML. + */ +public class PolicyToscaConverter { + + private final StandardCoder standardCoder; + private final YamlJsonTranslator yamlJsonTranslator; + + /** + * Creates a policy tosca converter. + * + * @param standardCoder the encoder that will handle JSON conversions + * @param yamlJsonTranslator the translator that will handle YAML conversions + */ + public PolicyToscaConverter(final StandardCoder standardCoder, final YamlJsonTranslator yamlJsonTranslator) { + this.standardCoder = standardCoder; + this.yamlJsonTranslator = yamlJsonTranslator; + } + + /** + * Converts the policy model to TOSCA, by merging the 3 given JSON models. + * + * @param policyModelJsonString the policy model JSON + * @param apexConfigJsonString the apex config JSON + * @param toscaTemplateJsonString the base TOSCA template in JSON format + * @return the merged policy model in YAML format + * @throws PolicyToscaConverterException when a JSON string could not be parsed to JsonObject or the resulting JSON + * could not be parsed to YAML. + */ + public Optional<String> convert(final String policyModelJsonString, final String apexConfigJsonString, + final String toscaTemplateJsonString) throws PolicyToscaConverterException { + final JsonObject apexConfigJson = decodeToJson(apexConfigJsonString); + final JsonObject policyModelJson = decodeToJson(policyModelJsonString); + final JsonObject toscaTemplateJson = decodeToJson(toscaTemplateJsonString); + + final JsonObject toscaPolicyProperties = readTopologyTemplateAsJsonObject(toscaTemplateJson); + final JsonObject toscaPolicy = readToscaPolicyAsJsonObject(toscaPolicyProperties); + final JsonObject toscaProperties = readPolicyPropertiesAsJsonObject(toscaPolicy); + + for (final Entry<String, JsonElement> entry : apexConfigJson.entrySet()) { + if (ENGINE_SERVICE_PARAMETERS.getKey().equals(entry.getKey())) { + final JsonObject engineServiceParameters = readEngineServiceParametersAsJsonObject(entry.getValue()); + engineServiceParameters.add(POLICY_TYPE_IMPL.getKey(), policyModelJson); + } + toscaProperties.add(entry.getKey(), entry.getValue()); + } + return Optional.ofNullable(convertToYaml(toscaTemplateJson)); + } + + private JsonObject readTopologyTemplateAsJsonObject(final JsonObject toscaTemplateJson) + throws PolicyToscaConverterException { + + try { + return toscaTemplateJson.get(TOPOLOGY_TEMPLATE.getKey()).getAsJsonObject(); + } catch (final Exception e) { + throw new PolicyToscaConverterException( + String.format("Could not read the '%s' entry in the Tosca Template", TOPOLOGY_TEMPLATE.getKey()), e); + } + } + + private JsonObject readEngineServiceParametersAsJsonObject(final JsonElement engineServiceParametersEntry) + throws PolicyToscaConverterException { + + try { + return engineServiceParametersEntry.getAsJsonObject(); + } catch (final Exception e) { + throw new PolicyToscaConverterException( + String.format("Could not read the '%s' in the Apex Config", ENGINE_SERVICE_PARAMETERS.getKey()), e); + } + } + + private JsonObject readToscaPolicyAsJsonObject(final JsonObject toscaPolicyProperties) + throws PolicyToscaConverterException { + + try { + return toscaPolicyProperties.get(POLICIES.getKey()).getAsJsonArray().get(0).getAsJsonObject(); + } catch (final Exception e) { + throw new PolicyToscaConverterException( + String.format("Could not read the first policy in the '%s' entry under '%s'", + POLICIES.getKey(), TOPOLOGY_TEMPLATE.getKey()), e); + } + } + + private JsonObject readPolicyPropertiesAsJsonObject(final JsonObject toscaPolicy) + throws PolicyToscaConverterException { + + try { + final String policyObjectKey = toscaPolicy.keySet().iterator().next(); + final JsonObject policyEntry = toscaPolicy.get(policyObjectKey).getAsJsonObject(); + return policyEntry.get(PROPERTIES.getKey()).getAsJsonObject(); + } catch (final Exception e) { + throw new PolicyToscaConverterException( + String.format("Could not read the policy '%s' entry", PROPERTIES.getKey()), e); + } + } + + private String convertToYaml(final JsonObject jsonObject) throws PolicyToscaConverterException { + try { + return yamlJsonTranslator.toYaml(jsonObject); + } catch (final Exception e) { + throw new PolicyToscaConverterException( + String.format("Could not convert JSON Object to YAML:%n%s", jsonObject.toString()), e); + } + } + + private JsonObject decodeToJson(final String jsonString) throws PolicyToscaConverterException { + try { + return standardCoder.decode(jsonString, JsonObject.class); + } catch (final CoderException e) { + throw new PolicyToscaConverterException( + String.format("Could not convert JSON string to JSON:%n%s", jsonString), e); + } + } + + @Getter + public enum ToscaKey { + TOPOLOGY_TEMPLATE("topology_template"), + TOSCA_DEFINITIONS_VERSION("tosca_definitions_version"), + PROPERTIES("properties"), + ENGINE_SERVICE_PARAMETERS("engineServiceParameters"), + POLICY_TYPE_IMPL("policy_type_impl"), + POLICIES("policies"); + + private final String key; + + ToscaKey(final String key) { + this.key = key; + } + } + +} diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/ProcessedTemplate.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/ProcessedTemplate.java new file mode 100644 index 0000000..1b4bb97 --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/ProcessedTemplate.java @@ -0,0 +1,60 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest.handling.converter.tosca; + +import java.util.HashSet; +import java.util.Set; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.collections4.CollectionUtils; + +@Getter +@Setter +public class ProcessedTemplate { + + private String content; + private final Set<String> errorSet; + + public ProcessedTemplate() { + errorSet = new HashSet<>(); + } + + /** + * Adds the given error messages to the errors collection. + * + * @param errorSet a set of error messages + */ + public void addToErrors(final Set<String> errorSet) { + if (CollectionUtils.isEmpty(errorSet)) { + return; + } + + this.errorSet.addAll(errorSet); + } + + /** + * Checks if the processed template is valid. + * + * @return {@code true} if the content is valid, {@code false} otherwise + */ + public boolean isValid() { + return CollectionUtils.isEmpty(errorSet); + } +} diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/ToscaTemplateProcessor.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/ToscaTemplateProcessor.java new file mode 100644 index 0000000..5539617 --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/ToscaTemplateProcessor.java @@ -0,0 +1,179 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest.handling.converter.tosca; + +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.POLICIES; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.PROPERTIES; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.TOPOLOGY_TEMPLATE; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey.TOSCA_DEFINITIONS_VERSION; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.INVALID_ENTRY; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.INVALID_POLICY; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.INVALID_TOSCA_TEMPLATE; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.MISSING_ENTRY; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.MISSING_POLICY; +import static org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.ToscaTemplateProcessor.ErrorMessage.ONLY_ONE_POLICY_ALLOWED; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import lombok.AllArgsConstructor; +import org.apache.commons.io.IOUtils; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.gui.editors.apex.rest.handling.converter.tosca.PolicyToscaConverter.ToscaKey; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Process the TOSCA JSON template file, base for the Policy Model TOSCA conversion. + */ +public class ToscaTemplateProcessor { + + private static final Logger LOGGER = LoggerFactory.getLogger(ToscaTemplateProcessor.class); + + private final StandardCoder jsonCoder; + + public ToscaTemplateProcessor(final StandardCoder jsonCoder) { + this.jsonCoder = jsonCoder; + } + + /** + * Process the TOSCA JSON template file. + * + * @param toscaTemplateInputStream the input stream for the TOSCA JSON template file + * @return the result of the processing with the read JSON and its errors. + */ + public ProcessedTemplate process(final InputStream toscaTemplateInputStream) throws IOException { + final ProcessedTemplate processedTemplate = new ProcessedTemplate(); + + final String templateAsString; + try (final InputStream inputStream = toscaTemplateInputStream) { + templateAsString = IOUtils.toString(inputStream, StandardCharsets.UTF_8); + } + + final Set<String> errorSet = validate(templateAsString); + processedTemplate.setContent(templateAsString); + processedTemplate.addToErrors(errorSet); + + return processedTemplate; + } + + private Set<String> validate(final String toscaTemplate) { + final Set<String> errorSet = new HashSet<>(); + final JsonObject toscaTemplateJson; + try { + toscaTemplateJson = jsonCoder.decode(toscaTemplate, JsonObject.class); + } catch (final CoderException e) { + LOGGER.debug(INVALID_TOSCA_TEMPLATE.getMessage(), e); + errorSet.add(INVALID_TOSCA_TEMPLATE.getMessage()); + return errorSet; + } + + final Optional<JsonPrimitive> toscaDefinitionVersionOpt = + readJsonEntry(TOSCA_DEFINITIONS_VERSION, toscaTemplateJson::getAsJsonPrimitive, errorSet); + if (toscaDefinitionVersionOpt.isEmpty()) { + return errorSet; + } + + final Optional<JsonObject> topologyTemplate = + readJsonEntry(TOPOLOGY_TEMPLATE, toscaTemplateJson::getAsJsonObject, errorSet); + if (topologyTemplate.isEmpty()) { + return errorSet; + } + + final Optional<JsonArray> policiesOpt = + readJsonEntry(POLICIES, topologyTemplate.get()::getAsJsonArray, errorSet); + if (policiesOpt.isEmpty()) { + return errorSet; + } + final JsonArray policies = policiesOpt.get(); + + if (policies.size() == 0) { + errorSet.add(MISSING_POLICY.getMessage()); + return errorSet; + } + + if (policies.size() > 1) { + errorSet.add(ONLY_ONE_POLICY_ALLOWED.getMessage()); + return errorSet; + } + + final JsonObject firstPolicy; + try { + final JsonObject firstPolicyObj = policies.get(0).getAsJsonObject(); + firstPolicy = firstPolicyObj.entrySet().iterator().next().getValue().getAsJsonObject(); + } catch (final Exception e) { + final String errorMsg = INVALID_POLICY.getMessage(); + LOGGER.debug(errorMsg, e); + errorSet.add(errorMsg); + return errorSet; + } + + readJsonEntry(PROPERTIES, firstPolicy::getAsJsonObject, errorSet); + + return errorSet; + } + + private <T> Optional<T> readJsonEntry(final ToscaKey toscaKey, + final Function<String, T> jsonFunction, final Set<String> errorSet) { + try { + final T json = jsonFunction.apply(toscaKey.getKey()); + if (json == null) { + errorSet.add(MISSING_ENTRY.getMessage(toscaKey.getKey())); + } + return Optional.ofNullable(json); + } catch (final Exception e) { + final String errorMsg = INVALID_ENTRY.getMessage(toscaKey.getKey()); + LOGGER.debug(errorMsg, e); + errorSet.add(errorMsg); + return Optional.empty(); + } + + } + + /** + * Stores the possible error messages for the Tosca template validation process. + */ + @AllArgsConstructor + public enum ErrorMessage { + MISSING_ENTRY("Missing '%s' entry"), + MISSING_POLICY("No policy was provided in the 'policies' list"), + INVALID_POLICY("Invalid policy was provided in the 'policies' list"), + ONLY_ONE_POLICY_ALLOWED("Only one policy entry is allowed in the 'policies' list"), + INVALID_TOSCA_TEMPLATE("Invalid tosca template provided"), + INVALID_ENTRY("Invalid entry '%s' provided"), + MISSING_PROPERTIES_ENTRY("Missing properties entry in '%s'"); + + private final String messageFormat; + + public String getMessage(final String... params) { + return String.format(this.messageFormat, params); + } + } + + +} diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/exception/PolicyToscaConverterException.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/exception/PolicyToscaConverterException.java new file mode 100644 index 0000000..a24c393 --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/converter/tosca/exception/PolicyToscaConverterException.java @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest.handling.converter.tosca.exception; + +public class PolicyToscaConverterException extends Exception { + + public PolicyToscaConverterException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/plugin/upload/UploadPluginClient.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/plugin/upload/UploadPluginClient.java new file mode 100644 index 0000000..d0c97c9 --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/plugin/upload/UploadPluginClient.java @@ -0,0 +1,69 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest.handling.plugin.upload; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.onap.policy.common.parameters.ParameterService; +import org.onap.policy.gui.editors.apex.rest.UploadPluginConfigParameters; + +/** + * Client for the Policy Model upload endpoint. + */ +public class UploadPluginClient { + + private final Client client; + private final UploadPluginConfigParameters uploadConfigParam; + + /** + * Create a upload plugin client. + */ + public UploadPluginClient() { + this(ClientBuilder.newClient(), ParameterService.get(UploadPluginConfigParameters.GROUP_NAME)); + } + + /** + * Create a upload plugin client. + * @param client the http client + * @param uploadConfigParam the upload configuration parameters + */ + UploadPluginClient(final Client client, + final UploadPluginConfigParameters uploadConfigParam) { + this.client = client; + this.uploadConfigParam = uploadConfigParam; + } + + /** + * Uploads the policy to the configured endpoint. + * + * @param uploadPolicyRequestDto the policy DTO to upload + * @return the request response + */ + public Response upload(final UploadPolicyRequestDto uploadPolicyRequestDto) { + return client + .target(uploadConfigParam.getUrl()) + .request(MediaType.APPLICATION_JSON) + .post(Entity.entity(uploadPolicyRequestDto, MediaType.APPLICATION_JSON)); + } + +} diff --git a/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/plugin/upload/UploadPolicyRequestDto.java b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/plugin/upload/UploadPolicyRequestDto.java new file mode 100644 index 0000000..dbd15a0 --- /dev/null +++ b/gui-editors/gui-editor-apex/src/main/java/org/onap/policy/gui/editors/apex/rest/handling/plugin/upload/UploadPolicyRequestDto.java @@ -0,0 +1,40 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 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.gui.editors.apex.rest.handling.plugin.upload; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import lombok.Data; + +/** + * DTO to a policy upload endpoint. + */ +@XmlRootElement(name = "policy") +@XmlAccessorType(XmlAccessType.FIELD) +@Data +public class UploadPolicyRequestDto { + + private Long id; + private String userId; + private String filename; + private String fileData; + +} |