diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1d59732 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,37 @@ +name: CI + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + - name: Verify Maven wrapper + run: chmod +x mvnw + + - name: Run tests + run: ./mvnw clean test + + - name: Check code formatting + run: ./mvnw spotless:check \ No newline at end of file diff --git a/.gitignore b/.gitignore index abdd123..71b2449 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,9 @@ target *.bkp *.pyc .coverage -.idea \ No newline at end of file +.idea +logs/ +*.log + +# Maven wrapper jar (but keep properties) +.mvn/wrapper/maven-wrapper.jar \ No newline at end of file diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..c0bcafe --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,3 @@ +wrapperVersion=3.3.4 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/README.md b/README.md index bea4201..cf71ffe 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Viron +[![CI](https://github.com/Preponderous-Software/Viron/actions/workflows/ci.yml/badge.svg)](https://github.com/Preponderous-Software/Viron/actions/workflows/ci.yml) + **Viron** is your **foundational spatial simulation service** — the bedrock on which worlds are built. It manages **environments**, **grids**, **locations**, and **entities** through a clean REST API so you can skip the boilerplate and focus on *fun, emergent gameplay*. diff --git a/legacy/README.md b/legacy/README.md new file mode 100644 index 0000000..197095b --- /dev/null +++ b/legacy/README.md @@ -0,0 +1,25 @@ +# Legacy Implementation + +This directory contains the previous implementation of Viron that was moved here for reference during the MVP rebuild process. + +## Structure + +The legacy code includes: +- Java implementation with Spring Boot +- Python models and services +- Various test files +- Original pom.xml configuration + +## Usage + +This code is preserved for reference purposes during the rebuild. It should not be used in production and may contain technical debt or architectural issues that led to the decision to rebuild. + +## Migration Notes + +Key differences between legacy and new implementation: +- Java version updated from 21 to 17 for broader compatibility +- Improved error handling with global exception handler +- Better code formatting and style enforcement with Spotless +- Enhanced logging configuration with different profiles +- Streamlined package structure +- Updated dependencies and Spring Boot configuration \ No newline at end of file diff --git a/legacy/pom.xml b/legacy/pom.xml new file mode 100644 index 0000000..8d104b3 --- /dev/null +++ b/legacy/pom.xml @@ -0,0 +1,101 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.4 + + + preponderous + viron + 0.6.0-SNAPSHOT + viron + Environment manager + + 21 + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.postgresql + postgresql + + + + org.springframework.boot + spring-boot-starter-web + + + + org.projectlombok + lombok + 1.18.30 + provided + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.3.0 + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.jacoco + jacoco-maven-plugin + + + + prepare-agent + + + + report + test + + report + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + ${java.version} + ${java.version} + + + org.projectlombok + lombok + 1.18.30 + + + + + + + + diff --git a/legacy/src/main/java/preponderous/viron/VironApplication.java b/legacy/src/main/java/preponderous/viron/VironApplication.java new file mode 100644 index 0000000..08b3307 --- /dev/null +++ b/legacy/src/main/java/preponderous/viron/VironApplication.java @@ -0,0 +1,21 @@ +// Copyright (c) 2024 Preponderous Software +// MIT License + +package preponderous.viron; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Import; + +import preponderous.viron.config.DbConfig; +import preponderous.viron.config.ServiceConfig; + +@SpringBootApplication +@Import({DbConfig.class, ServiceConfig.class}) +public class VironApplication { + + public static void main(String[] args) { + SpringApplication.run(VironApplication.class, args); + } + +} diff --git a/src/main/java/preponderous/viron/config/DbConfig.java b/legacy/src/main/java/preponderous/viron/config/DbConfig.java similarity index 100% rename from src/main/java/preponderous/viron/config/DbConfig.java rename to legacy/src/main/java/preponderous/viron/config/DbConfig.java diff --git a/legacy/src/main/java/preponderous/viron/config/OpenApiConfig.java b/legacy/src/main/java/preponderous/viron/config/OpenApiConfig.java new file mode 100644 index 0000000..f945645 --- /dev/null +++ b/legacy/src/main/java/preponderous/viron/config/OpenApiConfig.java @@ -0,0 +1,17 @@ +package preponderous.viron.config; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OpenApiConfig { + @Bean + public OpenAPI customOpenAPI() { + return new OpenAPI() + .info(new Info() + .title("Viron API") + .version("0.5.0")); + } +} \ No newline at end of file diff --git a/src/main/java/preponderous/viron/config/RestConfig.java b/legacy/src/main/java/preponderous/viron/config/RestConfig.java similarity index 100% rename from src/main/java/preponderous/viron/config/RestConfig.java rename to legacy/src/main/java/preponderous/viron/config/RestConfig.java diff --git a/src/main/java/preponderous/viron/config/ServiceConfig.java b/legacy/src/main/java/preponderous/viron/config/ServiceConfig.java similarity index 100% rename from src/main/java/preponderous/viron/config/ServiceConfig.java rename to legacy/src/main/java/preponderous/viron/config/ServiceConfig.java diff --git a/src/main/java/preponderous/viron/controllers/DebugController.java b/legacy/src/main/java/preponderous/viron/controllers/DebugController.java similarity index 100% rename from src/main/java/preponderous/viron/controllers/DebugController.java rename to legacy/src/main/java/preponderous/viron/controllers/DebugController.java diff --git a/src/main/java/preponderous/viron/controllers/EntityController.java b/legacy/src/main/java/preponderous/viron/controllers/EntityController.java similarity index 100% rename from src/main/java/preponderous/viron/controllers/EntityController.java rename to legacy/src/main/java/preponderous/viron/controllers/EntityController.java diff --git a/src/main/java/preponderous/viron/controllers/EnvironmentController.java b/legacy/src/main/java/preponderous/viron/controllers/EnvironmentController.java similarity index 100% rename from src/main/java/preponderous/viron/controllers/EnvironmentController.java rename to legacy/src/main/java/preponderous/viron/controllers/EnvironmentController.java diff --git a/src/main/java/preponderous/viron/controllers/GridController.java b/legacy/src/main/java/preponderous/viron/controllers/GridController.java similarity index 100% rename from src/main/java/preponderous/viron/controllers/GridController.java rename to legacy/src/main/java/preponderous/viron/controllers/GridController.java diff --git a/src/main/java/preponderous/viron/controllers/LocationController.java b/legacy/src/main/java/preponderous/viron/controllers/LocationController.java similarity index 100% rename from src/main/java/preponderous/viron/controllers/LocationController.java rename to legacy/src/main/java/preponderous/viron/controllers/LocationController.java diff --git a/src/main/java/preponderous/viron/database/DbInteractions.java b/legacy/src/main/java/preponderous/viron/database/DbInteractions.java similarity index 100% rename from src/main/java/preponderous/viron/database/DbInteractions.java rename to legacy/src/main/java/preponderous/viron/database/DbInteractions.java diff --git a/src/main/java/preponderous/viron/exceptions/EntityCreationException.java b/legacy/src/main/java/preponderous/viron/exceptions/EntityCreationException.java similarity index 100% rename from src/main/java/preponderous/viron/exceptions/EntityCreationException.java rename to legacy/src/main/java/preponderous/viron/exceptions/EntityCreationException.java diff --git a/src/main/java/preponderous/viron/exceptions/EntityServiceException.java b/legacy/src/main/java/preponderous/viron/exceptions/EntityServiceException.java similarity index 100% rename from src/main/java/preponderous/viron/exceptions/EntityServiceException.java rename to legacy/src/main/java/preponderous/viron/exceptions/EntityServiceException.java diff --git a/src/main/java/preponderous/viron/exceptions/EnvironmentCreationException.java b/legacy/src/main/java/preponderous/viron/exceptions/EnvironmentCreationException.java similarity index 100% rename from src/main/java/preponderous/viron/exceptions/EnvironmentCreationException.java rename to legacy/src/main/java/preponderous/viron/exceptions/EnvironmentCreationException.java diff --git a/src/main/java/preponderous/viron/exceptions/NotFoundException.java b/legacy/src/main/java/preponderous/viron/exceptions/NotFoundException.java similarity index 100% rename from src/main/java/preponderous/viron/exceptions/NotFoundException.java rename to legacy/src/main/java/preponderous/viron/exceptions/NotFoundException.java diff --git a/src/main/java/preponderous/viron/exceptions/ServiceException.java b/legacy/src/main/java/preponderous/viron/exceptions/ServiceException.java similarity index 100% rename from src/main/java/preponderous/viron/exceptions/ServiceException.java rename to legacy/src/main/java/preponderous/viron/exceptions/ServiceException.java diff --git a/src/main/java/preponderous/viron/factories/EntityFactory.java b/legacy/src/main/java/preponderous/viron/factories/EntityFactory.java similarity index 100% rename from src/main/java/preponderous/viron/factories/EntityFactory.java rename to legacy/src/main/java/preponderous/viron/factories/EntityFactory.java diff --git a/src/main/java/preponderous/viron/factories/EnvironmentFactory.java b/legacy/src/main/java/preponderous/viron/factories/EnvironmentFactory.java similarity index 100% rename from src/main/java/preponderous/viron/factories/EnvironmentFactory.java rename to legacy/src/main/java/preponderous/viron/factories/EnvironmentFactory.java diff --git a/src/main/java/preponderous/viron/models/Entity.java b/legacy/src/main/java/preponderous/viron/models/Entity.java similarity index 100% rename from src/main/java/preponderous/viron/models/Entity.java rename to legacy/src/main/java/preponderous/viron/models/Entity.java diff --git a/src/main/java/preponderous/viron/models/Environment.java b/legacy/src/main/java/preponderous/viron/models/Environment.java similarity index 100% rename from src/main/java/preponderous/viron/models/Environment.java rename to legacy/src/main/java/preponderous/viron/models/Environment.java diff --git a/src/main/java/preponderous/viron/models/Grid.java b/legacy/src/main/java/preponderous/viron/models/Grid.java similarity index 100% rename from src/main/java/preponderous/viron/models/Grid.java rename to legacy/src/main/java/preponderous/viron/models/Grid.java diff --git a/src/main/java/preponderous/viron/models/Location.java b/legacy/src/main/java/preponderous/viron/models/Location.java similarity index 100% rename from src/main/java/preponderous/viron/models/Location.java rename to legacy/src/main/java/preponderous/viron/models/Location.java diff --git a/src/main/java/preponderous/viron/repositories/EntityRepository.java b/legacy/src/main/java/preponderous/viron/repositories/EntityRepository.java similarity index 100% rename from src/main/java/preponderous/viron/repositories/EntityRepository.java rename to legacy/src/main/java/preponderous/viron/repositories/EntityRepository.java diff --git a/src/main/java/preponderous/viron/repositories/EntityRepositoryImpl.java b/legacy/src/main/java/preponderous/viron/repositories/EntityRepositoryImpl.java similarity index 100% rename from src/main/java/preponderous/viron/repositories/EntityRepositoryImpl.java rename to legacy/src/main/java/preponderous/viron/repositories/EntityRepositoryImpl.java diff --git a/src/main/java/preponderous/viron/repositories/EnvironmentRepository.java b/legacy/src/main/java/preponderous/viron/repositories/EnvironmentRepository.java similarity index 100% rename from src/main/java/preponderous/viron/repositories/EnvironmentRepository.java rename to legacy/src/main/java/preponderous/viron/repositories/EnvironmentRepository.java diff --git a/src/main/java/preponderous/viron/repositories/EnvironmentRepositoryImpl.java b/legacy/src/main/java/preponderous/viron/repositories/EnvironmentRepositoryImpl.java similarity index 100% rename from src/main/java/preponderous/viron/repositories/EnvironmentRepositoryImpl.java rename to legacy/src/main/java/preponderous/viron/repositories/EnvironmentRepositoryImpl.java diff --git a/src/main/java/preponderous/viron/repositories/GridRepository.java b/legacy/src/main/java/preponderous/viron/repositories/GridRepository.java similarity index 100% rename from src/main/java/preponderous/viron/repositories/GridRepository.java rename to legacy/src/main/java/preponderous/viron/repositories/GridRepository.java diff --git a/src/main/java/preponderous/viron/repositories/GridRepositoryImpl.java b/legacy/src/main/java/preponderous/viron/repositories/GridRepositoryImpl.java similarity index 100% rename from src/main/java/preponderous/viron/repositories/GridRepositoryImpl.java rename to legacy/src/main/java/preponderous/viron/repositories/GridRepositoryImpl.java diff --git a/src/main/java/preponderous/viron/repositories/LocationRepository.java b/legacy/src/main/java/preponderous/viron/repositories/LocationRepository.java similarity index 100% rename from src/main/java/preponderous/viron/repositories/LocationRepository.java rename to legacy/src/main/java/preponderous/viron/repositories/LocationRepository.java diff --git a/src/main/java/preponderous/viron/repositories/LocationRepositoryImpl.java b/legacy/src/main/java/preponderous/viron/repositories/LocationRepositoryImpl.java similarity index 100% rename from src/main/java/preponderous/viron/repositories/LocationRepositoryImpl.java rename to legacy/src/main/java/preponderous/viron/repositories/LocationRepositoryImpl.java diff --git a/src/main/java/preponderous/viron/services/EntityService.java b/legacy/src/main/java/preponderous/viron/services/EntityService.java similarity index 100% rename from src/main/java/preponderous/viron/services/EntityService.java rename to legacy/src/main/java/preponderous/viron/services/EntityService.java diff --git a/src/main/java/preponderous/viron/services/EnvironmentService.java b/legacy/src/main/java/preponderous/viron/services/EnvironmentService.java similarity index 100% rename from src/main/java/preponderous/viron/services/EnvironmentService.java rename to legacy/src/main/java/preponderous/viron/services/EnvironmentService.java diff --git a/src/main/java/preponderous/viron/services/GridService.java b/legacy/src/main/java/preponderous/viron/services/GridService.java similarity index 100% rename from src/main/java/preponderous/viron/services/GridService.java rename to legacy/src/main/java/preponderous/viron/services/GridService.java diff --git a/src/main/java/preponderous/viron/services/LocationService.java b/legacy/src/main/java/preponderous/viron/services/LocationService.java similarity index 100% rename from src/main/java/preponderous/viron/services/LocationService.java rename to legacy/src/main/java/preponderous/viron/services/LocationService.java diff --git a/src/main/python/preponderous/viron/models/__init__.py b/legacy/src/main/python/preponderous/viron/models/__init__.py similarity index 100% rename from src/main/python/preponderous/viron/models/__init__.py rename to legacy/src/main/python/preponderous/viron/models/__init__.py diff --git a/src/main/python/preponderous/viron/models/entity.py b/legacy/src/main/python/preponderous/viron/models/entity.py similarity index 100% rename from src/main/python/preponderous/viron/models/entity.py rename to legacy/src/main/python/preponderous/viron/models/entity.py diff --git a/src/main/python/preponderous/viron/models/environment.py b/legacy/src/main/python/preponderous/viron/models/environment.py similarity index 100% rename from src/main/python/preponderous/viron/models/environment.py rename to legacy/src/main/python/preponderous/viron/models/environment.py diff --git a/src/main/python/preponderous/viron/models/grid.py b/legacy/src/main/python/preponderous/viron/models/grid.py similarity index 100% rename from src/main/python/preponderous/viron/models/grid.py rename to legacy/src/main/python/preponderous/viron/models/grid.py diff --git a/src/main/python/preponderous/viron/models/location.py b/legacy/src/main/python/preponderous/viron/models/location.py similarity index 100% rename from src/main/python/preponderous/viron/models/location.py rename to legacy/src/main/python/preponderous/viron/models/location.py diff --git a/src/main/python/preponderous/viron/services/__init__.py b/legacy/src/main/python/preponderous/viron/services/__init__.py similarity index 100% rename from src/main/python/preponderous/viron/services/__init__.py rename to legacy/src/main/python/preponderous/viron/services/__init__.py diff --git a/src/main/python/preponderous/viron/services/entityService.py b/legacy/src/main/python/preponderous/viron/services/entityService.py similarity index 100% rename from src/main/python/preponderous/viron/services/entityService.py rename to legacy/src/main/python/preponderous/viron/services/entityService.py diff --git a/src/main/python/preponderous/viron/services/environmentService.py b/legacy/src/main/python/preponderous/viron/services/environmentService.py similarity index 100% rename from src/main/python/preponderous/viron/services/environmentService.py rename to legacy/src/main/python/preponderous/viron/services/environmentService.py diff --git a/src/main/python/preponderous/viron/services/gridService.py b/legacy/src/main/python/preponderous/viron/services/gridService.py similarity index 100% rename from src/main/python/preponderous/viron/services/gridService.py rename to legacy/src/main/python/preponderous/viron/services/gridService.py diff --git a/src/main/python/preponderous/viron/services/locationService.py b/legacy/src/main/python/preponderous/viron/services/locationService.py similarity index 100% rename from src/main/python/preponderous/viron/services/locationService.py rename to legacy/src/main/python/preponderous/viron/services/locationService.py diff --git a/src/main/resources/application.properties b/legacy/src/main/resources/application.properties similarity index 100% rename from src/main/resources/application.properties rename to legacy/src/main/resources/application.properties diff --git a/src/test/java/preponderous/viron/VironApplicationTest.java b/legacy/src/test/java/preponderous/viron/VironApplicationTest.java similarity index 100% rename from src/test/java/preponderous/viron/VironApplicationTest.java rename to legacy/src/test/java/preponderous/viron/VironApplicationTest.java diff --git a/src/test/java/preponderous/viron/config/DbConfigTest.java b/legacy/src/test/java/preponderous/viron/config/DbConfigTest.java similarity index 100% rename from src/test/java/preponderous/viron/config/DbConfigTest.java rename to legacy/src/test/java/preponderous/viron/config/DbConfigTest.java diff --git a/src/test/java/preponderous/viron/config/ServiceConfigTest.java b/legacy/src/test/java/preponderous/viron/config/ServiceConfigTest.java similarity index 100% rename from src/test/java/preponderous/viron/config/ServiceConfigTest.java rename to legacy/src/test/java/preponderous/viron/config/ServiceConfigTest.java diff --git a/src/test/java/preponderous/viron/controllers/DebugControllerTest.java b/legacy/src/test/java/preponderous/viron/controllers/DebugControllerTest.java similarity index 100% rename from src/test/java/preponderous/viron/controllers/DebugControllerTest.java rename to legacy/src/test/java/preponderous/viron/controllers/DebugControllerTest.java diff --git a/src/test/java/preponderous/viron/controllers/EntityControllerTest.java b/legacy/src/test/java/preponderous/viron/controllers/EntityControllerTest.java similarity index 100% rename from src/test/java/preponderous/viron/controllers/EntityControllerTest.java rename to legacy/src/test/java/preponderous/viron/controllers/EntityControllerTest.java diff --git a/src/test/java/preponderous/viron/controllers/EnvironmentControllerTest.java b/legacy/src/test/java/preponderous/viron/controllers/EnvironmentControllerTest.java similarity index 100% rename from src/test/java/preponderous/viron/controllers/EnvironmentControllerTest.java rename to legacy/src/test/java/preponderous/viron/controllers/EnvironmentControllerTest.java diff --git a/src/test/java/preponderous/viron/controllers/GridControllerTest.java b/legacy/src/test/java/preponderous/viron/controllers/GridControllerTest.java similarity index 100% rename from src/test/java/preponderous/viron/controllers/GridControllerTest.java rename to legacy/src/test/java/preponderous/viron/controllers/GridControllerTest.java diff --git a/src/test/java/preponderous/viron/controllers/LocationControllerTest.java b/legacy/src/test/java/preponderous/viron/controllers/LocationControllerTest.java similarity index 100% rename from src/test/java/preponderous/viron/controllers/LocationControllerTest.java rename to legacy/src/test/java/preponderous/viron/controllers/LocationControllerTest.java diff --git a/src/test/java/preponderous/viron/models/EntityTest.java b/legacy/src/test/java/preponderous/viron/models/EntityTest.java similarity index 100% rename from src/test/java/preponderous/viron/models/EntityTest.java rename to legacy/src/test/java/preponderous/viron/models/EntityTest.java diff --git a/src/test/java/preponderous/viron/models/EnvironmentTest.java b/legacy/src/test/java/preponderous/viron/models/EnvironmentTest.java similarity index 100% rename from src/test/java/preponderous/viron/models/EnvironmentTest.java rename to legacy/src/test/java/preponderous/viron/models/EnvironmentTest.java diff --git a/src/test/java/preponderous/viron/models/GridTest.java b/legacy/src/test/java/preponderous/viron/models/GridTest.java similarity index 100% rename from src/test/java/preponderous/viron/models/GridTest.java rename to legacy/src/test/java/preponderous/viron/models/GridTest.java diff --git a/src/test/java/preponderous/viron/models/LocationTest.java b/legacy/src/test/java/preponderous/viron/models/LocationTest.java similarity index 100% rename from src/test/java/preponderous/viron/models/LocationTest.java rename to legacy/src/test/java/preponderous/viron/models/LocationTest.java diff --git a/src/test/java/preponderous/viron/repositories/EntityRepositoryImplTest.java b/legacy/src/test/java/preponderous/viron/repositories/EntityRepositoryImplTest.java similarity index 100% rename from src/test/java/preponderous/viron/repositories/EntityRepositoryImplTest.java rename to legacy/src/test/java/preponderous/viron/repositories/EntityRepositoryImplTest.java diff --git a/src/test/python/preponderous/viron/models/test_entity.py b/legacy/src/test/python/preponderous/viron/models/test_entity.py similarity index 100% rename from src/test/python/preponderous/viron/models/test_entity.py rename to legacy/src/test/python/preponderous/viron/models/test_entity.py diff --git a/src/test/python/preponderous/viron/models/test_environment.py b/legacy/src/test/python/preponderous/viron/models/test_environment.py similarity index 100% rename from src/test/python/preponderous/viron/models/test_environment.py rename to legacy/src/test/python/preponderous/viron/models/test_environment.py diff --git a/src/test/python/preponderous/viron/models/test_grid.py b/legacy/src/test/python/preponderous/viron/models/test_grid.py similarity index 100% rename from src/test/python/preponderous/viron/models/test_grid.py rename to legacy/src/test/python/preponderous/viron/models/test_grid.py diff --git a/src/test/python/preponderous/viron/models/test_location.py b/legacy/src/test/python/preponderous/viron/models/test_location.py similarity index 100% rename from src/test/python/preponderous/viron/models/test_location.py rename to legacy/src/test/python/preponderous/viron/models/test_location.py diff --git a/src/test/python/preponderous/viron/services/test_entityService.py b/legacy/src/test/python/preponderous/viron/services/test_entityService.py similarity index 100% rename from src/test/python/preponderous/viron/services/test_entityService.py rename to legacy/src/test/python/preponderous/viron/services/test_entityService.py diff --git a/src/test/python/preponderous/viron/services/test_environmentService.py b/legacy/src/test/python/preponderous/viron/services/test_environmentService.py similarity index 100% rename from src/test/python/preponderous/viron/services/test_environmentService.py rename to legacy/src/test/python/preponderous/viron/services/test_environmentService.py diff --git a/src/test/python/preponderous/viron/services/test_gridService.py b/legacy/src/test/python/preponderous/viron/services/test_gridService.py similarity index 100% rename from src/test/python/preponderous/viron/services/test_gridService.py rename to legacy/src/test/python/preponderous/viron/services/test_gridService.py diff --git a/src/test/python/preponderous/viron/services/test_locationService.py b/legacy/src/test/python/preponderous/viron/services/test_locationService.py similarity index 100% rename from src/test/python/preponderous/viron/services/test_locationService.py rename to legacy/src/test/python/preponderous/viron/services/test_locationService.py diff --git a/mvnw b/mvnw old mode 100644 new mode 100755 index 19529dd..bd8896b --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.3.2 +# Apache Maven Wrapper startup batch script, version 3.3.4 # # Optional ENV vars # ----------------- @@ -105,14 +105,17 @@ trim() { printf "%s" "${1}" | tr -d '[:space:]' } +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + # parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties while IFS="=" read -r key value; do case "${key-}" in distributionUrl) distributionUrl=$(trim "${value-}") ;; distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; esac -done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" -[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" case "${distributionUrl##*/}" in maven-mvnd-*bin.*) @@ -130,7 +133,7 @@ maven-mvnd-*bin.*) distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" ;; maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; -*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; esac # apply MVNW_REPOURL and calculate MAVEN_HOME @@ -227,7 +230,7 @@ if [ -n "${distributionSha256Sum-}" ]; then echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 exit 1 elif command -v sha256sum >/dev/null; then - if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then distributionSha256Result=true fi elif command -v shasum >/dev/null; then @@ -252,8 +255,41 @@ if command -v unzip >/dev/null; then else tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" fi -printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" -mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" clean || : exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 249bdf3..5761d94 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,149 +1,189 @@ -<# : batch portion -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.3.2 -@REM -@REM Optional ENV vars -@REM MVNW_REPOURL - repo url base for downloading maven distribution -@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven -@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output -@REM ---------------------------------------------------------------------------- - -@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) -@SET __MVNW_CMD__= -@SET __MVNW_ERROR__= -@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% -@SET PSModulePath= -@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( - IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) -) -@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% -@SET __MVNW_PSMODULEP_SAVE= -@SET __MVNW_ARG0_NAME__= -@SET MVNW_USERNAME= -@SET MVNW_PASSWORD= -@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) -@echo Cannot start maven from wrapper >&2 && exit /b 1 -@GOTO :EOF -: end batch / begin powershell #> - -$ErrorActionPreference = "Stop" -if ($env:MVNW_VERBOSE -eq "true") { - $VerbosePreference = "Continue" -} - -# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties -$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl -if (!$distributionUrl) { - Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" -} - -switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { - "maven-mvnd-*" { - $USE_MVND = $true - $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" - $MVN_CMD = "mvnd.cmd" - break - } - default { - $USE_MVND = $false - $MVN_CMD = $script -replace '^mvnw','mvn' - break - } -} - -# apply MVNW_REPOURL and calculate MAVEN_HOME -# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ -if ($env:MVNW_REPOURL) { - $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } - $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" -} -$distributionUrlName = $distributionUrl -replace '^.*/','' -$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' -$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" -if ($env:MAVEN_USER_HOME) { - $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" -} -$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' -$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" - -if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { - Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" - Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" - exit $? -} - -if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { - Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" -} - -# prepare tmp dir -$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile -$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" -$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null -trap { - if ($TMP_DOWNLOAD_DIR.Exists) { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } - } -} - -New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null - -# Download and Install Apache Maven -Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." -Write-Verbose "Downloading from: $distributionUrl" -Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" - -$webclient = New-Object System.Net.WebClient -if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { - $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) -} -[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null - -# If specified, validate the SHA-256 sum of the Maven distribution zip file -$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum -if ($distributionSha256Sum) { - if ($USE_MVND) { - Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." - } - Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash - if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { - Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." - } -} - -# unzip and move -Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null -Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null -try { - Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null -} catch { - if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { - Write-Error "fail to move MAVEN_HOME" - } -} finally { - try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } - catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } -} - -Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.4 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/pom.xml b/pom.xml index 8d104b3..9f2425b 100644 --- a/pom.xml +++ b/pom.xml @@ -12,46 +12,74 @@ viron 0.6.0-SNAPSHOT viron - Environment manager + Foundational spatial simulation service - the bedrock on which worlds are built - 21 + 17 + 17 + 17 + 2.43.0 + org.springframework.boot - spring-boot-starter + spring-boot-starter-web - org.springframework.boot - spring-boot-starter-test - test + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-actuator + org.postgresql postgresql + runtime + - org.springframework.boot - spring-boot-starter-web + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.3.0 + org.projectlombok lombok 1.18.30 provided + + - org.springdoc - springdoc-openapi-starter-webmvc-ui - 2.3.0 + org.springframework.boot + spring-boot-starter-test + test - org.springframework.boot - spring-boot-starter-actuator + com.h2database + h2 + runtime + + + org.testcontainers + junit-jupiter + test + + + org.testcontainers + postgresql + test @@ -60,10 +88,39 @@ org.springframework.boot spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + ${java.version} + ${java.version} + + + org.projectlombok + lombok + 1.18.30 + + + + + org.jacoco jacoco-maven-plugin + 0.8.10 @@ -77,25 +134,54 @@ report + + check + + check + + + + + BUNDLE + + + INSTRUCTION + COVEREDRATIO + 0.80 + + + + + + + + - org.apache.maven.plugins - maven-compiler-plugin - 3.11.0 + com.diffplug.spotless + spotless-maven-plugin + ${spotless.version} - ${java.version} - ${java.version} - - - org.projectlombok - lombok - 1.18.30 - - + + + 1.17.0 + + + + + + + + + + check + + compile + + - - + \ No newline at end of file diff --git a/src/main/java/preponderous/viron/VironApplication.java b/src/main/java/preponderous/viron/VironApplication.java index 08b3307..5f96b52 100644 --- a/src/main/java/preponderous/viron/VironApplication.java +++ b/src/main/java/preponderous/viron/VironApplication.java @@ -1,21 +1,19 @@ -// Copyright (c) 2024 Preponderous Software -// MIT License - package preponderous.viron; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Import; - -import preponderous.viron.config.DbConfig; -import preponderous.viron.config.ServiceConfig; +/** + * Main application class for Viron - the foundational spatial simulation service. + * + *

