Search in sources :

Example 16 with Transformation

use of org.opentosca.toscana.core.transformation.Transformation in project TOSCAna by StuPro-TOSCAna.

the class BaseTransformTest method initContext.

/**
 *     initializes the transformation context
 */
protected TransformationContext initContext() throws Exception {
    Csar csar = new CsarImpl(tmpdir, "csarId", logMock());
    Transformation t = new TransformationImpl(csar, plugin.getPlatform(), logMock(), model);
    Transformation transformation = spy(t);
    when(transformation.getInputs()).thenReturn(inputs);
    return new TransformationContext(transformation, workingDir);
}
Also used : Csar(org.opentosca.toscana.core.csar.Csar) TransformationImpl(org.opentosca.toscana.core.transformation.TransformationImpl) Transformation(org.opentosca.toscana.core.transformation.Transformation) CsarImpl(org.opentosca.toscana.core.csar.CsarImpl) TransformationContext(org.opentosca.toscana.core.transformation.TransformationContext)

Example 17 with Transformation

use of org.opentosca.toscana.core.transformation.Transformation in project TOSCAna by StuPro-TOSCAna.

the class TransformationController method deleteTransformation.

/**
 *     Deletes a transformation. If it is still running, this request is ignored (returning 400)
 *     <p>
 *     Accessed with http call <code>DELETE /csars/{csar}/transformations/{platform}/delete</code>
 *     <p>
 *     <table summary="">
 *     <tr>
 *     <td>HTTP-Code</td>
 *     <td>Mime-Type</td>
 *     <td>Description (Returned if)</td>
 *     </tr>
 *     <tr>
 *     <td>200</td>
 *     <td>application/hal+json</td>
 *     <td>Returns a Empty body if the deletion was successful</td>
 *     </tr>
 *     <tr>
 *     <td>400</td>
 *     <td>application/hal+json</td>
 *     <td>Returns a empty body if the transformation cannot be deleted (if its still running)</td>
 *     </tr>
 *     <tr>
 *     <td>404</td>
 *     <td>application/json</td>
 *     <td>Returns a error message if the csar is not found or if the csar does not have a transformation for the given
 *     name (see returned error message for details)</td>
 *     </tr>
 *     </table>
 */
@RequestMapping(path = "/{platform}/delete", method = RequestMethod.DELETE, produces = "application/hal+json")
@ApiOperation(value = "Delete a transformation", tags = { "transformations" }, notes = "Deletes a transformation and all the coresponding artifacts")
@ApiResponses({ @ApiResponse(code = 200, message = "The operation was executed successfully"), @ApiResponse(code = 400, message = "The Deletion of the csar failed", response = Void.class), @ApiResponse(code = 404, message = "There is no CSAR for the given identifier or the CSAR does not have " + "a Transformation for the specified platform.", response = RestErrorResponse.class) })
public ResponseEntity<Void> deleteTransformation(@ApiParam(value = "The unique identifier for the CSAR", required = true, example = "test") @PathVariable(name = "csarId") String name, @ApiParam(value = "The identifier for the platform", required = true, example = "kubernetes") @PathVariable(name = "platform") String platform) {
    Csar csar = findByCsarId(name);
    Transformation transformation = findTransformationByPlatform(csar, platform);
    if (transformationService.deleteTransformation(transformation)) {
        // return 200 if the deletion was successful
        return ResponseEntity.ok().build();
    } else {
        // return 400 if the deletion failed
        return ResponseEntity.status(400).build();
    }
}
Also used : Csar(org.opentosca.toscana.core.csar.Csar) Transformation(org.opentosca.toscana.core.transformation.Transformation) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 18 with Transformation

use of org.opentosca.toscana.core.transformation.Transformation in project TOSCAna by StuPro-TOSCAna.

the class TransformationController method getTransformationArtifact.

