Skip to content
This repository was archived by the owner on Jul 11, 2025. It is now read-only.

Commit a37e64e

Browse files
authored
Merge pull request #74 from open-AIMS/feat/minio-dropin
2 parents 606c315 + 031e10b commit a37e64e

File tree

10 files changed

+137
-24
lines changed

10 files changed

+137
-24
lines changed

.env.dist

Lines changed: 0 additions & 9 deletions
This file was deleted.

.env.local

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Local web-api
2+
API_ENDPOINT=http://localhost:5000
3+
AWS_REGION=ap-southeast-2
4+
JOB_TYPES=SUITABILITY_ASSESSMENT,REGIONAL_ASSESSMENT,TEST
5+
WORKER_USERNAME=worker@email.com
6+
WORKER_PASSWORD=password
7+
JULIA_DEBUG=ReefGuideAPI
8+
CONFIG_PATH=config.toml
9+
10+
# Minio (local)
11+
S3_ENDPOINT=http://localhost:9000
12+
MINIO_USERNAME=minioadmin
13+
MINIO_PASSWORD=minioadmin

Manifest-v1.11.toml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
julia_version = "1.11.5"
44
manifest_format = "2.0"
5-
project_hash = "6fb79bd8da16ed2240c62044e56e825aaaef4a46"
5+
project_hash = "3d5a0b33a7af4f2946e13fad2322181d045cdacf"
66

77
[[deps.ADTypes]]
88
git-tree-sha1 = "e2478490447631aedba0823d4d7a80b2cc8cdb32"
@@ -1614,6 +1614,12 @@ git-tree-sha1 = "bc95bf4149bf535c09602e3acdf950d9b4376227"
16141614
uuid = "9237b28f-5490-5468-be7b-bb81f5f5e6cf"
16151615
version = "10.1.4+3"
16161616

1617+
[[deps.Minio]]
1618+
deps = ["AWS", "AWSS3", "FilePathsBase", "Pkg", "URIs", "minio_jll"]
1619+
git-tree-sha1 = "ab0cf8db62040e835197b4e9416ab34baa89b693"
1620+
uuid = "4281f0d9-7ae0-406e-9172-b7277c1efa20"
1621+
version = "0.2.2"
1622+
16171623
[[deps.Missings]]
16181624
deps = ["DataAPI"]
16191625
git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d"
@@ -2677,6 +2683,12 @@ git-tree-sha1 = "86addc139bca85fdf9e7741e10977c45785727b7"
26772683
uuid = "337d8026-41b4-5cde-a456-74a10e5b31d1"
26782684
version = "1.11.3+0"
26792685

