Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cancellation as claim note through VRO's svc-bgs-api #2315

Merged
merged 6 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions .github/workflows/ee-ep-merge-end-to-end.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
workflow_call:

env:
COMPOSE_PROFILES: 'bip'
COMPOSE_PROFILES: 'bip,bgs'
VRO_DEV_SECRETS_FOLDER: "${{ github.workspace }}/.cache/abd-vro-dev-secrets"

jobs:
Expand Down Expand Up @@ -62,18 +62,6 @@ jobs:
# Quit after 60 seconds
retries: 30

# Temporary step added to avoid condition where bipApiExchange is not yet created.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer necessary as the integration tests declare the bipApiExchange

- name: 'Create bipApiExchange exchange'
uses: indiesdev/[email protected]
with:
url: 'http://localhost:15672/api/exchanges/%2f/bipApiExchange'
method: 'PUT'
basic-auth-token: '${{env.RABBITMQ_BASIC_AUTH}}'
body: '{"type":"direct", "durable":true, "auto_delete":true}'
accept: 201, 204
retries: 3
log-response: true

- name: "Run Employee Experience Integration Tests"
run: |
./gradlew :domain-ee:ee-ep-merge-app:integrationTest
Expand Down
20 changes: 15 additions & 5 deletions domain-ee/ee-ep-merge-app/integration/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import asyncio

import pytest
import pytest_asyncio
from integration.mq_endpoint import MqEndpoint
from src.python_src.config import QUEUES, REPLY_QUEUES, ClientName
from src.python_src.config import EXCHANGES, QUEUES, REPLY_QUEUES, ClientName


@pytest.fixture(autouse=True, scope="session")
Expand Down Expand Up @@ -29,22 +31,29 @@ def cancel_claim_endpoint():
return create_mq_endpoint(ClientName.CANCEL_CLAIM)


@pytest.fixture(autouse=True, scope="session")
def add_claim_note_endpoint():
return create_mq_endpoint(ClientName.BGS_ADD_CLAIM_NOTE)


def create_mq_endpoint(name):
return MqEndpoint(name, QUEUES[name], REPLY_QUEUES[name])
return MqEndpoint(name, EXCHANGES[name], QUEUES[name], REPLY_QUEUES[name])


@pytest_asyncio.fixture(autouse=True, scope="session")
async def endpoint_lifecycle(event_loop,
get_claim_endpoint: MqEndpoint,
async def endpoint_lifecycle(get_claim_endpoint: MqEndpoint,
get_claim_contentions_endpoint: MqEndpoint,
put_tsoj_endpoint: MqEndpoint,
create_claim_contentions_endpoint: MqEndpoint,
cancel_claim_endpoint: MqEndpoint):
cancel_claim_endpoint: MqEndpoint,
add_claim_note_endpoint: MqEndpoint):
event_loop = asyncio.get_running_loop()
await get_claim_endpoint.start(event_loop)
await get_claim_contentions_endpoint.start(event_loop)
await put_tsoj_endpoint.start(event_loop)
await create_claim_contentions_endpoint.start(event_loop)
await cancel_claim_endpoint.start(event_loop)
await add_claim_note_endpoint.start(event_loop)

yield

