Skip to content

Commit

Permalink
Add cancellation as claim note through VRO's svc-bgs-api (#2315)
Browse files Browse the repository at this point in the history
* Add cancellation as claim note through VRO's svc-bgs-api. Updated integration tests to create the required exchanges along with the queues. 
* fixed issues with event_loop deprecation message.
  • Loading branch information
dfitchett authored Dec 12, 2023
1 parent 5a573e9 commit 21c7f20
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 63 deletions.
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.
- 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",
}
16 changes: 16 additions & 0 deletions domain-ee/ee-ep-merge-app/src/python_src/model/add_claim_note.py
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")
| 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

0 comments on commit 21c7f20

Please sign in to comment.