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

Limit hourlies endpoint to only store ffmc files #3563

Merged
merged 3 commits into from
Apr 25, 2024
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
4 changes: 4 additions & 0 deletions api/app/auto_spatial_advisory/sfms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ def is_hfi_file(filename: str) -> bool:
"Returns true if filename starts with 'hfi'"
return filename.startswith("hfi")

def is_ffmc_file(filename: str) -> bool:
"Returns true if filename starts with 'fine_fuel_moisture_code'"
return filename.startswith("fine_fuel_moisture_code")

def get_date_part(filename: str) -> str:
""" Get the date part of the filename.
Filename example: hfi20220823.tif
Expand Down
28 changes: 15 additions & 13 deletions api/app/routers/sfms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from app.nats_publish import publish
from app.utils.s3 import get_client
from app import config
from app.auto_spatial_advisory.sfms import get_hourly_filename, get_sfms_file_message, get_target_filename, get_date_part, is_hfi_file
from app.auto_spatial_advisory.sfms import get_hourly_filename, get_sfms_file_message, get_target_filename, get_date_part, is_ffmc_file, is_hfi_file
from app.auto_spatial_advisory.nats_config import stream_name, subjects, sfms_file_subject
from app.schemas.auto_spatial_advisory import ManualSFMS, SFMSFile

Expand Down Expand Up @@ -126,18 +126,20 @@ async def upload_hourlies(file: UploadFile,
```
"""
logger.info('sfms/upload/hourlies')
# Get an async S3 client.
async with get_client() as (client, bucket):
# We save the Last-modified and Create-time as metadata in the object store - just
# in case we need to know about it in the future.
key = get_hourly_filename(file.filename)
logger.info('Uploading file "%s" to "%s"', file.filename, key)
meta_data = get_meta_data(request)
await client.put_object(Bucket=bucket,
Key=key,
Body=FileLikeObject(file.file),
Metadata=meta_data)
logger.info('Done uploading file')

if is_ffmc_file(file.filename):
# Get an async S3 client.
async with get_client() as (client, bucket):
# We save the Last-modified and Create-time as metadata in the object store - just
# in case we need to know about it in the future.
key = get_hourly_filename(file.filename)
logger.info('Uploading file "%s" to "%s"', file.filename, key)
meta_data = get_meta_data(request)
await client.put_object(Bucket=bucket,
Key=key,
Body=FileLikeObject(file.file),
Metadata=meta_data)
logger.info('Done uploading file')
return Response(status_code=200)


Expand Down
10 changes: 9 additions & 1 deletion api/app/tests/sfms/test_sfms.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from app.auto_spatial_advisory.sfms import is_hfi_file
from app.auto_spatial_advisory.sfms import is_hfi_file, is_ffmc_file


def test_is_hfi_file():
Expand All @@ -7,3 +7,11 @@ def test_is_hfi_file():

def test_is_not_hfi_file():
assert is_hfi_file('at20220824.tiff') is False


def test_is_ffmc_file():
assert is_ffmc_file('fine_fuel_moisture_code20220824.tiff') is True


def test_is_not_ffmc_file():
assert is_ffmc_file('hfi20220824.tiff') is False
27 changes: 26 additions & 1 deletion api/app/tests/sfms/test_sfms_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ async def _mock_get_client_for_router():
mock_get_client.return_value = _mock_get_client_for_router()
client = TestClient(app)
response = client.post(HOURLY_FFMC_URL,
files={'file': ('hfi20220904.tiff', b'')},
files={'file': ('fine_fuel_moisture_code20220904.tiff', b'')},
headers={
'Secret': config.get('SFMS_SECRET'),
'Last-modified': datetime.now().isoformat(),
Expand All @@ -221,4 +221,29 @@ async def _mock_get_client_for_router():
# We should have called put_object once.
assert mock_s3_client.put_object.called
# We should not publish hourly ffmc
assert mock_publish.called == False

@patch('app.routers.sfms.get_client')
@patch('app.routers.sfms.publish')
def test_hourly_ffmc_endpoint_non_ffmc_file(mock_publish: AsyncMock, mock_get_client: AsyncMock):
""" Verify we don't store other files besides ffmc files """
mock_s3_client = AsyncMock()

@asynccontextmanager
async def _mock_get_client_for_router():
yield mock_s3_client, 'some_bucket'

mock_get_client.return_value = _mock_get_client_for_router()
client = TestClient(app)
response = client.post(HOURLY_FFMC_URL,
files={'file': ('hfi20220904.tiff', b'')},
headers={
'Secret': config.get('SFMS_SECRET'),
'Last-modified': datetime.now().isoformat(),
'Create-time': datetime.now().isoformat()})
# We should get a 200 response if the file is received
assert response.status_code == 200
# We should not upload the file
assert mock_s3_client.put_object.called == False
# We should not publish hourly ffmc
assert mock_publish.called == False
Loading