diff --git a/.gitea/workflows/ui_assets.yaml b/.gitea/workflows/ui_assets.yaml index 3c7f527..d4e1088 100644 --- a/.gitea/workflows/ui_assets.yaml +++ b/.gitea/workflows/ui_assets.yaml @@ -25,7 +25,7 @@ jobs: || echo "$MODIFIED_FILES" | grep -q ".gitea/workflows/ui_assets.yaml"; then echo "UI files have changed" - ./pkgs/ui/nix/update-ui-assets.sh + bash ./pkgs/ui/nix/update-ui-assets.sh # git push if we have a diff diff --git a/README.md b/README.md index c2c5987..5d285c8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# 1Service Aware Network Project Repo +# Service Aware Network Project Repo -Welcome to our website repository! This repo is designed to help you and your team build high-quality websites efficiently. We've carefully chosen the technologies to make development smooth and enjoyable. Here's what you can expect from this template: +Welcome to our website repository! This repo is designed to build high-quality websites efficiently. We've carefully chosen the technologies to make development smooth and enjoyable. **Frontend**: Our frontend is powered by [React NextJS](https://nextjs.org/), a popular and versatile framework for building web applications. @@ -26,6 +26,12 @@ Let's get your development environment up and running: curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install ``` +On Windows Subsystem for Linux (WSL) the installer will fail and tell you what to do. Execute the command from the error message and then afterwards execute: + +```bash +sudo echo "experimental-features = nix-command flakes" > '/etc/nix/nix.conf' +``` + 2. **Install direnv**: - Download the direnv package from [here](https://direnv.net/docs/installation.html) or run the following command: @@ -45,6 +51,7 @@ Let's get your development environment up and running: 4. **Clone the Repository and Navigate**: - Clone this repository and navigate to it. + - If you are under Windows Subystem For Linux (WSL) please clone the repository to the home folder of your Linux. Do NOT clone it onto your Windows machine! 5. **Allow .envrc**: @@ -66,9 +73,10 @@ Let's get your development environment up and running: - To start the backend server, execute: ```bash - clan webui --reload --no-open --log-level debug + clan webui --reload --no-open --log-level debug --populate ``` - The server will automatically restart if any Python files change. + - The `--populate` flag will automatically populate the database with dummy data 8. **Build the Frontend**: @@ -95,19 +103,19 @@ Let's set up your Git workflow to collaborate effectively: ```bash tea login add ``` + - Go to https://gitea.gchq.icu/user/settings/applications and create token with all privileges - Fill out the prompt as follows: - URL of Gitea instance: `https://gitea.gchq.icu` - Name of new Login [gitea.gchq.icu]: `gitea.gchq.icu:7171` - - Do you have an access token? No - - Username: YourUsername - - Password: YourPassword + - Do you have an access token? Yes + - Token: \***\*\*\*\*** - Set Optional settings: No 2. **Git Workflow**: 1. Add your changes to Git using `git add `. - 2. Run `nix fmt` to lint your files. - 3. Commit your changes with a descriptive message: `git commit -a -m "My descriptive commit message"`. + 2. Run `nix fmt` to lint your files. This will format your files and make changes! + 3. Commit your changes and those of nix fmt with a descriptive message: `git commit -a -m "My descriptive commit message"`. 4. Make sure your branch has the latest changes from upstream by executing: ```bash git fetch && git rebase origin/main --autostash @@ -188,8 +196,8 @@ If you need to inspect the Nix sandbox while running tests, follow these steps: 2. Use `cntr` and `psgrep` to attach to the Nix sandbox. This allows you to interactively debug your code while it's paused. For example: ```bash - cntr exec -w your_sandbox_name psgrep -a -x your_python_process_name + cntr attach ``` These debugging and testing methods will help you identify and fix issues in your backend code efficiently, ensuring the reliability and robustness of your application. diff --git a/pkgs/clan-cli/bin/clan b/pkgs/clan-cli/bin/clan old mode 100755 new mode 100644 diff --git a/pkgs/clan-cli/bin/clan-config b/pkgs/clan-cli/bin/clan-config old mode 100755 new mode 100644 diff --git a/pkgs/clan-cli/bin/gen-openapi b/pkgs/clan-cli/bin/gen-openapi old mode 100755 new mode 100644 diff --git a/pkgs/clan-cli/clan_cli/webui/__init__.py b/pkgs/clan-cli/clan_cli/webui/__init__.py index de2f5ae..1305e78 100644 --- a/pkgs/clan-cli/clan_cli/webui/__init__.py +++ b/pkgs/clan-cli/clan_cli/webui/__init__.py @@ -22,6 +22,12 @@ def register_parser(parser: argparse.ArgumentParser) -> None: parser.add_argument( "--host", type=str, default="localhost", help="Host to listen on" ) + parser.add_argument( + "--populate", + action="store_true", + help="Populate the database with dummy data", + default=False, + ) parser.add_argument( "--no-open", action="store_true", help="Don't open the browser", default=False ) diff --git a/pkgs/clan-cli/clan_cli/webui/app.py b/pkgs/clan-cli/clan_cli/webui/app.py index b5cb9b1..173cef8 100644 --- a/pkgs/clan-cli/clan_cli/webui/app.py +++ b/pkgs/clan-cli/clan_cli/webui/app.py @@ -35,10 +35,11 @@ def setup_app() -> FastAPI: # bind sql engine # TODO comment aut and add flag to run with pupulated data rm *.sql run pytest with marked then start clan webui # https://docs.pytest.org/en/7.1.x/example/markers.html - sql_models.Base.metadata.drop_all(engine) + # sql_models.Base.metadata.drop_all(engine) + sql_models.Base.metadata.create_all(bind=engine) - app = FastAPI(lifespan=lifespan) + app = FastAPI(lifespan=lifespan, swagger_ui_parameters={"tryItOutEnabled": True}) app.add_middleware( CORSMiddleware, allow_origins=origins, diff --git a/pkgs/clan-cli/clan_cli/webui/error_handlers.py b/pkgs/clan-cli/clan_cli/webui/error_handlers.py index 341bb2e..9948cc5 100644 --- a/pkgs/clan-cli/clan_cli/webui/error_handlers.py +++ b/pkgs/clan-cli/clan_cli/webui/error_handlers.py @@ -25,7 +25,7 @@ def sql_error_handler(request: Request, exc: SQLAlchemyError) -> JSONResponse: def clan_error_handler(request: Request, exc: ClanError) -> JSONResponse: - log.error("ClanError: %s", exc) + log.exception(exc) detail = [ { "loc": [], diff --git a/pkgs/clan-cli/clan_cli/webui/routers/sql_connect.py b/pkgs/clan-cli/clan_cli/webui/routers/sql_connect.py index 5a9f338..05da969 100644 --- a/pkgs/clan-cli/clan_cli/webui/routers/sql_connect.py +++ b/pkgs/clan-cli/clan_cli/webui/routers/sql_connect.py @@ -1,3 +1,4 @@ +import logging import time from typing import List, Optional @@ -5,6 +6,7 @@ import httpx from fastapi import APIRouter, BackgroundTasks, Depends from sqlalchemy.orm import Session +from ...errors import ClanError from .. import sql_crud, sql_db, sql_models from ..schemas import ( Consumer, @@ -15,11 +17,15 @@ from ..schemas import ( ProducerCreate, Repository, RepositoryCreate, + Resolution, + ResolutionCreate, ) from ..tags import Tags router = APIRouter() +log = logging.getLogger(__name__) + ######################### # # @@ -57,6 +63,15 @@ def get_producer( return producer +@router.delete("/api/v1/delete_producer", tags=[Tags.producers]) +def delete_producer( + entity_did: str = "did:sov:test:1234", + db: Session = Depends(sql_db.get_db), +) -> dict[str, str]: + sql_crud.delete_producer_by_entity_did(db, entity_did) + return {"message": "Producer deleted"} + + ######################### # # # Consumer # @@ -93,6 +108,15 @@ def get_consumer( return consumer +@router.delete("/api/v1/delete_consumer", tags=[Tags.consumers]) +def delete_consumer( + entity_did: str = "did:sov:test:1234", + db: Session = Depends(sql_db.get_db), +) -> dict[str, str]: + sql_crud.delete_consumer_by_entity_did(db, entity_did) + return {"message": "Consumer deleted"} + + ######################### # # # REPOSITORY # @@ -129,10 +153,19 @@ def get_repository( limit: int = 100, db: Session = Depends(sql_db.get_db), ) -> List[sql_models.Repository]: - repository = sql_crud.get_repository_by_did(db, did=entity_did) + repository = sql_crud.get_repository_by_entity_did(db, did=entity_did) return repository +@router.delete("/api/v1/delete_repository", tags=[Tags.repositories]) +def delete_repository( + entity_did: str = "did:sov:test:1234", + db: Session = Depends(sql_db.get_db), +) -> dict[str, str]: + sql_crud.delete_repository_by_entity_did(db, did=entity_did) + return {"message": "Repository deleted"} + + ######################### # # # Entity # @@ -141,11 +174,7 @@ def get_repository( @router.post("/api/v1/create_entity", response_model=Entity, tags=[Tags.entities]) def create_entity( entity: EntityCreate, db: Session = Depends(sql_db.get_db) -) -> EntityCreate | str: - # todo checken ob schon da ... - if sql_crud.get_entity_by_did(db, did=entity.did): - print("did already exsists") - return "Error did already exsists in db" +) -> EntityCreate: return sql_crud.create_entity(db, entity) @@ -178,21 +207,19 @@ def get_attached_entities( return entities -@router.get("/api/v1/detach") +@router.post("/api/v1/detach", response_model=Entity, tags=[Tags.entities]) async def detach( background_tasks: BackgroundTasks, entity_did: str = "did:sov:test:1234", skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db), -) -> dict[str, str]: - background_tasks.add_task( - sql_crud.set_attached_by_entity_did, db, entity_did, False - ) - return {"message": "Detaching in the background"} +) -> sql_models.Entity: + entity = sql_crud.set_attached_by_entity_did(db, entity_did, False) + return entity -@router.get("/api/v1/attach") +@router.post("/api/v1/attach", tags=[Tags.entities]) async def attach( background_tasks: BackgroundTasks, entity_did: str = "did:sov:test:1234", @@ -200,27 +227,86 @@ async def attach( limit: int = 100, db: Session = Depends(sql_db.get_db), ) -> dict[str, str]: + if sql_crud.get_entity_by_did(db, entity_did) is None: + raise ClanError(f"Entity with did '{entity_did}' not found") + background_tasks.add_task(attach_entity, db, entity_did) return {"message": "Attaching in the background"} -# TODO def attach_entity(db: Session, entity_did: str) -> None: db_entity = sql_crud.set_attached_by_entity_did(db, entity_did, True) try: - if db_entity is not None: - while db_entity.attached: - # query status endpoint - # https://www.python-httpx.org/ - response = httpx.get(f"http://{db_entity.ip}", timeout=2) - print(response) - # test with: - # while true ; do printf 'HTTP/1.1 200 OK\r\n\r\ncool, thanks' | nc -l -N localhost 5555 ; done - # client test (apt install python3-httpx): - # httpx http://localhost:5555 - # except not reached set false - time.sleep(1) - except Exception as e: - print(e) - if db_entity is not None: - db_entity = sql_crud.set_attached_by_entity_did(db, entity_did, False) + while db_entity.attached: + # query status endpoint + # https://www.python-httpx.org/ + response = httpx.get(f"http://{db_entity.ip}", timeout=2) + print(response) + # test with: + # while true ; do printf 'HTTP/1.1 200 OK\r\n\r\ncool, thanks' | nc -l -N localhost 5555 ; done + # client test (apt install python3-httpx): + # httpx http://localhost:5555 + # except not reached set false + time.sleep(1) + except Exception: + log.warning(f"Entity {entity_did} not reachable. Setting attached to false") + + db_entity = sql_crud.set_attached_by_entity_did(db, entity_did, False) + + +@router.delete("/api/v1/delete_entity_recursive", tags=[Tags.entities]) +def delete_entity( + entity_did: str = "did:sov:test:1234", + db: Session = Depends(sql_db.get_db), +) -> dict[str, str]: + sql_crud.delete_entity_by_did_recursive(db, did=entity_did) + return {"message": "Entity deleted and all relations to that entity"} + + +######################### +# # +# Resolution # +# # +######################### +@router.post( + "/api/v1/create_resolution", response_model=Resolution, tags=[Tags.resolutions] +) +def create_resolution( + resolution: ResolutionCreate, + db: Session = Depends(sql_db.get_db), +) -> sql_models.Resolution: + return sql_crud.create_resolution(db, resolution) + + +@router.get( + "/api/v1/get_resolutions", response_model=List[Resolution], tags=[Tags.resolutions] +) +def get_resolutions( + skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db) +) -> List[sql_models.Resolution]: + resolutions = sql_crud.get_resolutions(db, skip=skip, limit=limit) + return resolutions + + +@router.get( + "/api/v1/get_resolution", response_model=List[Resolution], tags=[Tags.resolutions] +) +def get_resolution( + requester_did: str = "did:sov:test:1122", + skip: int = 0, + limit: int = 100, + db: Session = Depends(sql_db.get_db), +) -> List[sql_models.Resolution]: + resolution = sql_crud.get_resolution_by_requester_did( + db, requester_did=requester_did + ) + return resolution + + +@router.delete("/api/v1/delete_resolution", tags=[Tags.resolutions]) +def delete_resolution( + requester_did: str = "did:sov:test:1122", + db: Session = Depends(sql_db.get_db), +) -> dict[str, str]: + sql_crud.delete_resolution_by_requester_did(db, requester_did=requester_did) + return {"message": "Resolution deleted"} diff --git a/pkgs/clan-cli/clan_cli/webui/schemas.py b/pkgs/clan-cli/clan_cli/webui/schemas.py index 96987f9..303e0f7 100644 --- a/pkgs/clan-cli/clan_cli/webui/schemas.py +++ b/pkgs/clan-cli/clan_cli/webui/schemas.py @@ -27,7 +27,7 @@ class ProducerBase(BaseModel): service_type: str = "3D Printing" endpoint_url: str = "http://127.0.0.1:8000" status: str = "unknown" - other: dict = {"test": "test"} + other: dict = {"action": ["register", "deregister", "delete", "create"]} class ProducerCreate(ProducerBase): @@ -91,7 +91,11 @@ class EntityBase(BaseModel): name: str = "C1" ip: str = "127.0.0.1" attached: bool = False - other: dict = {"test": "test"} + visible: bool = True + other: dict = { + "network": "Carlo's Home Network", + "roles": ["service repository", "service prosumer"], + } class EntityCreate(EntityBase): @@ -105,3 +109,29 @@ class Entity(EntityCreate): class Config: orm_mode = True + + +######################### +# # +# Resolution # +# # +######################### + + +class ResolutionBase(BaseModel): + requester_name: str = "C1" + requester_did: str = "did:sov:test:1122" + resolved_did: str = "did:sov:test:1234" + other: dict = {"test": "test"} + + +class ResolutionCreate(ResolutionBase): + pass + + +class Resolution(ResolutionCreate): + timestamp: datetime + id: int + + class Config: + orm_mode = True diff --git a/pkgs/clan-cli/clan_cli/webui/server.py b/pkgs/clan-cli/clan_cli/webui/server.py index 66b0f39..762ccb2 100644 --- a/pkgs/clan-cli/clan_cli/webui/server.py +++ b/pkgs/clan-cli/clan_cli/webui/server.py @@ -105,6 +105,27 @@ def start_server(args: argparse.Namespace) -> None: if not args.no_open: Thread(target=open_browser, args=(base_url, args.sub_url)).start() + # DELETE all data from the database + from . import sql_models + from .sql_db import engine + + sql_models.Base.metadata.drop_all(engine) + + if args.populate: + test_dir = Path(__file__).parent.parent.parent / "tests" + + if not test_dir.is_dir(): + raise ClanError(f"Could not find test dir: {test_dir}") + + test_db_api = test_dir / "test_db_api.py" + if not test_db_api.is_file(): + raise ClanError(f"Could not find test db api: {test_db_api}") + + import subprocess + + cmd = ["pytest", "-s", "-n0", str(test_db_api)] + subprocess.run(cmd, check=True) + uvicorn.run( "clan_cli.webui.app:app", host=args.host, diff --git a/pkgs/clan-cli/clan_cli/webui/sql_crud.py b/pkgs/clan-cli/clan_cli/webui/sql_crud.py index d6119c9..cf03c41 100644 --- a/pkgs/clan-cli/clan_cli/webui/sql_crud.py +++ b/pkgs/clan-cli/clan_cli/webui/sql_crud.py @@ -3,6 +3,7 @@ from typing import List, Optional from sqlalchemy.orm import Session from sqlalchemy.sql.expression import true +from ..errors import ClanError from . import schemas, sql_models ######################### @@ -40,6 +41,13 @@ def get_producers_by_entity_did( ) +def delete_producer_by_entity_did(db: Session, entity_did: str) -> None: + db.query(sql_models.Producer).filter( + sql_models.Producer.entity_did == entity_did + ).delete() + db.commit() + + ######################### # # # Consumer # @@ -75,6 +83,13 @@ def get_consumers_by_entity_did( ) +def delete_consumer_by_entity_did(db: Session, entity_did: str) -> None: + db.query(sql_models.Consumer).filter( + sql_models.Consumer.entity_did == entity_did + ).delete() + db.commit() + + ######################### # # # REPOSITORY # @@ -104,7 +119,7 @@ def get_repository_by_uuid(db: Session, uuid: str) -> Optional[sql_models.Reposi ) -def get_repository_by_did( +def get_repository_by_entity_did( db: Session, did: str, skip: int = 0, limit: int = 100 ) -> List[sql_models.Repository]: return ( @@ -116,6 +131,13 @@ def get_repository_by_did( ) +def delete_repository_by_entity_did(db: Session, did: str) -> None: + db.query(sql_models.Repository).filter( + sql_models.Repository.entity_did == did + ).delete() + db.commit() + + ######################### # # # Entity # @@ -153,21 +175,70 @@ def get_attached_entities( ) -# set attached -# None if did not found # Returns same entity if setting didnt changed something def set_attached_by_entity_did( db: Session, entity_did: str, value: bool -) -> Optional[sql_models.Entity]: - # ste attached to true +) -> sql_models.Entity: db_entity = get_entity_by_did(db, entity_did) - if db_entity is not None: - # db_entity.attached = Column(True) - setattr(db_entity, "attached", value) - # save changes in db - db.add(db_entity) - db.commit() - db.refresh(db_entity) - return db_entity - else: - return db_entity + if db_entity is None: + raise ClanError(f"Entity with did '{entity_did}' not found") + + setattr(db_entity, "attached", value) + + # save changes in db + db.add(db_entity) + db.commit() + db.refresh(db_entity) + return db_entity + + +def delete_entity_by_did(db: Session, did: str) -> None: + db.query(sql_models.Entity).filter(sql_models.Entity.did == did).delete() + db.commit() + + +def delete_entity_by_did_recursive(db: Session, did: str) -> None: + delete_producer_by_entity_did(db, did) + delete_consumer_by_entity_did(db, did) + delete_repository_by_entity_did(db, did) + delete_entity_by_did(db, did) + + +######################### +# # +# Resolution # +# # +######################### +def create_resolution( + db: Session, resolution: schemas.ResolutionCreate +) -> sql_models.Resolution: + db_resolution = sql_models.Resolution(**resolution.dict()) + db.add(db_resolution) + db.commit() + db.refresh(db_resolution) + return db_resolution + + +def get_resolutions( + db: Session, skip: int = 0, limit: int = 100 +) -> List[sql_models.Resolution]: + return db.query(sql_models.Resolution).offset(skip).limit(limit).all() + + +def get_resolution_by_requester_did( + db: Session, requester_did: str, skip: int = 0, limit: int = 100 +) -> List[sql_models.Resolution]: + return ( + db.query(sql_models.Resolution) + .filter(sql_models.Resolution.requester_did == requester_did) + .offset(skip) + .limit(limit) + .all() + ) + + +def delete_resolution_by_requester_did(db: Session, requester_did: str) -> None: + db.query(sql_models.Resolution).filter( + sql_models.Resolution.requester_did == requester_did + ).delete() + db.commit() diff --git a/pkgs/clan-cli/clan_cli/webui/sql_models.py b/pkgs/clan-cli/clan_cli/webui/sql_models.py index 88231ca..c606b9f 100644 --- a/pkgs/clan-cli/clan_cli/webui/sql_models.py +++ b/pkgs/clan-cli/clan_cli/webui/sql_models.py @@ -26,6 +26,7 @@ class Entity(Base): name = Column(String, index=True) ip = Column(String, index=True) attached = Column(Boolean, index=True) + visible = Column(Boolean, index=True) ## Non queryable body ## # In here we deposit: Network, Roles, Visible, etc. @@ -106,4 +107,5 @@ class Resolution(Base): requester_name = Column(String, index=True) requester_did = Column(String, index=True) resolved_did = Column(String, index=True) - timestamp = Column(DateTime, index=True) + other = Column(JSON) + timestamp = Column(DateTime(timezone=True), server_default=func.now()) diff --git a/pkgs/clan-cli/clan_cli/webui/tags.py b/pkgs/clan-cli/clan_cli/webui/tags.py index 78f7968..7f11e48 100644 --- a/pkgs/clan-cli/clan_cli/webui/tags.py +++ b/pkgs/clan-cli/clan_cli/webui/tags.py @@ -7,6 +7,7 @@ class Tags(Enum): consumers = "consumers" entities = "entities" repositories = "repositories" + resolutions = "resolution" def __str__(self) -> str: return self.value @@ -29,4 +30,8 @@ tags_metadata: List[Dict[str, Any]] = [ "name": str(Tags.repositories), "description": "Operations on a repository.", }, + { + "name": str(Tags.resolutions), + "description": "Operations on a resolution.", + }, ] diff --git a/pkgs/clan-cli/tests/test_db_api.py b/pkgs/clan-cli/tests/test_db_api.py index 01151da..4d24b79 100644 --- a/pkgs/clan-cli/tests/test_db_api.py +++ b/pkgs/clan-cli/tests/test_db_api.py @@ -38,8 +38,11 @@ def make_test_post_and_get( headers={"Content-Type": "application/json"}, ) assert response.status_code == 200 + if paramter == "repository": assert_extra_info(["time_created"], request_body, response.json()) + elif paramter == "resolution": + assert_extra_info(["timestamp", "id"], request_body, response.json()) elif paramter == "consumer": assert_extra_info(["id"], request_body, response.json()) elif paramter == "entity": @@ -55,6 +58,8 @@ def make_test_post_and_get( assert response.status_code == 200 if paramter == "repository": assert_extra_info(["time_created"], request_body, response.json()[0]) + elif paramter == "resolution": + assert_extra_info(["timestamp", "id"], request_body, response.json()[0]) elif paramter == "consumer": assert_extra_info(["id"], request_body, response.json()[0]) elif paramter == "entity": @@ -77,7 +82,7 @@ def test_producer(api: TestClient) -> None: "service_type": "3D Printing", "endpoint_url": "http://127.0.0.1:8000", "status": "unknown", - "other": {"test": "test"}, + "other": {"action": ["register", "deregister", "delete", "create"]}, "entity_did": default_entity_did, } paramter = "producer" @@ -151,7 +156,7 @@ def test_producer2(api: TestClient) -> None: "service_type": "Fax", "endpoint_url": "http://127.0.0.1:8001", "status": "unknown", - "other": {"faxen": "dicke"}, + "other": {"action": ["register", "deregister", "delete", "create"]}, "entity_did": default_entity_did2, } paramter = "producer" @@ -166,7 +171,7 @@ def test_producer3(api: TestClient) -> None: "service_type": "VR-Stream", "endpoint_url": "http://127.0.0.1:8002", "status": "unknown", - "other": {"oculos": "rift"}, + "other": {"action": ["register", "deregister", "delete", "create"]}, "entity_did": default_entity_did3, } paramter = "producer" @@ -181,7 +186,7 @@ def test_producer4(api: TestClient) -> None: "service_type": "gallary", "endpoint_url": "http://127.0.0.1:8003", "status": "unknown", - "other": {"nice": "pics"}, + "other": {"action": ["register", "deregister", "delete", "create"]}, "entity_did": default_entity_did4, } paramter = "producer" @@ -196,7 +201,7 @@ def test_producer5(api: TestClient) -> None: "service_type": "Game-Shop", "endpoint_url": "http://127.0.0.1:8004", "status": "unknown", - "other": {"war": "games"}, + "other": {"action": ["register", "deregister", "delete", "create"]}, "entity_did": default_entity_did5, } paramter = "producer" @@ -389,7 +394,11 @@ def test_entity(api: TestClient) -> None: "name": "C1", "ip": "127.0.0.1", "attached": False, - "other": {"test": "test"}, + "visible": True, + "other": { + "network": "Carlo1's Home Network", + "roles": ["service repository", "service consumer"], + }, } paramter = "entity" # get_request = "entity_did=did%3Asov%3Atest%3A1234" @@ -402,8 +411,53 @@ def test_entity2(api: TestClient) -> None: "name": "C2", "ip": "127.0.0.2", "attached": False, - "other": {"test": "test"}, + "visible": True, + "other": { + "network": "Carlo2's Home Network", + "roles": ["service repository", "service prosumer"], + }, } paramter = "entity" get_request = "entity_did=" + url.quote(default_entity_did2) make_test_post_and_get(api, request_body, paramter, get_request) + + +######################### +# # +# Resolution # +# # +######################### +def test_resolution(api: TestClient) -> None: + request_body = { + "requester_did": default_entity_did2, + "requester_name": "C2", + "resolved_did": default_entity_did, + "other": {"test": "test"}, + } + paramter = "resolution" + get_request = "requester_did=" + url.quote(default_entity_did2) + make_test_post_and_get(api, request_body, paramter, get_request) + + +def test_resolution2(api: TestClient) -> None: + request_body = { + "requester_did": default_entity_did3, + "requester_name": "C3", + "resolved_did": default_entity_did, + "other": {"test": "test"}, + } + paramter = "resolution" + get_request = "requester_did=" + url.quote(default_entity_did3) + make_test_post_and_get(api, request_body, paramter, get_request) + + +def test_resolution3(api: TestClient) -> None: + request_body = { + "requester_did": default_entity_did4, + "requester_name": "C4", + "resolved_did": default_entity_did, + "other": {"test": "test"}, + } + paramter = "resolution" + get_request = "requester_did=" + url.quote(default_entity_did4) + make_test_post_and_get(api, request_body, paramter, get_request) diff --git a/pkgs/node-packages/generate.sh b/pkgs/node-packages/generate.sh old mode 100755 new mode 100644 diff --git a/pkgs/ui/nix/ui-assets.nix b/pkgs/ui/nix/ui-assets.nix index 9e81835..848c912 100644 --- a/pkgs/ui/nix/ui-assets.nix +++ b/pkgs/ui/nix/ui-assets.nix @@ -1,5 +1,5 @@ { fetchzip }: fetchzip { - url = "https://gitea.gchq.icu/api/packages/IoSL/generic/IoSL-service-aware-frontend/16glc9nkcqsalf5jwcwcsv1nx65cqwrqr95n1ghmb365nxi57bb4/assets.tar.gz"; - sha256 = "16glc9nkcqsalf5jwcwcsv1nx65cqwrqr95n1ghmb365nxi57bb4"; + url = "https://gitea.gchq.icu/api/packages/IoSL/generic/IoSL-service-aware-frontend/042x4cdb35zzwjx3fc7v0qxil1fbam5xrgg42v816yih9kl5dqrz/assets.tar.gz"; + sha256 = "042x4cdb35zzwjx3fc7v0qxil1fbam5xrgg42v816yih9kl5dqrz"; } diff --git a/pkgs/ui/nix/update-ui-assets.sh b/pkgs/ui/nix/update-ui-assets.sh old mode 100755 new mode 100644 index 0bfc6b1..d3ab7d9 --- a/pkgs/ui/nix/update-ui-assets.sh +++ b/pkgs/ui/nix/update-ui-assets.sh @@ -1,3 +1,5 @@ +#!/usr/bin/env bash + # shellcheck shell=bash set -xeuo pipefail diff --git a/pkgs/ui/src/app/access-point/page.tsx b/pkgs/ui/src/app/access-point/page.tsx index 177073c..6a18acf 100644 --- a/pkgs/ui/src/app/access-point/page.tsx +++ b/pkgs/ui/src/app/access-point/page.tsx @@ -6,11 +6,34 @@ import { APSummaryDetails, APAttachmentsDummyData, APAttachmentsTableConfig, - APServiceRepositoryDummyData, APServiceRepositoryTableConfig, } from "@/mock/access_point"; +import { useEffect, useState } from "react"; + +interface RepositoryData { + entity_name: string; + entity_did: string; + network: string; + ip_address: string; +} export default function AccessPoint() { + const [repositoryData, setRepositoryData] = useState([]); + + useEffect(() => { + fetch("http://localhost:2979/api/v1/get_repositories", { + method: "GET", + }) + .then((resp) => + resp.json().then((jsonData) => { + console.log(jsonData); + setRepositoryData(jsonData); + }), + ) + .then() + .catch(); + }, []); + return (

