Exemplo n.º 1
0
async def delete_documentation(
    # pylint: disable=redefined-builtin
    id: UUID, ) -> None:
    """Change the documentation of a transformation revision in the data base to "".

    This endpoint is deprecated and will be removed soon,
    use PUT /api/transformations/{id} instead
    """

    logger.info("delete documentation %s", id)

    try:
        transformation_revision = read_single_transformation_revision(id)
    except DBNotFoundError as e:
        raise HTTPException(status.HTTP_404_NOT_FOUND, detail=str(e)) from e

    transformation_revision.documentation = ""

    try:
        update_or_create_single_transformation_revision(
            transformation_revision)
        logger.info("deleted documentation {id}")
    except DBIntegrityError as e:
        raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR,
                            detail=str(e)) from e
    except DBNotFoundError as e:
        raise HTTPException(status.HTTP_404_NOT_FOUND, detail=str(e)) from e
def test_updating(clean_test_db_engine):
    with mock.patch(
        "hetdesrun.persistence.dbservice.revision.Session",
        sessionmaker(clean_test_db_engine),
    ):
        tr_uuid = get_uuid_from_seed("test_updating")

        tr_object = TransformationRevision(
            id=tr_uuid,
            revision_group_id=tr_uuid,
            name="Test",
            description="Test description",
            version_tag="1.0.0",
            category="Test category",
            state=State.DRAFT,
            type=Type.COMPONENT,
            content="code",
            io_interface=IOInterface(),
            test_wiring=WorkflowWiring(),
            documentation="",
        )

        store_single_transformation_revision(tr_object)

        tr_object.name = "Test Update"

        update_or_create_single_transformation_revision(tr_object)

        received_tr_object = read_single_transformation_revision(tr_uuid)

        assert tr_object == received_tr_object
Exemplo n.º 3
0
def import_transformation(
    tr_json: dict,
    path: str,
    strip_wirings: bool = False,
    directly_into_db: bool = False,
    update_component_code: bool = True,
) -> None:

    if strip_wirings:
        tr_json["test_wiring"] = {"input_wirings": [], "output_wirings": []}

    if directly_into_db:
        tr = TransformationRevision(**tr_json)
        logger.info(
            ("Update or create database entry"
             " for transformation revision %s of type %s\n"
             "in category %s with name %s"),
            str(tr.id),
            str(tr.type),
            tr.category,
            tr.name,
        )
        update_or_create_single_transformation_revision(tr)

    else:
        headers = get_auth_headers()

        response = requests.put(
            posix_urljoin(get_config().hd_backend_api_url, "transformations",
                          tr_json["id"]),
            params={
                "allow_overwrite_released": True,
                "update_component_code": update_component_code,
            },
            verify=get_config().hd_backend_verify_certs,
            json=tr_json,
            auth=get_backend_basic_auth()  # type: ignore
            if get_config().hd_backend_use_basic_auth else None,
            headers=headers,
        )
        logger.info(
            ("PUT transformation status code: %d"
             " for transformation revision %s of type %s\n"
             "in category %s with name %s"),
            response.status_code,
            tr_json["id"],
            tr_json["type"],
            tr_json["name"],
            tr_json["category"],
        )
        if response.status_code != 201:
            msg = (f"COULD NOT PUT {tr_json['type']} from path {path}\n."
                   f"Response status code {response.status_code}"
                   f"with response text:\n{response.text}")
            logger.error(msg)