Viron manages environments, grids, locations, and entities through a clean REST API, serving + * as a reusable backend component for simulation-based games, AI experiments, and virtual world + * applications. + */ @SpringBootApplication -@Import({DbConfig.class, ServiceConfig.class}) public class VironApplication { - public static void main(String[] args) { - SpringApplication.run(VironApplication.class, args); - } - + public static void main(String[] args) { + SpringApplication.run(VironApplication.class, args); + } } diff --git a/src/main/java/preponderous/viron/config/OpenApiConfig.java b/src/main/java/preponderous/viron/config/OpenApiConfig.java index f945645..2fd517c 100644 --- a/src/main/java/preponderous/viron/config/OpenApiConfig.java +++ b/src/main/java/preponderous/viron/config/OpenApiConfig.java @@ -1,17 +1,43 @@ package preponderous.viron.config; import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +/** + * Configuration for OpenAPI documentation. + * + *

This configuration sets up Swagger/OpenAPI documentation for the Viron API, providing + * interactive API documentation accessible via the Swagger UI. + */ @Configuration public class OpenApiConfig { - @Bean - public OpenAPI customOpenAPI() { - return new OpenAPI() - .info(new Info() - .title("Viron API") - .version("0.5.0")); - } -} \ No newline at end of file + + /** + * Creates the OpenAPI configuration bean. + * + * @return configured OpenAPI instance with application metadata + */ + @Bean + public OpenAPI vironOpenAPI() { + return new OpenAPI() + .info( + new Info() + .title("Viron API") + .description( + "Foundational spatial simulation service - the bedrock on which worlds are" + + " built. Manages environments, grids, locations, and entities through a" + + " clean REST API.") + .version("0.6.0-SNAPSHOT") + .contact( + new Contact() + .name("Preponderous Software") + .url("https://github.com/Preponderous-Software/Viron") + .email("support@preponderoussoftware.com")) + .license( + new License().name("MIT License").url("https://opensource.org/licenses/MIT"))); + } +} diff --git a/src/main/java/preponderous/viron/controllers/HealthController.java b/src/main/java/preponderous/viron/controllers/HealthController.java new file mode 100644 index 0000000..24e5df5 --- /dev/null +++ b/src/main/java/preponderous/viron/controllers/HealthController.java @@ -0,0 +1,43 @@ +package preponderous.viron.controllers; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.time.LocalDateTime; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Health check controller for monitoring application status. + * + *