Service Repository View

diff --git a/pkgs/ui/src/app/client-1/page.tsx b/pkgs/ui/src/app/client-1/page.tsx index 5abb913..763702a 100644 --- a/pkgs/ui/src/app/client-1/page.tsx +++ b/pkgs/ui/src/app/client-1/page.tsx @@ -3,14 +3,42 @@ import SummaryDetails from "@/components/summary_card"; import { Client1SummaryDetails, - Client1ConsumerData, Client1ConsumerTableConfig, Client1ProducerTableConfig, - Client1ProducerData, } from "@/mock/client_1"; import CustomTable from "@/components/table"; +import { useEffect, useState } from "react"; export default function Client1() { + const [consumerData, setConsumerData] = useState([]); + const [producerData, setProducerData] = useState([]); + + useEffect(() => { + fetch("http://localhost:2979/api/v1/get_consumers", { + method: "GET", + }) + .then((resp) => + resp.json().then((jsonData) => { + console.log(jsonData); + setConsumerData(jsonData); + }), + ) + .then() + .catch(); + + fetch("http://localhost:2979/api/v1/get_producers", { + method: "GET", + }) + .then((resp) => + resp.json().then((jsonData) => { + console.log(jsonData); + setProducerData(jsonData); + }), + ) + .then() + .catch(); + }, []); + return (

Consumer View

Producer View

diff --git a/pkgs/ui/src/app/client-2/page.tsx b/pkgs/ui/src/app/client-2/page.tsx index 80be865..b3a7b75 100644 --- a/pkgs/ui/src/app/client-2/page.tsx +++ b/pkgs/ui/src/app/client-2/page.tsx @@ -2,15 +2,44 @@ import SummaryDetails from "@/components/summary_card"; import { - Client2ConsumerData, Client2ConsumerTableConfig, - Client2ProducerData, Client2ProducerTableConfig, Client2SummaryDetails, } from "@/mock/client_2"; import CustomTable from "@/components/table"; +import { useEffect, useState } from "react"; export default function Client1() { + const [consumerData, setConsumerData] = useState([]); + const [producerData, setProducerData] = useState([]); + + useEffect(() => { + fetch("http://localhost:2979/api/v1/get_consumers", { + method: "GET", + }) + .then((resp) => + resp.json().then((jsonData) => { + console.log(jsonData); + setConsumerData(jsonData); + }), + ) + .then() + .catch(); + + fetch("http://localhost:2979/api/v1/get_producers", { + method: "GET", + // credentials: 'include', + }) + .then((resp) => + resp.json().then((jsonData) => { + console.log(jsonData); + setProducerData(jsonData); + }), + ) + .then() + .catch(); + }, []); + return (

Consumer View

Producer View

diff --git a/pkgs/ui/src/app/distributed-ledger-gateway/page.tsx b/pkgs/ui/src/app/distributed-ledger-gateway/page.tsx index cc1c15e..73312b2 100644 --- a/pkgs/ui/src/app/distributed-ledger-gateway/page.tsx +++ b/pkgs/ui/src/app/distributed-ledger-gateway/page.tsx @@ -1,14 +1,27 @@ "use client"; -import { - DLGResolutionDummyData, - DLGResolutionTableConfig, - DLGSummaryDetails, -} from "@/mock/dlg"; +import { DLGResolutionTableConfig, DLGSummaryDetails } from "@/mock/dlg"; import CustomTable from "@/components/table"; import SummaryDetails from "@/components/summary_card"; +import { useEffect, useState } from "react"; export default function DLG() { + const [resolutionData, setResolutionData] = useState([]); + + useEffect(() => { + fetch("http://localhost:2979/api/v1/get_resolutions", { + method: "GET", + }) + .then((resp) => + resp.json().then((jsonData) => { + console.log(jsonData); + setResolutionData(jsonData); + }), + ) + .then() + .catch(); + }, []); + return (

DID Resolution View

diff --git a/pkgs/ui/src/app/home/page.tsx b/pkgs/ui/src/app/home/page.tsx index 37e51de..d6c3566 100644 --- a/pkgs/ui/src/app/home/page.tsx +++ b/pkgs/ui/src/app/home/page.tsx @@ -3,9 +3,26 @@ import { NoDataOverlay } from "@/components/noDataOverlay"; import SummaryDetails from "@/components/summary_card"; import CustomTable from "@/components/table"; -import { HomeDummyData, HomeTableConfig } from "@/mock/home"; +import { HomeTableConfig } from "@/mock/home"; +import { useEffect, useState } from "react"; export default function Home() { + const [homeData, setHomeData] = useState([]); + + useEffect(() => { + fetch("http://localhost:2979/api/v1/get_entities", { + method: "GET", + }) + .then((resp) => + resp.json().then((jsonData) => { + console.log(jsonData); + setHomeData(jsonData); + }), + ) + .then() + .catch(); + }, []); + return (

Home View Table

- +
diff --git a/pkgs/ui/src/mock/access_point/index.ts b/pkgs/ui/src/mock/access_point/index.ts index 07ae286..8af005c 100644 --- a/pkgs/ui/src/mock/access_point/index.ts +++ b/pkgs/ui/src/mock/access_point/index.ts @@ -20,25 +20,25 @@ export const APSummaryDetails = [ export const APAttachmentsDummyData = [ { entity_name: "C1", - entity_DID: "did:sov:test:1234", + entity_did: "did:sov:test:1234", network: "Carlo's Home Network", ip_address: "127.0.0.1", }, { entity_name: "C2", - entity_DID: "did:sov:test:4567", + entity_did: "did:sov:test:4567", network: "Steve's Home Network", ip_address: "127.0.0.1", }, { entity_name: "C1-TEST", - entity_DID: "did:sov:test:0001", + entity_did: "did:sov:test:0001", network: "Test Network A", ip_address: "127.0.0.1", }, { entity_name: "C2-TEST", - entity_DID: "did:sov:test:0002", + entity_did: "did:sov:test:0002", network: "Test Network B", ip_address: "127.0.0.1", }, @@ -49,7 +49,7 @@ export const APAttachmentsTableConfig = [ label: "Entity name", }, { - key: "entity_DID", + key: "entity_did", label: "Entity DID", }, { @@ -67,17 +67,17 @@ export const APServiceRepositoryDummyData = [ { service_name: "Carlo's Printing", service_type: "3D Printing", - end_point: "URL", - producer: "C1", - producer_DID: "did:sov:test:1234", + endpoint_url: "URL", + entity: "C1", + entity_did: "did:sov:test:1234", network: "Carlo's Home Network", }, { service_name: "Jeff's Printing", service_type: "3D Printing", - end_point: "URL", - producer: "C2", - producer_DID: "did:sov:test:5678", + endpoint_url: "URL", + entity: "C2", + entity_did: "did:sov:test:5678", network: "Jeff's Home Network", }, ]; @@ -91,19 +91,23 @@ export const APServiceRepositoryTableConfig = [ label: "Service type", }, { - key: "end_point", + key: "endpoint_url", label: "End point", }, + // { + // key: "entity", + // label: "Entity", + // }, { - key: "producer", - label: "Producer", + key: "entity_did", + label: "Entity DID", }, + // { + // key: "network", + // label: "Network", + // }, { - key: "producer_DID", - label: "Producer DID", - }, - { - key: "network", - label: "Network", + key: "status", + label: "Status", }, ]; diff --git a/pkgs/ui/src/mock/client_1/index.ts b/pkgs/ui/src/mock/client_1/index.ts index 658b51e..9139156 100644 --- a/pkgs/ui/src/mock/client_1/index.ts +++ b/pkgs/ui/src/mock/client_1/index.ts @@ -19,33 +19,33 @@ export const Client1ConsumerData = [ { service_name: "Carlo's Printing", service_type: "3D Printing", - end_point: "Consume", - producer: "C2", - producer_did: "did:sov:test:1223", + endpoint_url: "Consume", + entity: "C2", + entity_did: "did:sov:test:1223", network: "Carlo's Home Network", }, { service_name: "Steve's Printing", service_type: "3D Printing", - end_point: "Consume", - producer: "C2", - producer_did: "did:sov:test:1234", + endpoint_url: "Consume", + entity: "C2", + entity_did: "did:sov:test:1234", network: "Steve's Home Network", }, { service_name: "Test A", service_type: "3D Printing", - end_point: "Consume", - producer: "C2", - producer_did: "did:sov:test:4567", + endpoint_url: "Consume", + entity: "C2", + entity_did: "did:sov:test:4567", network: "Test Network A", }, { service_name: "Test B", service_type: "3D Printing", - end_point: "Consume", - producer: "C2", - producer_did: "did:sov:test:0062", + endpoint_url: "Consume", + entity: "C2", + entity_did: "did:sov:test:0062", network: "Test Network B", }, ]; @@ -60,16 +60,16 @@ export const Client1ConsumerTableConfig = [ label: "Service Type", }, { - key: "end_point", + key: "endpoint_url", label: "End Point", }, { - key: "producer", - label: "Producer", + key: "entity", + label: "Entity", }, { - key: "producer_did", - label: "Producer DID", + key: "entity_did", + label: "Entity DID", }, { key: "network", @@ -81,7 +81,7 @@ export const Client1ProducerData = [ { service_name: "Carlo's Printing", service_type: "3D Printing", - end_point: "URL", + endpoint_url: "URL", usage: "C1(3), C3(4)", status: "DRAFT, REGISTERED", action: "Register, Deregister, Delete", @@ -89,7 +89,7 @@ export const Client1ProducerData = [ { service_name: "Steve's Printing", service_type: "3D Printing", - end_point: "URL", + endpoint_url: "URL", usage: "C1(3), C3(4)", status: "REGISTERED", action: "Create", @@ -97,7 +97,7 @@ export const Client1ProducerData = [ { service_name: "Test Printing A", service_type: "3D Printing", - end_point: "URL", + endpoint_url: "URL", usage: "C1(3), C3(4)", status: "DRAFT", action: "Register, Deregister", @@ -105,7 +105,7 @@ export const Client1ProducerData = [ { service_name: "Test Printing B", service_type: "3D Printing", - end_point: "URL", + endpoint_url: "URL", usage: "C1(3), C3(4)", status: "DRAFT, REGISTERED", action: "Delete, Create", @@ -122,19 +122,19 @@ export const Client1ProducerTableConfig = [ label: "Service Type", }, { - key: "end_point", + key: "endpoint_url", label: "End Point", }, - { - key: "usage", - label: "Usage", - }, + // { + // key: "usage", + // label: "Usage", + // }, { key: "status", label: "Status", }, - { - key: "action", - label: "Action", - }, + // { + // key: "action", + // label: "Action", + // }, ]; diff --git a/pkgs/ui/src/mock/client_2/index.ts b/pkgs/ui/src/mock/client_2/index.ts index b0105fd..1f40fcd 100644 --- a/pkgs/ui/src/mock/client_2/index.ts +++ b/pkgs/ui/src/mock/client_2/index.ts @@ -19,33 +19,33 @@ export const Client2ConsumerData = [ { service_name: "Carlo's Printing", service_type: "3D Printing", - end_point: "Consume", - producer: "C2", - producer_did: "did:sov:test:1223", + endpoint_url: "Consume", + entity: "C2", + entity_did: "did:sov:test:1223", network: "Carlo's Home Network", }, { service_name: "Steve's Printing", service_type: "3D Printing", - end_point: "Consume", - producer: "C2", - producer_did: "did:sov:test:1234", + endpoint_url: "Consume", + entity: "C2", + entity_did: "did:sov:test:1234", network: "Steve's Home Network", }, { service_name: "Test A", service_type: "3D Printing", - end_point: "Consume", - producer: "C2", - producer_did: "did:sov:test:4567", + endpoint_url: "Consume", + entity: "C2", + entity_did: "did:sov:test:4567", network: "Test Network A", }, { service_name: "Test B", service_type: "3D Printing", - end_point: "Consume", - producer: "C2", - producer_did: "did:sov:test:0062", + endpoint_url: "Consume", + entity: "C2", + entity_did: "did:sov:test:0062", network: "Test Network B", }, ]; @@ -60,16 +60,16 @@ export const Client2ConsumerTableConfig = [ label: "Service Type", }, { - key: "end_point", + key: "endpoint_url", label: "End Point", }, { - key: "producer", - label: "Producer", + key: "entity", + label: "Entity", }, { - key: "producer_did", - label: "Producer DID", + key: "entity_did", + label: "Entity DID", }, { key: "network", @@ -81,7 +81,7 @@ export const Client2ProducerData = [ { service_name: "Carlo's Printing", service_type: "3D Printing", - end_point: "URL", + endpoint_url: "URL", usage: "C1(3), C3(4)", status: "DRAFT, REGISTERED", action: "Register, Deregister, Delete", @@ -89,7 +89,7 @@ export const Client2ProducerData = [ { service_name: "Steve's Printing", service_type: "3D Printing", - end_point: "URL", + endpoint_url: "URL", usage: "C1(3), C3(4)", status: "REGISTERED", action: "Create", @@ -97,7 +97,7 @@ export const Client2ProducerData = [ { service_name: "Test Printing A", service_type: "3D Printing", - end_point: "URL", + endpoint_url: "URL", usage: "C1(3), C3(4)", status: "DRAFT", action: "Register, Deregister", @@ -105,7 +105,7 @@ export const Client2ProducerData = [ { service_name: "Test Printing B", service_type: "3D Printing", - end_point: "URL", + endpoint_url: "URL", usage: "C1(3), C3(4)", status: "DRAFT, REGISTERED", action: "Delete, Create", @@ -122,7 +122,7 @@ export const Client2ProducerTableConfig = [ label: "Service Type", }, { - key: "end_point", + key: "endpoint_url", label: "End Point", }, { diff --git a/pkgs/ui/src/mock/dlg/index.ts b/pkgs/ui/src/mock/dlg/index.ts index 0163634..2e33f79 100644 --- a/pkgs/ui/src/mock/dlg/index.ts +++ b/pkgs/ui/src/mock/dlg/index.ts @@ -16,14 +16,14 @@ export const DLGSummaryDetails = [ export const DLGResolutionDummyData = [ { requester_name: "C1", - requester_DID: "did:sov:test:1234", - DID_resolved: "did:sov:test:1234", + requester_did: "did:sov:test:1234", + resolved_did: "did:sov:test:1234", timestamp: "2023.11.01 17:05:45", }, { requester_name: "C2", - requester_DID: "did:sov:test:5678", - DID_resolved: "did:sov:test:5678", + requester_did: "did:sov:test:5678", + resolved_did: "did:sov:test:5678", timestamp: "2023.12.01 15:05:50", }, ]; @@ -34,12 +34,12 @@ export const DLGResolutionTableConfig = [ label: "Requester name", }, { - key: "requester_DID", + key: "requester_did", label: "Requester DID", }, { - key: "DID_resolved", - label: "DID resolved", + key: "resolved_did", + label: "Resolved DID", }, { key: "timestamp", diff --git a/pkgs/ui/src/mock/home/index.ts b/pkgs/ui/src/mock/home/index.ts index ccff693..b6c2d4f 100644 --- a/pkgs/ui/src/mock/home/index.ts +++ b/pkgs/ui/src/mock/home/index.ts @@ -21,27 +21,27 @@ export const HomeDummyData = [ export const HomeTableConfig = [ { - key: "entity_name", + key: "name", label: "Entity name", }, { - key: "entity_DID", + key: "did", label: "Entity DID", }, + // { + // key: "network", + // label: "Network", + // }, { - key: "network", - label: "Network", - }, - { - key: "ip_address", + key: "ip", label: "IP address", }, + // { + // key: "roles", + // label: "Roles", + // }, { - key: "roles", - label: "Roles", - }, - { - key: "visible", - label: "Visible", + key: "attached", + label: "Attached", }, ];