/**
 *     Returns the URL to download the target Artifact (Wrapped in json)<p>
 *     <p>
 *     Accessed with http call <code>GET /csars/{csar}/transformations/{platform}/artifacts</code>
 *     <table summary="">
 *     <tr>
 *     <td>HTTP-Code</td>
 *     <td>Mime-Type</td>
 *     <td>Description (Returned if)</td>
 *     </tr>
 *     <tr>
 *     <td>200</td>
 *     <td>application/hal+json</td>
 *     <td>Returns a Json object containing the download url for the artifact</td>
 *     </tr>
 *     <tr>
 *     <td>400</td>
 *     <td>application/json</td>
 *     <td>Returned if the transformation is not in a valid state (has to be in DONE or ERROR) to set inputs</td>
 *     </tr>
 *     <tr>
 *     <td>404</td>
 *     <td>application/json</td>
 *     <td>Returns a error message if the csar is not found or if the csar does not have a transformation for the given
 *     name (see returned error message for details)</td>
 *     </tr>
 *     </table>
 */
@RequestMapping(path = "/{platform}/artifact", method = RequestMethod.GET, produces = "application/octet-stream")
@ApiOperation(value = "Download the target artifact archive", tags = { "transformations" }, notes = "Once the transformation is done (in the state DONE) or it has encountered a error (state ERROR). " + "It is possible to download a archive (ZIP format) of all the files generated while the transformation was " + "running.")
@ApiResponses({ @ApiResponse(code = 200, message = "The operation was executed successfully"), @ApiResponse(code = 400, message = "There is nothing to download yet because the execution of the transformation has not yet started " + "or is not finished (With or without errors)", response = RestErrorResponse.class), @ApiResponse(code = 404, message = "There is no CSAR for the given identifier or the CSAR does not have " + "a Transformation for the specified platform.", response = RestErrorResponse.class) })
public ResponseEntity<Void> getTransformationArtifact(@ApiParam(value = "The unique identifier for the CSAR", required = true, example = "test") @PathVariable(name = "csarId") String csarName, @ApiParam(value = "The identifier for the platform", required = true, example = "kubernetes") @PathVariable(name = "platform") String platform, HttpServletResponse response) throws IOException {
    Csar csar = csarService.getCsar(csarName).orElseThrow(CsarNotFoundException::new);
    Transformation transformation = csar.getTransformation(platform).orElseThrow(TransformationNotFoundException::new);
    TargetArtifact artifact = transformation.getTargetArtifact().orElseThrow(() -> new IllegalTransformationStateException(format("Artifact for csar '{}' and platform '{}' not found", csarName, platform)));
    response.setHeader("Content-Disposition", "attachment; filename=\"" + artifact.name + "\"");
    response.setHeader("Content-Type", "application/octet-stream");
    response.setHeader("Content-Length", artifact.getFileSize() + "");
    InputStream in = artifact.readAccess();
    OutputStream out = response.getOutputStream();
    IOUtils.copy(in, out);
    in.close();
    out.close();
    return ResponseEntity.ok().build();
}
Also used : TargetArtifact(org.opentosca.toscana.core.transformation.artifacts.TargetArtifact) IllegalTransformationStateException(org.opentosca.toscana.api.exceptions.IllegalTransformationStateException) Csar(org.opentosca.toscana.core.csar.Csar) Transformation(org.opentosca.toscana.core.transformation.Transformation) TransformationNotFoundException(org.opentosca.toscana.api.exceptions.TransformationNotFoundException) CsarNotFoundException(org.opentosca.toscana.api.exceptions.CsarNotFoundException) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 19 with Transformation

use of org.opentosca.toscana.core.transformation.Transformation in project TOSCAna by StuPro-TOSCAna.

the class TransformationController method setInputs.

/**
 *     This mapping is used to post the inputs to the server.
 *     <p>
 *     Accessed with http call <code>PUT or POST /csars/{csar}/transformations/{platform}/inputs</code>
 *     <table summary="">
 *     <tr>
 *     <td>HTTP-Code</td>
 *     <td>Mime-Type</td>
 *     <td>Description (Returned if)</td>
 *     </tr>
 *     <tr>
 *     <td>200</td>
 *     <td>application/hal+json</td>
 *     <td>Returns a empty body if all required inputs have been set</td>
 *     </tr>
 *     <tr>
 *     <td>400</td>
 *     <td>application/json</td>
 *     <td>Returned if the transformation is not in a valid state (has to be in INPUT_REQUIRED or READY)</td>
 *     </tr>
 *     <tr>
 *     <td>404</td>
 *     <td>application/json</td>
 *     <td>Returns an error message if the csar is not found or if the csar does not have a transformation for the given
 *     platformId (see returned error message for details)</td>
 *     </tr>
 *     </table>
 */