Exemplo n.º 4
0
async def bind_wiring_to_component_revision(
    # pylint: disable=redefined-builtin
    id: UUID,
    wiring_dto: WiringFrontendDto,
) -> ComponentRevisionFrontendDto:
    """Store or update the test wiring of a transformation revision of type component.

    This endpoint is deprecated and will be removed soon,
    use PUT /api/transformations/{id} instead.
    """

    logger.info("bind wiring to component %s", id)

    try:
        transformation_revision = read_single_transformation_revision(id)
        logger.info("found component with id %s", id)
    except DBNotFoundError as e:
        raise HTTPException(status.HTTP_404_NOT_FOUND, detail=str(e)) from e

    if transformation_revision.type != Type.COMPONENT:
        msg = f"DB entry for id {id} does not have type {Type.COMPONENT}"
        logger.error(msg)
        raise HTTPException(status.HTTP_404_NOT_FOUND, detail=msg)

    wiring = wiring_dto.to_wiring()
    transformation_revision.test_wiring = wiring

    try:
        persisted_transformation_revision = (
            update_or_create_single_transformation_revision(
                transformation_revision))
        logger.info("bound wiring to component %s", id)
    except DBIntegrityError as e:
        raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR,
                            detail=str(e)) from e
    except DBNotFoundError as e:
        raise HTTPException(status.HTTP_404_NOT_FOUND, detail=str(e)) from e

    persisted_component_dto = ComponentRevisionFrontendDto.from_transformation_revision(
        persisted_transformation_revision)
    logger.debug(persisted_component_dto.json())

    return persisted_component_dto
Exemplo n.º 5
0
async def update_documentation(
    # pylint: disable=redefined-builtin
    id: UUID,
    documentation_dto: DocumentationFrontendDto,
) -> DocumentationFrontendDto:
    """Update or store the documentation of a transformation revision in the data base.

    This endpoint is deprecated and will be removed soon,
    use PUT /api/transformations/{id} instead
    """

    logger.info("update documentation %s", id)

    if id != documentation_dto.id:
        msg = (f"The id {id} does not match "
               f"the id of the documentation DTO {documentation_dto.id}")
        logger.error(msg)
        raise HTTPException(status.HTTP_403_FORBIDDEN, detail=msg)

    try:
        transformation_revision = read_single_transformation_revision(id)
    except DBNotFoundError as e:
        raise HTTPException(status.HTTP_404_NOT_FOUND, detail=str(e)) from e

    transformation_revision.documentation = documentation_dto.document

    try:
        persisted_transformation_revision = (
            update_or_create_single_transformation_revision(
                transformation_revision))
        logger.info("updated documentation {id}")
    except DBIntegrityError as e:
        raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR,
                            detail=str(e)) from e
    except DBNotFoundError as e:
        raise HTTPException(status.HTTP_404_NOT_FOUND, detail=str(e)) from e

    persisted_documentation_dto = DocumentationFrontendDto.from_transformation_revision(
        persisted_transformation_revision)
    logger.debug(persisted_documentation_dto.json())

    return persisted_documentation_dto