Provides endpoints to verify that the Viron application is running and healthy. + */ +@RestController +@RequestMapping("/health") +@Tag(name = "Health", description = "Application health monitoring") +@Slf4j +public class HealthController { + + /** + * Basic health check endpoint. + * + * @return ResponseEntity with health status information + */ + @GetMapping + @Operation(summary = "Check application health", description = "Returns basic health status") + public ResponseEntity> health() { + log.debug("Health check requested"); + + Map health = + Map.of( + "status", "UP", + "timestamp", LocalDateTime.now(), + "service", "Viron Spatial Simulation Service", + "version", "0.6.0-SNAPSHOT"); + + return ResponseEntity.ok(health); + } +} diff --git a/src/main/java/preponderous/viron/dto/ErrorResponseDto.java b/src/main/java/preponderous/viron/dto/ErrorResponseDto.java new file mode 100644 index 0000000..137f8fb --- /dev/null +++ b/src/main/java/preponderous/viron/dto/ErrorResponseDto.java @@ -0,0 +1,33 @@ +package preponderous.viron.dto; + +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Data Transfer Object for error responses. + * + *

This DTO provides a consistent structure for error responses across all API endpoints, + * including timestamp, status code, error message, and request path. + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ErrorResponseDto { + + /** Timestamp when the error occurred. */ + private LocalDateTime timestamp; + + /** HTTP status code. */ + private int status; + + /** Brief error description. */ + private String error; + + /** Detailed error message. */ + private String message; + + /** Request path where error occurred. */ + private String path; +} diff --git a/src/main/java/preponderous/viron/exceptions/BusinessLogicException.java b/src/main/java/preponderous/viron/exceptions/BusinessLogicException.java new file mode 100644 index 0000000..0fe8b8a --- /dev/null +++ b/src/main/java/preponderous/viron/exceptions/BusinessLogicException.java @@ -0,0 +1,29 @@ +package preponderous.viron.exceptions; + +/** + * Exception thrown when business logic constraints are violated. + * + *

This exception is used for cases where the request is technically valid but violates business + * rules, such as attempting to place an entity in a location that already contains another entity. + */ +public class BusinessLogicException extends VironException { + + /** + * Constructs a new BusinessLogicException with the specified detail message. + * + * @param message the detail message describing the business rule violation + */ + public BusinessLogicException(String message) { + super(message); + } + + /** + * Constructs a new BusinessLogicException with the specified detail message and cause. + * + * @param message the detail message describing the business rule violation + * @param cause the cause of this exception + */ + public BusinessLogicException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/preponderous/viron/exceptions/GlobalExceptionHandler.java b/src/main/java/preponderous/viron/exceptions/GlobalExceptionHandler.java new file mode 100644 index 0000000..4f27822 --- /dev/null +++ b/src/main/java/preponderous/viron/exceptions/GlobalExceptionHandler.java @@ -0,0 +1,123 @@ +package preponderous.viron.exceptions; + +import jakarta.servlet.http.HttpServletRequest; +import java.time.LocalDateTime; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import preponderous.viron.dto.ErrorResponseDto; + +/** + * Global exception handler for the Viron application. + * + *

This class provides centralized exception handling across the entire application, ensuring + * consistent error response formats and appropriate HTTP status codes. + */ +@RestControllerAdvice +@Slf4j +public class GlobalExceptionHandler { + + /** + * Handles ResourceNotFoundException and returns a 404 Not Found response. + * + * @param ex the ResourceNotFoundException + * @param request the HTTP request that caused the exception + * @return ResponseEntity with error details and 404 status + */ + @ExceptionHandler(ResourceNotFoundException.class) + public ResponseEntity handleResourceNotFound( + ResourceNotFoundException ex, HttpServletRequest request) { + log.warn("Resource not found: {}", ex.getMessage()); + + ErrorResponseDto errorResponse = + new ErrorResponseDto( + LocalDateTime.now(), + HttpStatus.NOT_FOUND.value(), + "Not Found", + ex.getMessage(), + request.getRequestURI()); + + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorResponse); + } + + /** + * Handles BusinessLogicException and returns a 400 Bad Request response. + * + * @param ex the BusinessLogicException + * @param request the HTTP request that caused the exception + * @return ResponseEntity with error details and 400 status + */ + @ExceptionHandler(BusinessLogicException.class) + public ResponseEntity handleBusinessLogicException( + BusinessLogicException ex, HttpServletRequest request) { + log.warn("Business logic violation: {}", ex.getMessage()); + + ErrorResponseDto errorResponse = + new ErrorResponseDto( + LocalDateTime.now(), + HttpStatus.BAD_REQUEST.value(), + "Bad Request", + ex.getMessage(), + request.getRequestURI()); + + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse); + } + + /** + * Handles validation errors from request body validation. + * + * @param ex the MethodArgumentNotValidException + * @param request the HTTP request that caused the exception + * @return ResponseEntity with error details and 400 status + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity handleValidationException( + MethodArgumentNotValidException ex, HttpServletRequest request) { + log.warn("Validation error: {}", ex.getMessage()); + + String message = "Validation failed"; + if (ex.getBindingResult().hasFieldErrors()) { + message = + ex.getBindingResult().getFieldErrors().stream() + .map(error -> error.getField() + ": " + error.getDefaultMessage()) + .reduce((a, b) -> a + "; " + b) + .orElse("Validation failed"); + } + + ErrorResponseDto errorResponse = + new ErrorResponseDto( + LocalDateTime.now(), + HttpStatus.BAD_REQUEST.value(), + "Bad Request", + message, + request.getRequestURI()); + + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse); + } + + /** + * Handles all other unexpected exceptions and returns a 500 Internal Server Error response. + * + * @param ex the unexpected exception + * @param request the HTTP request that caused the exception + * @return ResponseEntity with error details and 500 status + */ + @ExceptionHandler(Exception.class) + public ResponseEntity handleGenericException( + Exception ex, HttpServletRequest request) { + log.error("Unexpected error occurred", ex); + + ErrorResponseDto errorResponse = + new ErrorResponseDto( + LocalDateTime.now(), + HttpStatus.INTERNAL_SERVER_ERROR.value(), + "Internal Server Error", + "An unexpected error occurred. Please try again later.", + request.getRequestURI()); + + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse); + } +} diff --git a/src/main/java/preponderous/viron/exceptions/ResourceNotFoundException.java b/src/main/java/preponderous/viron/exceptions/ResourceNotFoundException.java new file mode 100644 index 0000000..d570976 --- /dev/null +++ b/src/main/java/preponderous/viron/exceptions/ResourceNotFoundException.java @@ -0,0 +1,29 @@ +package preponderous.viron.exceptions; + +/** + * Exception thrown when a requested resource cannot be found. + * + *

This exception is typically thrown when attempting to retrieve an entity by ID that doesn't + * exist in the system. + */ +public class ResourceNotFoundException extends VironException { + + /** + * Constructs a new ResourceNotFoundException with the specified detail message. + * + * @param message the detail message explaining which resource was not found + */ + public ResourceNotFoundException(String message) { + super(message); + } + + /** + * Constructs a new ResourceNotFoundException with the specified detail message and cause. + * + * @param message the detail message explaining which resource was not found + * @param cause the cause of this exception + */ + public ResourceNotFoundException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/preponderous/viron/exceptions/VironException.java b/src/main/java/preponderous/viron/exceptions/VironException.java new file mode 100644 index 0000000..0ac2146 --- /dev/null +++ b/src/main/java/preponderous/viron/exceptions/VironException.java @@ -0,0 +1,29 @@ +package preponderous.viron.exceptions; + +/** + * Base exception class for all Viron-specific exceptions. + * + *

This class serves as the root of the Viron exception hierarchy, providing a common base for + * all custom exceptions in the application. + */ +public abstract class VironException extends RuntimeException { + + /** + * Constructs a new VironException with the specified detail message. + * + * @param message the detail message explaining the reason for the exception + */ + protected VironException(String message) { + super(message); + } + + /** + * Constructs a new VironException with the specified detail message and cause. + * + * @param message the detail message explaining the reason for the exception + * @param cause the cause of this exception + */ + protected VironException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..d5578ce --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,107 @@ +spring: + application: + name: viron + + profiles: + active: dev + + # Database Configuration + datasource: + url: jdbc:postgresql://localhost:5432/viron + username: viron + password: password + driver-class-name: org.postgresql.Driver + + # JPA Configuration + jpa: + hibernate: + ddl-auto: create-drop + show-sql: false + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect + format_sql: true + + # API Documentation + springdoc: + api-docs: + path: /api-docs + swagger-ui: + path: /swagger-ui.html + +# Logging Configuration +logging: + level: + root: INFO + preponderous.viron: DEBUG + org.springframework.web: DEBUG + org.hibernate.SQL: DEBUG + org.hibernate.type.descriptor.sql.BasicBinder: TRACE + pattern: + console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" + file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" + file: + name: logs/viron.log + +# Management & Actuator +management: + endpoints: + web: + exposure: + include: health,info,metrics + endpoint: + health: + show-details: when_authorized + +# Server Configuration +server: + port: 8080 + servlet: + context-path: /api/v1 + +--- +# Production Profile +spring: + config: + activate: + on-profile: prod + + jpa: + hibernate: + ddl-auto: validate + show-sql: false + + datasource: + url: ${DATABASE_URL:jdbc:postgresql://localhost:5432/viron} + username: ${DATABASE_USERNAME:viron} + password: ${DATABASE_PASSWORD:password} + +logging: + level: + root: WARN + preponderous.viron: INFO + file: + name: /var/log/viron/viron.log + +--- +# Test Profile +spring: + config: + activate: + on-profile: test + + datasource: + url: jdbc:h2:mem:testdb + driver-class-name: org.h2.Driver + username: sa + password: password + + jpa: + hibernate: + ddl-auto: create-drop + database-platform: org.hibernate.dialect.H2Dialect + +logging: + level: + root: ERROR + preponderous.viron: DEBUG \ No newline at end of file diff --git a/src/test/java/preponderous/viron/VironApplicationTests.java b/src/test/java/preponderous/viron/VironApplicationTests.java new file mode 100644 index 0000000..65ac87f --- /dev/null +++ b/src/test/java/preponderous/viron/VironApplicationTests.java @@ -0,0 +1,15 @@ +package preponderous.viron; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +@SpringBootTest +@ActiveProfiles("test") +class VironApplicationTests { + + @Test + void contextLoads() { + // This test verifies that the Spring application context loads successfully + } +} diff --git a/src/test/java/preponderous/viron/controllers/HealthControllerTest.java b/src/test/java/preponderous/viron/controllers/HealthControllerTest.java new file mode 100644 index 0000000..2e1d731 --- /dev/null +++ b/src/test/java/preponderous/viron/controllers/HealthControllerTest.java @@ -0,0 +1,26 @@ +package preponderous.viron.controllers; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.web.servlet.MockMvc; + +@WebMvcTest(HealthController.class) +class HealthControllerTest { + + @Autowired private MockMvc mockMvc; + + @Test + void healthEndpointReturnsUpStatus() throws Exception { + mockMvc + .perform(get("/health")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.status").value("UP")) + .andExpect(jsonPath("$.service").value("Viron Spatial Simulation Service")) + .andExpect(jsonPath("$.version").value("0.6.0-SNAPSHOT")); + } +}