@RequestMapping(path = "/{platform}/inputs", method = { RequestMethod.POST, RequestMethod.PUT }, produces = "application/json")
@ApiOperation(value = "Set the value of inputs", tags = { "transformations" }, notes = "With this method it is possible to set the value of an input or multiple inputs at once. The values " + "of inputs can be set as long as they are in the READY or INPUT_REQUIRED state. The transformation changes its state " + "to ready once all required inputs have a valid value assigned to them.")
@ApiResponses({ @ApiResponse(code = 200, message = "The operation was executed successfully", response = Void.class), @ApiResponse(code = 400, message = "Inputs cannot get set once the transformation has been started.", response = RestErrorResponse.class), @ApiResponse(code = 404, message = "There is no CSAR for the given identifier or the CSAR does not have " + "a transformation for the specified platform.", response = RestErrorResponse.class), @ApiResponse(code = 406, message = "At least one of the inputs could not get set because either the key does not exist or the " + "syntax validation of the value has failed.", response = InputsResponse.class) })
public ResponseEntity<InputsResponse> setInputs(@ApiParam(value = "The unique identifier for the CSAR", required = true, example = "test") @PathVariable(name = "csarId") String csarId, @ApiParam(value = "The identifier for the platform", required = true, example = "kubernetes") @PathVariable(name = "platform") String platformId, @RequestBody InputsResponse propertiesRequest) {
    Csar csar = findByCsarId(csarId);
    Transformation transformation = findTransformationByPlatform(csar, platformId);
    List<TransformationState> validStates = Arrays.asList(INPUT_REQUIRED, READY);
    if (!Arrays.asList(INPUT_REQUIRED, READY).contains(transformation.getState())) {
        throw new IllegalTransformationStateException(String.format("The transformation is not in one of the states '%s'", validStates));
    }
    PropertyInstance inputs = transformation.getInputs();
    Map<String, Boolean> successes = new HashMap<>();
    boolean somethingFailed = false;
    // Set the properties and check their validity
    for (InputWrap entry : propertiesRequest.getInputs()) {
        try {
            boolean success = inputs.set(entry.getKey(), entry.getValue());
            successes.put(entry.getKey(), success);
            if (!success) {
                somethingFailed = true;
            }
        } catch (NoSuchPropertyException e) {
            logger.error("Failed to set inputs for transformation '%s'", transformation, e);
            somethingFailed = true;
            successes.put(entry.getKey(), false);
        }
    }
    if (!somethingFailed) {
        return ResponseEntity.ok().build();
    } else {
        Set<String> requestedKeys = new HashSet<>(successes.keySet());
        List<InputWrap> propWrapList = toPropertyWrapList(inputs, requestedKeys);
        // The request contains invalid values
        if (requestedKeys.size() > propWrapList.size()) {
            Set<String> knownKeys = propWrapList.stream().map(InputWrap::getKey).collect(Collectors.toSet());
            // Remove all known (valid) keys
            requestedKeys.removeAll(knownKeys);
            requestedKeys.forEach(e -> {
                propWrapList.add(new InputWrap(e, PropertyType.INVALID_KEY, "Invalid Key", null, false, null, false));
            });
        }
        InputsResponse response = new InputsResponse(propWrapList);
        return ResponseEntity.status(HttpStatus.NOT_ACCEPTABLE).body(response);
    }
}
Also used : IllegalTransformationStateException(org.opentosca.toscana.api.exceptions.IllegalTransformationStateException) Csar(org.opentosca.toscana.core.csar.Csar) Transformation(org.opentosca.toscana.core.transformation.Transformation) HashMap(java.util.HashMap) InputWrap(org.opentosca.toscana.api.model.InputWrap) PropertyInstance(org.opentosca.toscana.core.transformation.properties.PropertyInstance) TransformationState(org.opentosca.toscana.core.transformation.TransformationState) InputsResponse(org.opentosca.toscana.api.model.InputsResponse) GetInputsResponse(org.opentosca.toscana.api.model.GetInputsResponse) NoSuchPropertyException(org.opentosca.toscana.core.transformation.properties.NoSuchPropertyException) HashSet(java.util.HashSet) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 20 with Transformation

use of org.opentosca.toscana.core.transformation.Transformation in project TOSCAna by StuPro-TOSCAna.

the class TransformationController method getTransformationLogs.

