This is an automated email from the ASF dual-hosted git repository. lahirujayathilake pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/airavata-custos.git
commit b93b7dc3f2c38196f0b56a479c351f05b1cf3792 Author: lahiruj <[email protected]> AuthorDate: Tue May 5 02:16:43 2026 -0400 support extracting the correct user role and included dev_email in the AMIE test packets --- allocations/access-amie/README.md | 8 +++ allocations/access-amie/handler/handler.go | 15 ++++ .../access-amie/handler/request_account_create.go | 6 +- allocations/devtools/amie/README.md | 14 ++++ allocations/devtools/amie/mock-amie-server.py | 81 ++++++++++++++++++++++ 5 files changed, 121 insertions(+), 3 deletions(-) diff --git a/allocations/access-amie/README.md b/allocations/access-amie/README.md index 890d6589a..b754b93e0 100644 --- a/allocations/access-amie/README.md +++ b/allocations/access-amie/README.md @@ -28,6 +28,14 @@ export AMIE_API_KEY="your-api-key" The default `config.yaml` works for local development with the Docker Compose MariaDB defaults. +For local dev without a real ACCESS endpoint, point the service at the local mock AMIE server in [`devtools/amie/`](../devtools/amie/README.md) + +```bash +export AMIE_BASE_URL="http://localhost:8180" +export AMIE_SITE_CODE="TESTSITE" +export AMIE_API_KEY="dev" +``` + ### 3. Build ```bash diff --git a/allocations/access-amie/handler/handler.go b/allocations/access-amie/handler/handler.go index 0bc946fae..70e7adac0 100644 --- a/allocations/access-amie/handler/handler.go +++ b/allocations/access-amie/handler/handler.go @@ -59,6 +59,21 @@ func getBody(packetJSON map[string]any) (map[string]any, error) { return body, nil } +var roleNormalizer = strings.NewReplacer(" ", "", "-", "", "_", "") + +func normalizeRole(raw string) string { + switch strings.ToUpper(roleNormalizer.Replace(raw)) { + case "PI": + return "PI" + case "COPI": + return "CO_PI" + case "ALLOCATIONMANAGER": + return "ALLOCATION_MANAGER" + default: + return "USER" + } +} + func getResourceList(body map[string]any) []string { v, ok := body["ResourceList"] if !ok { diff --git a/allocations/access-amie/handler/request_account_create.go b/allocations/access-amie/handler/request_account_create.go index dc16fcab2..487b5b333 100644 --- a/allocations/access-amie/handler/request_account_create.go +++ b/allocations/access-amie/handler/request_account_create.go @@ -124,9 +124,9 @@ func (h *RequestAccountCreateHandler) Handle(ctx context.Context, tx *sql.Tx, pa return fmt.Errorf("request_account_create: creating/finding project: %w", err) } - // Create USER membership. - if _, err := h.membershipSvc.CreateMembership(ctx, tx, projectID, account.ID, "USER"); err != nil { - return fmt.Errorf("request_account_create: creating USER membership: %w", err) + role := normalizeRole(getString(body, "UserRole")) + if _, err := h.membershipSvc.CreateMembership(ctx, tx, projectID, account.ID, role); err != nil { + return fmt.Errorf("request_account_create: creating %s membership: %w", role, err) } if err := h.auditSvc.Log(ctx, tx, packet.ID, eventID, model.AuditCreateMembership, "membership", "", ""); err != nil { return fmt.Errorf("request_account_create: audit CREATE_MEMBERSHIP: %w", err) diff --git a/allocations/devtools/amie/README.md b/allocations/devtools/amie/README.md index 9c61c89d1..98ec62ca8 100644 --- a/allocations/devtools/amie/README.md +++ b/allocations/devtools/amie/README.md @@ -25,10 +25,24 @@ curl -X POST 'http://localhost:8180/test/TESTSITE/scenarios?type=failures_only' # heavy batch curl -X POST 'http://localhost:8180/test/TESTSITE/scenarios?type=heavy' + +# dev email across multiple projects with different roles (requires DEV_EMAIL) +curl -X POST 'http://localhost:8180/test/TESTSITE/scenarios?type=dev_email' ``` Point `access-amie` at it with `AMIE_BASE_URL=http://localhost:8180`. +### `dev_email` scenario + +Run the `dev_email` scenario to generate AMIE packets placing DEV_EMAIL in multiple projects with different roles. + +```bash [email protected] python3 mock-amie-server.py +curl -X POST 'http://localhost:8180/test/TESTSITE/scenarios?type=dev_email' +``` + +Today the access-amie handlers persist PI and USER memberships only; Co-PI and Allocation Manager positions require handler enhancement to read a role field from the AMIE packet. + ## Load test (k6) Install k6, then run it. If you're hitting the local server, start that one first: diff --git a/allocations/devtools/amie/mock-amie-server.py b/allocations/devtools/amie/mock-amie-server.py index 0bd32f7c7..38f509d7e 100644 --- a/allocations/devtools/amie/mock-amie-server.py +++ b/allocations/devtools/amie/mock-amie-server.py @@ -27,6 +27,7 @@ # Then point the service at: access.amie.base-url=http://localhost:8180 import json +import os import random import time import uuid @@ -42,6 +43,8 @@ stats = {"created": 0, "fetched": 0, "replied": 0} SCENARIOS_DIR = Path(__file__).parent / "scenarios" +DEV_EMAIL = os.getenv("DEV_EMAIL", "").strip() + def next_id(): global packet_counter @@ -208,6 +211,76 @@ def gen_empty_body(): return make_packet("request_project_create", {}) +DEV_USER_GID = "100001" + +DEV_MEMBER_PROJECTS = [ + ("DEV-PROJ-002", "Climate Modeling Group", "Alice", "Smith", "[email protected]", "100002", "CoPI"), + ("DEV-PROJ-003", "Particle Physics Sim", "Bob", "Johnson", "[email protected]", "100003", "Allocation Manager"), + ("DEV-PROJ-004", "Genomics Pipeline", "Carol", "Williams", "[email protected]", "100004", "User"), +] + + +def gen_dev_email_scenario(): + if not DEV_EMAIL: + app.logger.warning("DEV_EMAIL is not set; dev_email scenario emits no packets") + return [] + + packets = [] + + packets.append(make_packet("request_project_create", { + "GrantNumber": "DEV-PROJ-001", + "PfosNumber": "PFOS-DEV-PROJ-001", + "ProjectTitle": "Dev's Own Project", + "PiGlobalID": DEV_USER_GID, + "PiFirstName": "Dev", + "PiLastName": "User", + "PiEmail": DEV_EMAIL, + "PiOrganization": "Dev Lab", + "PiOrgCode": "DEV", + "NsfStatusCode": "AC", + "PiDnList": ["/C=US/O=Dev Lab/CN=Dev User"], + "ServiceUnitsAllocated": "100000", + "StartDate": "2026-01-01", + "EndDate": "2026-12-31", + "ResourceList": "mock-cluster.example.edu", + })) + + for grant, title, pi_first, pi_last, pi_email, pi_gid, dev_role in DEV_MEMBER_PROJECTS: + packets.append(make_packet("request_project_create", { + "GrantNumber": grant, + "PfosNumber": f"PFOS-{grant}", + "ProjectTitle": title, + "PiGlobalID": pi_gid, + "PiFirstName": pi_first, + "PiLastName": pi_last, + "PiEmail": pi_email, + "PiOrganization": "Bogus Lab", + "PiOrgCode": "BOGUS", + "NsfStatusCode": "AC", + "PiDnList": [f"/C=US/O=Bogus Lab/CN={pi_first} {pi_last}"], + "ServiceUnitsAllocated": "50000", + "StartDate": "2026-01-01", + "EndDate": "2026-12-31", + "ResourceList": "mock-cluster.example.edu", + })) + packets.append(make_packet("request_account_create", { + "ProjectID": f"PRJ-{grant}", + "GrantNumber": grant, + "UserGlobalID": DEV_USER_GID, + "UserFirstName": "Dev", + "UserLastName": "User", + "UserEmail": DEV_EMAIL, + "UserOrganization": "Dev Lab", + "UserOrgCode": "DEV", + "NsfStatusCode": "AC", + "UserDnList": ["/C=US/O=Dev Lab/CN=Dev User"], + "UserRole": dev_role, + "ResourceList": "mock-cluster.example.edu", + })) + + return packets + + # Scenario mix SUCCESS_GENERATORS = [ @@ -303,6 +376,8 @@ def create_scenario(site): packets = generate_batch(success_count=8, failure_count=0) elif scenario_type == "heavy": packets = generate_batch(success_count=15, failure_count=10) + elif scenario_type == "dev_email": + packets = gen_dev_email_scenario() else: packets = generate_batch(success_count=3, failure_count=2) @@ -332,5 +407,11 @@ if __name__ == "__main__": print(" POST /test/{site}/scenarios?type=failures_only — 8 failures") print(" POST /test/{site}/scenarios?type=success_only — 8 successes") print(" POST /test/{site}/scenarios?type=heavy — 15 success + 10 failure") + print(" POST /test/{site}/scenarios?type=dev_email — scripted set placing DEV_EMAIL across projects") + print("") + if DEV_EMAIL: + print(f"DEV_EMAIL injection enabled: {DEV_EMAIL}") + else: + print("DEV_EMAIL is unset — set it (e.g. [email protected]) to use the dev_email scenario") print("") app.run(host="0.0.0.0", port=8180, debug=False)