Expand All @@ -53,3 +62,4 @@ async def endpoint_lifecycle(event_loop,
put_tsoj_endpoint.stop()
create_claim_contentions_endpoint.stop()
cancel_claim_endpoint.stop()
add_claim_note_endpoint.stop()
8 changes: 3 additions & 5 deletions domain-ee/ee-ep-merge-app/integration/mq_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@
from hoppy import async_consumer, async_publisher
from hoppy.hoppy_properties import ExchangeProperties, QueueProperties
from pika import BasicProperties
from src.python_src.config import EXCHANGE

exchange_props = ExchangeProperties(name=EXCHANGE)


class MqEndpoint:

def __init__(self, name, req_queue, response_queue):
def __init__(self, name, exchange, req_queue, response_queue):
self.name = name
self.index = 0
self.auto_response_files = []

queue_props = QueueProperties(name=req_queue, passive_declare=False)
exchange_props = ExchangeProperties(name=exchange, auto_delete=True, passive_declare=False)
queue_props = QueueProperties(name=req_queue, auto_delete=True, passive_declare=False)
self.consumer = async_consumer.AsyncConsumer(exchange_properties=exchange_props,
queue_properties=queue_props,
routing_key=req_queue,
Expand Down
60 changes: 39 additions & 21 deletions domain-ee/ee-ep-merge-app/integration/test_merge_request.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import asyncio

import pytest
import pytest_asyncio
from httpx import AsyncClient
Expand All @@ -19,16 +17,6 @@
ep400_duplicate_contentions_200 = f'{RESPONSE_DIR}/claim_contentions_increase_tendinitis_200.json'


@pytest.fixture(scope="session")
def event_loop():
try:
loop = asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
yield loop
loop.close()


@pytest_asyncio.fixture(autouse=True, scope="session")
async def app_lifespan():
await on_start_up()
Expand Down Expand Up @@ -65,18 +53,20 @@ async def submit_request(self, client):
assert response_json['job']['state'] == JobState.PENDING.value
return response_json['job']['job_id']

@pytest.mark.asyncio
@pytest.mark.asyncio(scope="session")(scope="session")
async def test_completed_success(self,
get_claim_endpoint: MqEndpoint,
get_claim_contentions_endpoint: MqEndpoint,
put_tsoj_endpoint: MqEndpoint,
create_claim_contentions_endpoint: MqEndpoint,
cancel_claim_endpoint: MqEndpoint):
cancel_claim_endpoint: MqEndpoint,
add_claim_note_endpoint: MqEndpoint):
get_claim_endpoint.set_responses([pending_claim_200])
get_claim_contentions_endpoint.set_responses([pending_contentions_200, ep400_contentions_200])
put_tsoj_endpoint.set_responses([response_200])
create_claim_contentions_endpoint.set_responses([response_201])
cancel_claim_endpoint.set_responses([response_200])
add_claim_note_endpoint.set_responses([response_200])

async with AsyncClient(app=app, base_url="http://test") as client:
job_id = await self.submit_request(client)
Expand All @@ -90,7 +80,7 @@ async def test_completed_success(self,
assert response_json['job']['ep400_claim_id'] == self.ep400_claim_id
assert response_json['job']['state'] == JobState.COMPLETED_SUCCESS.value

@pytest.mark.asyncio
@pytest.mark.asyncio(scope="session")
async def test_completed_success_with_duplicate_contention(self,
get_claim_endpoint: MqEndpoint,
get_claim_contentions_endpoint: MqEndpoint,
Expand All @@ -113,7 +103,7 @@ async def test_completed_success_with_duplicate_contention(self,
assert response_json['job']['ep400_claim_id'] == self.ep400_claim_id
assert response_json['job']['state'] == JobState.COMPLETED_SUCCESS.value

@pytest.mark.asyncio
@pytest.mark.asyncio(scope="session")
async def test_completed_error_at_get_pending_claim(self,
get_claim_endpoint: MqEndpoint):
get_claim_endpoint.set_responses([response_500])
Expand All @@ -131,7 +121,7 @@ async def test_completed_error_at_get_pending_claim(self,
assert response_json['job']['state'] == JobState.COMPLETED_ERROR.value
assert response_json['job']['error_state'] == JobState.RUNNING_GET_PENDING_CLAIM.value

@pytest.mark.asyncio
@pytest.mark.asyncio(scope="session")
async def test_completed_error_at_get_pending_contentions(self,
get_claim_endpoint: MqEndpoint,
get_claim_contentions_endpoint: MqEndpoint):
Expand All @@ -151,7 +141,7 @@ async def test_completed_error_at_get_pending_contentions(self,
assert response_json['job']['state'] == JobState.COMPLETED_ERROR.value
assert response_json['job']['error_state'] == JobState.RUNNING_GET_PENDING_CLAIM_CONTENTIONS.value

@pytest.mark.asyncio
@pytest.mark.asyncio(scope="session")
async def test_completed_error_at_get_ep400_contentions(self,
get_claim_endpoint: MqEndpoint,
get_claim_contentions_endpoint: MqEndpoint):
Expand All @@ -171,7 +161,7 @@ async def test_completed_error_at_get_ep400_contentions(self,
assert response_json['job']['state'] == JobState.COMPLETED_ERROR.value
assert response_json['job']['error_state'] == JobState.RUNNING_GET_EP400_CLAIM_CONTENTIONS.value

@pytest.mark.asyncio
@pytest.mark.asyncio(scope="session")
async def test_completed_error_at_set_tsoj(self,
get_claim_endpoint: MqEndpoint,
get_claim_contentions_endpoint: MqEndpoint,
Expand All @@ -193,7 +183,7 @@ async def test_completed_error_at_set_tsoj(self,
assert response_json['job']['state'] == JobState.COMPLETED_ERROR.value
assert response_json['job']['error_state'] == JobState.RUNNING_SET_TEMP_STATION_OF_JURISDICTION.value

@pytest.mark.asyncio
@pytest.mark.asyncio(scope="session")
async def test_completed_error_at_create_claim_contentions(self,
get_claim_endpoint: MqEndpoint,
get_claim_contentions_endpoint: MqEndpoint,
Expand All @@ -217,7 +207,7 @@ async def test_completed_error_at_create_claim_contentions(self,
assert response_json['job']['state'] == JobState.COMPLETED_ERROR.value
assert response_json['job']['error_state'] == JobState.RUNNING_MOVE_CONTENTIONS_TO_PENDING_CLAIM.value

@pytest.mark.asyncio
@pytest.mark.asyncio(scope="session")
async def test_completed_error_at_cancel_claim(self,
get_claim_endpoint: MqEndpoint,
get_claim_contentions_endpoint: MqEndpoint,
Expand All @@ -242,3 +232,31 @@ async def test_completed_error_at_cancel_claim(self,
assert response_json['job']['ep400_claim_id'] == self.ep400_claim_id
assert response_json['job']['state'] == JobState.COMPLETED_ERROR.value
assert response_json['job']['error_state'] == JobState.RUNNING_CANCEL_EP400_CLAIM.value

@pytest.mark.asyncio(scope="session")
async def test_completed_error_at_add_claim_note(self,
get_claim_endpoint: MqEndpoint,
get_claim_contentions_endpoint: MqEndpoint,
put_tsoj_endpoint: MqEndpoint,
create_claim_contentions_endpoint: MqEndpoint,
cancel_claim_endpoint: MqEndpoint,
add_claim_note_endpoint: MqEndpoint):
get_claim_endpoint.set_responses([pending_claim_200])
get_claim_contentions_endpoint.set_responses([pending_contentions_200, ep400_contentions_200])
put_tsoj_endpoint.set_responses([response_200])
create_claim_contentions_endpoint.set_responses([response_201])
cancel_claim_endpoint.set_responses([response_200])
add_claim_note_endpoint.set_responses([response_500])

async with AsyncClient(app=app, base_url="http://test") as client:
job_id = await self.submit_request(client)

response = await client.get(url=f"/merge/{job_id}")
assert response.status_code == 200

response_json = response.json()
assert response_json is not None
assert response_json['job']['pending_claim_id'] == self.pending_claim_id
assert response_json['job']['ep400_claim_id'] == self.ep400_claim_id
assert response_json['job']['state'] == JobState.COMPLETED_ERROR.value
assert response_json['job']['error_state'] == JobState.RUNNING_ADD_CLAIM_NOTE_TO_EP400.value
17 changes: 16 additions & 1 deletion domain-ee/ee-ep-merge-app/src/python_src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,20 @@ class ClientName(str, Enum):
PUT_TSOJ = "putTemporaryStationOfJurisdictionClient"
CREATE_CLAIM_CONTENTIONS = "createClaimContentionsClient"
CANCEL_CLAIM = "cancelClaimClient"
BGS_ADD_CLAIM_NOTE = "addClaimNoteClient"


EXCHANGE = "bipApiExchange"
BIP_EXCHANGE = "bipApiExchange"
BGS_EXCHANGE = "bgs-api"

EXCHANGES = {
ClientName.GET_CLAIM: os.environ.get("BIP_API_EXCHANGE") or BIP_EXCHANGE,
ClientName.GET_CLAIM_CONTENTIONS: os.environ.get("BIP_API_EXCHANGE") or BIP_EXCHANGE,
ClientName.PUT_TSOJ: os.environ.get("BIP_API_EXCHANGE") or BIP_EXCHANGE,
ClientName.CREATE_CLAIM_CONTENTIONS: os.environ.get("BIP_API_EXCHANGE") or BIP_EXCHANGE,
ClientName.CANCEL_CLAIM: os.environ.get("BIP_API_EXCHANGE") or BIP_EXCHANGE,
ClientName.BGS_ADD_CLAIM_NOTE: os.environ.get("BGS_API_EXCHANGE") or BGS_EXCHANGE,
}

QUEUES = {
ClientName.GET_CLAIM:
Expand All @@ -39,6 +50,8 @@ class ClientName(str, Enum):
os.environ.get("CREATE_CLAIM_CONTENTIONS_REQUEST") or "createClaimContentionsQueue",
ClientName.CANCEL_CLAIM:
os.environ.get("CANCEL_CLAIM_REQUEST") or "cancelClaimQueue",
ClientName.BGS_ADD_CLAIM_NOTE:
os.environ.get("ADD_CLAIM_NOTE_REQUEST") or "add-note",
}

REPLY_QUEUES = {
Expand All @@ -52,4 +65,6 @@ class ClientName(str, Enum):
os.environ.get("CREATE_CLAIM_CONTENTIONS_RESPONSE") or "createClaimContentionsResponseQueue",
ClientName.CANCEL_CLAIM:
os.environ.get("CANCEL_CLAIM_RESPONSE") or "cancelClaimResponseQueue",
ClientName.BGS_ADD_CLAIM_NOTE:
os.environ.get("ADD_CLAIM_NOTE_RESPONSE") or "add-note-response",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it too late to switch these to camel-case? 😅

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from pydantic import ConfigDict
from pydantic.alias_generators import to_camel

from .request import GeneralRequest
from .response import GeneralResponse


class Request(GeneralRequest):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)

vbms_claim_id: int
claim_notes: list[str]


class Response(GeneralResponse):
pass
7 changes: 4 additions & 3 deletions domain-ee/ee-ep-merge-app/src/python_src/model/merge_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class JobState(str, Enum):
RUNNING_MERGE_CONTENTIONS = 'RUNNING_MERGE_CONTENTIONS'
RUNNING_MOVE_CONTENTIONS_TO_PENDING_CLAIM = 'RUNNING_MOVE_CONTENTIONS_TO_PENDING_CLAIM'
RUNNING_CANCEL_EP400_CLAIM = 'RUNNING_CANCEL_EP400_CLAIM'
RUNNING_ADD_CLAIM_NOTE_TO_EP400 = 'RUNNING_ADD_CLAIM_NOTE_TO_EP400'
COMPLETED_SUCCESS = 'COMPLETED_SUCCESS'


Expand All @@ -26,9 +27,9 @@ class MergeJob(BaseModel):
error_state: JobState | None = None
messages: list[Any] | None = None

def error(self, current_state, message):
self.error_state = current_state
def error(self, messages):
self.error_state = self.state
self.state = JobState.COMPLETED_ERROR
if self.messages is None:
self.messages = []
self.messages.append(message)
self.messages.extend(messages)
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@
import logging
from typing import Type

from fastapi.encoders import jsonable_encoder
from hoppy.exception import ResponseException
from model import cancel_claim, create_contentions, get_claim, get_contentions
from model import (
add_claim_note,
cancel_claim,
create_contentions,
get_claim,
get_contentions,
)
from model import update_temp_station_of_jurisdiction as tsoj
from model.merge_job import JobState, MergeJob
from model.request import GeneralRequest
Expand All @@ -30,6 +37,7 @@ class EpMergeMachine(StateMachine):
running_merge_contentions = State(value=JobState.RUNNING_MERGE_CONTENTIONS)
running_move_contentions_to_pending_claim = State(value=JobState.RUNNING_MOVE_CONTENTIONS_TO_PENDING_CLAIM)
running_cancel_ep400_claim = State(value=JobState.RUNNING_CANCEL_EP400_CLAIM)
running_add_claim_note_to_ep400 = State(value=JobState.RUNNING_ADD_CLAIM_NOTE_TO_EP400)
completed_success = State(final=True, value=JobState.COMPLETED_SUCCESS)
completed_error = State(final=True, value=JobState.COMPLETED_ERROR)

Expand All @@ -48,8 +56,10 @@ class EpMergeMachine(StateMachine):
| running_merge_contentions.to(completed_error, cond="has_error")
| running_move_contentions_to_pending_claim.to(running_cancel_ep400_claim, unless="has_error")
| running_move_contentions_to_pending_claim.to(completed_error, cond="has_error")
| running_cancel_ep400_claim.to(completed_success, unless="has_error")
| running_cancel_ep400_claim.to(running_add_claim_note_to_ep400, unless="has_error")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the plan was to add a claim note when merging failed, not on success?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. The plan is to add a claim note as part of the happy path. See #2161. The claim note is being added after the claim is cancelled that way the cancellation reason for the claim will show in VBMS. 👍

| running_cancel_ep400_claim.to(completed_error, cond="has_error")
| running_add_claim_note_to_ep400.to(completed_success, unless="has_error")
| running_add_claim_note_to_ep400.to(completed_error, cond="has_error")
)

def __init__(self, merge_job: MergeJob):
Expand Down Expand Up @@ -138,6 +148,16 @@ def on_cancel_ep400_claim(self):
response_type=cancel_claim.Response)
self.process()

@running_add_claim_note_to_ep400.enter
def on_add_claim_note_to_ep400(self):
request = add_claim_note.Request(vbms_claim_id=self.job.ep400_claim_id,
claim_notes=[self.cancellation_reason])
self.make_request(
request=request,
hoppy_client=HOPPY.get_client(ClientName.BGS_ADD_CLAIM_NOTE),
response_type=add_claim_note.Response)
self.process()

@completed_success.enter
@completed_error.enter
def on_completed(self, state):
Expand Down Expand Up @@ -180,5 +200,5 @@ def log_error(self, error):
f"pending_claim_id={self.job.pending_claim_id} "
f"ep400_claim_id={self.job.ep400_claim_id} "
f"state={self.job.state} "
f"error=\'{error}\'")
self.job.error(self.job.state, error)
f"error=\"{jsonable_encoder(error)}\"")
self.job.error(error if isinstance(error, list) else [error])
Loading