/**
 *     Returns the logs from a given start index to the current end of the logger file. If the start index is higher then
 *     the current end index, a empty list is returned! The start parameter is a URL encoded parameter
 *     (<code>?start=0</code>)
 *     <p>
 *     Accessed with http call <code>GET /csars/{csar}/transformations/{platform}/logs</code>
 *     <table summary="">
 *     <tr>
 *     <td>HTTP-Code</td>
 *     <td>Mime-Type</td>
 *     <td>Description (Returned if)</td>
 *     </tr>
 *     <tr>
 *     <td>200</td>
 *     <td>application/hal+json</td>
 *     <td>Returns a Json object containing the desired part of the logger for the transformation</td>
 *     </tr>
 *     <tr>
 *     <td>404</td>
 *     <td>application/json</td>
 *     <td>Returns a error message if the csar is not found or if the csar does not have a transformation for the given
 *     name (see returned error message for details)</td>
 *     </tr>
 *     </table>
 */
@RequestMapping(path = "/{platform}/logs", method = RequestMethod.GET, produces = "application/hal+json")
@ApiOperation(value = "Get the logs for a Transformation", tags = { "transformations" }, notes = "Returns the logs for a transformation, starting at a specific position. from the given start index all " + "following log lines get returned. If the start index is larger than the current last log index the operation " + "will return a empty list.")
@ApiResponses({ @ApiResponse(code = 200, message = "The operation was executed successfully", response = LogResponse.class), @ApiResponse(code = 400, message = "The given start value is less than zero", response = RestErrorResponse.class), @ApiResponse(code = 404, message = "There is no CSAR for the given identifier or the CSAR does not have " + "a Transformation for the specified platform.", response = RestErrorResponse.class) })
public ResponseEntity<LogResponse> getTransformationLogs(@ApiParam(value = "The unique identifier for the CSAR", required = true, example = "test") @PathVariable(name = "csarId") String csarId, @ApiParam(value = "The identifier for the platform", required = true, example = "kubernetes") @PathVariable(name = "platform") String platformId, @ApiParam(value = "The index of the first log entry you want (0 returns the whole log)", required = true, example = "0") @RequestParam(name = "start", required = false, defaultValue = "0") Long start) {
    if (start < 0) {
        throw new IndexOutOfBoundsException("the start index has to be at least 0");
    }
    Csar csar = findByCsarId(csarId);
    Transformation transformation = findTransformationByPlatform(csar, platformId);
    Log log = transformation.getLog();
    List<LogEntry> entries = log.getLogEntries(Math.toIntExact(start));
    return ResponseEntity.ok().body(new LogResponse(start, // TODO Maybe move this calculation into the LogResponse Class
    entries.size() == 0 ? start : start + entries.size() - 1, entries, platformId, csarId));
}
Also used : Csar(org.opentosca.toscana.core.csar.Csar) Transformation(org.opentosca.toscana.core.transformation.Transformation) LogResponse(org.opentosca.toscana.api.model.LogResponse) Log(org.opentosca.toscana.core.transformation.logging.Log) LogEntry(org.opentosca.toscana.core.transformation.logging.LogEntry) ApiOperation(io.swagger.annotations.ApiOperation) ApiResponses(io.swagger.annotations.ApiResponses) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Aggregations

Transformation (org.opentosca.toscana.core.transformation.Transformation)22 Csar (org.opentosca.toscana.core.csar.Csar)16 ApiOperation (io.swagger.annotations.ApiOperation)9 ApiResponses (io.swagger.annotations.ApiResponses)9 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)9 TransformationImpl (org.opentosca.toscana.core.transformation.TransformationImpl)8 Test (org.junit.Test)6 File (java.io.File)4 IllegalTransformationStateException (org.opentosca.toscana.api.exceptions.IllegalTransformationStateException)4 BaseSpringTest (org.opentosca.toscana.core.BaseSpringTest)4 CsarImpl (org.opentosca.toscana.core.csar.CsarImpl)4 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 TransformationContext (org.opentosca.toscana.core.transformation.TransformationContext)3 PropertyInstance (org.opentosca.toscana.core.transformation.properties.PropertyInstance)3 InputStream (java.io.InputStream)2 ArrayList (java.util.ArrayList)2 Before (org.junit.Before)2 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)2 GetInputsResponse (org.opentosca.toscana.api.model.GetInputsResponse)2