2686+
[[deps.minio_jll]]
2687+
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
2688+
git-tree-sha1 = "59287c60d58776bbdecef63f8fda50ff345bb4dd"
2689+
uuid = "ad83bbfc-c153-533a-bb97-700a7db721e0"
2690+
version = "1.0.0+1"
2691+
26802692
[[deps.nghttp2_jll]]
26812693
deps = ["Artifacts", "Libdl"]
26822694
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
3535
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
3636
MKL_jll = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
3737
Memoization = "6fafb56a-5788-4b4e-91ca-c0cea6611c73"
38+
Minio = "4281f0d9-7ae0-406e-9172-b7277c1efa20"
3839
Mmap = "a63ad114-7e13-5084-954f-fe012c677804"
3940
NearestNeighbors = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
4041
NetCDF = "30363a11-5582-574a-97bb-aa9a979735b9"
@@ -63,6 +64,7 @@ ExtendableSparse = "1.7.1"
6364
JSON3 = "1.14.2"
6465
Logging = "1.11.0"
6566
MKL_jll = "2024.2.0"
67+
Minio = "0.2.2"
6668
NearestNeighbors = "0.4.20"
6769
Oxygen = "1.7.1"
6870
Random = "1.11.0"

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,65 @@ using ReefGuideAPI
3535
ReefGuideAPI.start_server(".config.toml")
3636
```
3737

38+
## Running the worker
39+
40+
### Local quick start
41+
42+
Ensure your local stack of [reefguide](https://github.com/open-AIMS/reefguide) is running. You can then do the below:
43+
44+
Setup env file:
45+
46+
```
47+
cp .env.local .env
48+
```
49+
50+
Then run the worker
51+
52+
```julia
53+
] add DotEnv
54+
using DotEnv
55+
DotEnv.load!()
56+
using ReefGuideAPI
57+
ReefGuideAPI.start_worker()
58+
```
59+
60+
### Env examples
61+
62+
The example below points to a local setup.
63+
64+
```
65+
API_ENDPOINT=http://localhost:5000
66+
AWS_REGION=ap-southeast-2
67+
JOB_TYPES=SUITABILITY_ASSESSMENT,REGIONAL_ASSESSMENT,TEST
68+
WORKER_USERNAME=worker@email.com
69+
WORKER_PASSWORD=password
70+
JULIA_DEBUG=ReefGuideAPI
71+
CONFIG_PATH=config.toml
72+
AWS_ACCESS_KEY_ID=minioadmin
73+
AWS_SECRET_ACCESS_KEY=minioadmin
74+
75+
# For minio dropin
76+
S3_ENDPOINT=http://localhost:9000
77+
MINIO_USERNAME=minioadmin
78+
MINIO_PASSWORD=minioadmin
79+
```
80+
81+
### Running against a real deployment
82+
83+
Typically you would deploy a production worker using a separate process to manage the env variables. But the below shows an example .env file (noting we do not include the minio dropin)
84+
85+
```
86+
API_ENDPOINT='https://web-api.reefguide.example.com'
87+
AWS_REGION='ap-southeast-2'
88+
JOB_TYPES=SUITABILITY_ASSESSMENT,TEST
89+
WORKER_USERNAME=worker@service.com
90+
WORKER_PASSWORD=<password>
91+
POLL_INTERVAL_MS=5000
92+
IDLE_TIMEOUT_MS=600000
93+
JULIA_DEBUG=ReefGuideAPI
94+
CONFIG_PATH=config.toml
95+
```
96+
3897
### Using Docker
3998

4099
```bash

src/job_worker/config.jl

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ struct WorkerConfig
2222
config_path::String
2323
"AWS Region"
2424
aws_region::String
25+
"S3 Endpoint for local S3 compatibility"
26+
s3_endpoint::OptionalValue{String}
2527

2628
# Kwarg constructor
2729
function WorkerConfig(;
@@ -34,7 +36,8 @@ struct WorkerConfig
3436
# Polling interval 2 second by default
3537
poll_interval_ms::Int64=2000,
3638
# Idle timeout 5 minutes by default
37-
idle_timeout_ms::Int64=5 * 60 * 1000
39+
idle_timeout_ms::Int64=5 * 60 * 1000,
40+
s3_endpoint::OptionalValue{String}=nothing
3841
)
3942
return new(
4043
api_endpoint,
@@ -44,7 +47,8 @@ struct WorkerConfig
4447
poll_interval_ms,
4548
idle_timeout_ms,
4649
config_path,
47-
aws_region
50+
aws_region,
51+
s3_endpoint
4852
)
4953
end
5054
end
@@ -149,6 +153,9 @@ function load_config_from_env()::WorkerConfig
149153
@warn "AWS_REGION environment variable not set, defaulting to $(aws_region)"
150154
end
151155

156+
# Get S3 endpoint
157+
s3_endpoint = get_env("S3_ENDPOINT", false)
158+
152159
# Optional environment variables with defaults (2 seconds)
153160
poll_interval_ms::Int64 = parse(
154161
Int64, something(get_env("POLL_INTERVAL_MS", false), string(2 * 1000))
@@ -167,7 +174,8 @@ function load_config_from_env()::WorkerConfig
167174
poll_interval_ms,
168175
idle_timeout_ms,
169176
config_path,
170-
aws_region
177+
aws_region,
178+
s3_endpoint
171179
)
172180
end
173181

src/job_worker/handlers.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,12 @@ struct HandlerContext
5353
"The path to the config file"
5454
config_path::String
5555
aws_region::String
56+
s3_endpoint::OptionalValue{String}
5657