Exemplo n.º 6
0
async def update_component_revision(
    # pylint: disable=redefined-builtin
    id: UUID,
    updated_component_dto: ComponentRevisionFrontendDto,
) -> ComponentRevisionFrontendDto:
    """Update or store a transformation revision of type component in the data base.

    If no DB entry with the provided id is found, it will be created.

    Updating a transformation revision is only possible if it is in state DRAFT
    or to change the state from RELEASED to DISABLED.

    This endpoint is deprecated and will be removed soon,
    use PUT /api/transformations/{id} instead.
    """

    logger.info("update component %s", id)

    if id != updated_component_dto.id:
        msg = (
            f"The id {id} does not match "
            f"the id of the component revision DTO {updated_component_dto.id}")
        logger.error(msg)
        raise HTTPException(status.HTTP_403_FORBIDDEN, detail=msg)

    try:
        updated_transformation_revision = (
            updated_component_dto.to_transformation_revision())
    except ValidationError as e:
        logger.error("The following validation error occured:\n%s", str(e))
        raise HTTPException(status.HTTP_422_UNPROCESSABLE_ENTITY,
                            detail=str(e)) from e

    existing_transformation_revision: Optional[TransformationRevision] = None

    try:
        existing_transformation_revision = read_single_transformation_revision(
            id, log_error=False)
        logger.info("found transformation revision %s", id)
    except DBNotFoundError:
        # base/example workflow deployment needs to be able to put
        # with an id and either create or update the component revision
        pass

    modifiable, msg = is_modifiable(
        existing_transformation_revision,
        updated_transformation_revision,
    )
    if not modifiable:
        logger.error(msg)
        raise HTTPException(status.HTTP_403_FORBIDDEN, detail=msg)

    if existing_transformation_revision is not None:
        updated_transformation_revision.documentation = (
            existing_transformation_revision.documentation)
        updated_transformation_revision.test_wiring = (
            existing_transformation_revision.test_wiring)
        updated_transformation_revision.released_timestamp = (
            existing_transformation_revision.released_timestamp)

    updated_transformation_revision = if_applicable_release_or_deprecate(
        existing_transformation_revision, updated_transformation_revision)

    updated_transformation_revision = update_content(
        existing_transformation_revision, updated_transformation_revision)

    try:
        persisted_transformation_revision = (
            update_or_create_single_transformation_revision(
                updated_transformation_revision))
        logger.info("updated component %s", id)
    except DBIntegrityError as e:
        raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR,
                            detail=str(e)) from e
    except DBNotFoundError as e:
        raise HTTPException(status.HTTP_404_NOT_FOUND, detail=str(e)) from e

    persisted_component_dto = ComponentRevisionFrontendDto.from_transformation_revision(
        persisted_transformation_revision)
    logger.debug(persisted_component_dto.json())

    return persisted_component_dto
async def update_transformation_revision(
    # pylint: disable=redefined-builtin
    id: UUID,
    updated_transformation_revision: TransformationRevision,
    allow_overwrite_released: bool = Query(
        False, description="Only set to True for deployment"
    ),
    update_component_code: bool = Query(
        True, description="Only set to False for deployment"
    ),
) -> TransformationRevision:
    """Update or store a transformation revision in the data base.

    If no DB entry with the provided id is found, it will be created.

    Updating a transformation revision is only possible if it is in state DRAFT
    or to change the state from RELEASED to DISABLED.

    Unset attributes of the json sent in the request body will be set to default values,
    possibly changing the attribute saved in the DB.
    """

    logger.info("update transformation revision %s", id)

    if id != updated_transformation_revision.id:
        msg = (
            f"The id {id} does not match the id of the provided "
            f"transformation revision DTO {updated_transformation_revision.id}"
        )
        logger.error(msg)
        raise HTTPException(status.HTTP_403_FORBIDDEN, detail=msg)

    existing_transformation_revision: Optional[TransformationRevision] = None

    try:
        existing_transformation_revision = read_single_transformation_revision(
            id, log_error=False
        )
        logger.info("found transformation revision %s", id)
    except DBNotFoundError:
        # base/example workflow deployment needs to be able to put
        # with an id and either create or update the transformation revision
        pass

    modifiable, msg = is_modifiable(
        existing_transformation_revision,
        updated_transformation_revision,
        allow_overwrite_released,
    )
    if not modifiable:
        logger.error(msg)
        raise HTTPException(status.HTTP_403_FORBIDDEN, detail=msg)

    updated_transformation_revision = if_applicable_release_or_deprecate(
        existing_transformation_revision, updated_transformation_revision
    )

    if updated_transformation_revision.type == Type.WORKFLOW or update_component_code:
        updated_transformation_revision = update_content(
            existing_transformation_revision, updated_transformation_revision
        )

    try:
        persisted_transformation_revision = (
            update_or_create_single_transformation_revision(
                updated_transformation_revision
            )
        )
        logger.info("updated transformation revision %s", id)
    except DBIntegrityError as e:
        logger.error(
            "integrity error in DB when trying to access entry for id %s\n%s", id, e
        )
        raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e)) from e
    except DBNotFoundError as e:
        raise HTTPException(status.HTTP_404_NOT_FOUND, detail=str(e)) from e

    logger.debug(persisted_transformation_revision.json())

    return persisted_transformation_revision