5758
function HandlerContext(;
58-
storage_uri::String, config_path::String, aws_region::String="ap-southeast-2"
59+
storage_uri::String, config_path::String, aws_region::String="ap-southeast-2", s3_endpoint::OptionalValue{String}=nothing
5960
)
60-
return new(storage_uri, config_path, aws_region)
61+
return new(storage_uri, config_path, aws_region, s3_endpoint)
6162
end
6263
end
6364

@@ -308,7 +309,7 @@ function handle_job(
308309
end
309310

310311
# Now upload this to s3
311-
client = S3StorageClient(; region=context.aws_region)
312+
client = S3StorageClient(; region=context.aws_region, s3_endpoint=context.s3_endpoint)
312313

313314
# Output file names
314315
output_file_name_rel = "regional_assessment.tiff"
@@ -415,7 +416,7 @@ function handle_job(
415416
end
416417

417418
# Now upload this to s3
418-
client = S3StorageClient(; region=context.aws_region)
419+
client = S3StorageClient(; region=context.aws_region, s3_endpoint=context.s3_endpoint)
419420

420421
# Output file names
421422
output_file_name_rel = "suitable.geojson"

src/job_worker/job_worker.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ using AWSS3
66
using AWS
77
using Random
88
using JSONWebTokens
9+
using Minio
910

1011
include("config.jl")
1112
include("ecs.jl")

src/job_worker/storage_client.jl

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@ S3 Storage Client implementation
3232
"""
3333
struct S3StorageClient <: StorageClient
3434
region::String
35+
s3_endpoint::OptionalValue{String}
3536

3637
# Constructor with defaults
3738
function S3StorageClient(;
38-
region::String
39+
region::String,
40+
s3_endpoint::OptionalValue{String}=nothing
3941
)
40-
return new(region)
42+
return new(region, s3_endpoint)
4143
end
4244
end
4345

@@ -59,7 +61,17 @@ function upload_file(
5961

6062
@debug "Uploading file from $(local_path) to $(storage_path)"
6163

62-
aws = AWS.AWSConfig(; region=client.region)
64+
aws =
65+
!isnothing(client.s3_endpoint) ?
66+
# Use minio special config if we need to
67+
Minio.MinioConfig(
68+
client.s3_endpoint;
69+
# TODO would be nicer to pass through config tree
70+
username=ENV["MINIO_USERNAME"],
71+
password=ENV["MINIO_PASSWORD"]
72+
) :
73+
# Otherwise use typical AWS config
74+
AWS.AWSConfig(; region=client.region)
6375

6476
# Read the file content
6577
file_data = Base.read(local_path)

src/job_worker/worker.jl

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,28 @@ struct JobContext
5151
config_path::String
5252
"AWS region for s3 storage"
5353
aws_region::String
54+
"S3 endpoint"
55+
s3_endpoint::OptionalValue{String}
56+
5457
"Constructor that takes all fields"
5558
function JobContext(;
5659
job::Job,
5760
assignment::JobAssignment,
5861
http_client::AuthApiClient,
5962
task_metadata::Any,
6063
config_path::String,
61-
aws_region::String="ap-southeast-2"
64+
aws_region::String="ap-southeast-2",
65+
s3_endpoint::OptionalValue{String}=nothing
6266
)
63-
return new(job, assignment, http_client, task_metadata, config_path, aws_region)
67+
return new(
68+
job,
69+
assignment,
70+
http_client,
71+
task_metadata,
72+
config_path,
73+
aws_region,
74+
s3_endpoint
75+
)
6476
end
6577
end
6678

@@ -115,7 +127,8 @@ function process(::TypedJobHandler, context::JobContext)
115127
HandlerContext(;
116128
storage_uri=storage_uri,
117129
config_path=context.config_path,
118-
aws_region=context.aws_region
130+
aws_region=context.aws_region,
131+
s3_endpoint=context.s3_endpoint
119132
)
120133
)
121134

@@ -388,7 +401,8 @@ function process_job_completely(worker::WorkerService, job::Job)
388401
http_client=worker.http_client,
389402
task_metadata=worker.metadata,
390403
config_path=worker.config.config_path,
391-
aws_region=worker.config.aws_region
404+
aws_region=worker.config.aws_region,
405+
s3_endpoint=worker.config.s3_endpoint
392406
)
393407

394408
# Process the job with the handler

0 commit comments

Comments
 (0)