diff --git a/.gitignore b/.gitignore index 9154f4c..a1e1908 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,39 @@ -# ---> Java -# Compiled class file -*.class +.gradle +gradlew +gradlew.bat +build/ +gradle/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ -# Log file -*.log +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ -# BlueJ files -*.ctxt +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* -replay_pid* +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +### VS Code ### +.vscode/ diff --git a/.run/Generate From OAS.run.xml b/.run/Generate From OAS.run.xml new file mode 100644 index 0000000..905dd5c --- /dev/null +++ b/.run/Generate From OAS.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/Postgres.run.xml b/.run/Postgres.run.xml new file mode 100644 index 0000000..e479381 --- /dev/null +++ b/.run/Postgres.run.xml @@ -0,0 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/.run/Run.run.xml b/.run/Run.run.xml new file mode 100644 index 0000000..057162a --- /dev/null +++ b/.run/Run.run.xml @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/.run/Validate OAS.run.xml b/.run/Validate OAS.run.xml new file mode 100644 index 0000000..694f324 --- /dev/null +++ b/.run/Validate OAS.run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/LICENSE b/License.md similarity index 100% rename from LICENSE rename to License.md diff --git a/README.md b/Readme.md similarity index 100% rename from README.md rename to Readme.md diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..0789034 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,84 @@ +import org.hidetake.gradle.swagger.generator.GenerateSwaggerCode + +repositories { + mavenCentral() +} + +plugins { + java + id("org.springframework.boot") version "3.3.3" + id("io.spring.dependency-management") version "1.1.6" + id("org.hidetake.swagger.generator") version "2.19.2" +} + +group = "de.hmmh" +version = "0.0.1-SNAPSHOT" + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(22) + } +} + +configurations { + compileOnly { + extendsFrom(configurations.annotationProcessor.get()) + } +} + +dependencies { + //Spring + implementation("org.springframework.boot:spring-boot-starter-data-jpa") + implementation("org.springframework.boot:spring-boot-starter-validation") + implementation("org.springframework.boot:spring-boot-starter-web") + runtimeOnly("org.postgresql:postgresql") + + //Lombok + compileOnly("org.projectlombok:lombok") + annotationProcessor("org.projectlombok:lombok") + + //Test + testImplementation("org.springframework.boot:spring-boot-starter-test") + testImplementation("org.springframework.boot:spring-boot-testcontainers") + testImplementation("org.testcontainers:junit-jupiter") + testImplementation("org.testcontainers:postgresql") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + + //OAS + swaggerCodegen("org.openapitools:openapi-generator-cli:7.8.0") + implementation("io.swagger.core.v3:swagger-annotations:2.2.22") +} + +swaggerSources { + register("pmt") { + setInputFile(file("${rootDir}/src/main/resources/api.yml")) + code.configFile = file("${rootDir}/src/main/resources/gen-config.json") + val validationTask = validation + code(delegateClosureOf { + language = "spring" + components = listOf("models", "apis", "supportingFiles=ApiUtil.java") + code.rawOptions = listOf("--ignore-file-override=" + file("${rootDir}/src/main/resources/.codegen-ignore").absolutePath) + dependsOn(validationTask) + }) + } +} + +tasks { + processResources { + dependsOn(generateSwaggerCode) + } + withType { + useJUnitPlatform() + } + named("compileJava").configure { + dependsOn(swaggerSources.getByName("pmt").code) + } +} + + +sourceSets { + main { + java.srcDir("${swaggerSources.getByName("pmt").code.outputDir}/src/main/java") + resources.srcDir("${swaggerSources.getByName("pmt").code.outputDir}/src/main/resources") + } +} diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..8a2c65d --- /dev/null +++ b/compose.yml @@ -0,0 +1,16 @@ +services: + postgres: + container_name: pmt_postgres + image: postgres:16 + environment: + - POSTGRES_DB=pmt + - POSTGRES_USER=pmt_user + - POSTGRES_PASSWORD=pmt123 + ports: + - "5432:5432" + volumes: + - "pmt_data:/var/lib/postgresql/data" + +volumes: + pmt_data: + name: pmt_data \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..f91d38c --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "Project Management Tool" diff --git a/src/main/java/de/hmmh/pmt/ApiController.java b/src/main/java/de/hmmh/pmt/ApiController.java new file mode 100644 index 0000000..5a242a9 --- /dev/null +++ b/src/main/java/de/hmmh/pmt/ApiController.java @@ -0,0 +1,19 @@ +package de.hmmh.pmt; + +import de.hmmh.pmt.oas.DefaultApi; +import de.hmmh.pmt.oas.HelloOut; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +@RequestMapping("${openapi.projectManagement.base-path:/api/v1}") +public class ApiController implements DefaultApi { + + @Override + public ResponseEntity getHello() throws Exception { + HelloOut hello = new HelloOut(); + hello.setMsg("Hello World"); + return ResponseEntity.ok(hello); + } +} diff --git a/src/main/java/de/hmmh/pmt/ProjectManagementToolApplication.java b/src/main/java/de/hmmh/pmt/ProjectManagementToolApplication.java new file mode 100644 index 0000000..0e72b54 --- /dev/null +++ b/src/main/java/de/hmmh/pmt/ProjectManagementToolApplication.java @@ -0,0 +1,13 @@ +package de.hmmh.pmt; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ProjectManagementToolApplication { + + public static void main(String[] args) { + SpringApplication.run(ProjectManagementToolApplication.class, args); + } + +} diff --git a/src/main/java/de/hmmh/pmt/oas/.gitkeep b/src/main/java/de/hmmh/pmt/oas/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/.codegen-ignore b/src/main/resources/.codegen-ignore new file mode 100644 index 0000000..f71569b --- /dev/null +++ b/src/main/resources/.codegen-ignore @@ -0,0 +1,2 @@ +**/*ApiController.java +**/org/openapitools/configuration/ \ No newline at end of file diff --git a/src/main/resources/api.yml b/src/main/resources/api.yml new file mode 100644 index 0000000..7e46e48 --- /dev/null +++ b/src/main/resources/api.yml @@ -0,0 +1,43 @@ +openapi: 3.0.0 +info: + title: Project Management API + description: An API for Managing Internal tools + version: 1.0.0 +servers: + - url: /api/v1 + +components: + schemas: + HelloOut: + description: "A Test Schema" + type: object + properties: + msg: + type: string + responses: + OK: + description: "OK" + content: + text/plain: + schema: + type: string + InternalError: + description: "Internal Server Error" + content: + text/plain: + schema: + type: string +paths: + /hello: + get: + operationId: "GetHello" + description: "A Simple Hello World Endpoint" + responses: + 200: + description: "A Hello Response" + content: + application/json: + schema: + $ref: "#/components/schemas/HelloOut" + 500: + $ref: "#/components/responses/InternalError" \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..676a110 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,9 @@ +# General +spring.application.name=Project Management Tool +server.port=8080 + +# DB +spring.datasource.url=jdbc:postgresql://localhost:5432/pmt +spring.datasource.username=pmt_user +spring.datasource.password=pmt123 +spring.jpa.hibernate.ddl-auto=create-drop \ No newline at end of file diff --git a/src/main/resources/gen-config.json b/src/main/resources/gen-config.json new file mode 100644 index 0000000..bf797af --- /dev/null +++ b/src/main/resources/gen-config.json @@ -0,0 +1,20 @@ +{ + "library": "spring-boot", + "dateLibrary": "java8", + "hideGenerationTimestamp": true, + "modelPackage": "de.hmmh.pmt.oas", + "apiPackage": "de.hmmh.pmt.oas", + "invokerPackage": "de.hmmh.pmt.oas", + "serializableModel": true, + "openApiNullable": false, + "useTags": true, + "useGzipFeature": true, + "unhandledException": true, + "useSpringBoot3": true, + "useSwaggerUI": true, + "importMappings": { + "ResourceSupport": "org.springframework.hateoas.RepresentationModel", + "Link": "org.springframework.hateoas.Link" + } +} + diff --git a/src/test/java/de/hmmh/pmt/IntegrationTest.java b/src/test/java/de/hmmh/pmt/IntegrationTest.java new file mode 100644 index 0000000..3683a7b --- /dev/null +++ b/src/test/java/de/hmmh/pmt/IntegrationTest.java @@ -0,0 +1,26 @@ +package de.hmmh.pmt; + +import org.junit.jupiter.api.BeforeEach; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.servlet.MockMvc; + +@SpringBootTest +@AutoConfigureMockMvc +@ActiveProfiles("test") +@ContextConfiguration(initializers = PostgresContextInitializer.class) +public abstract class IntegrationTest { + + @Autowired + protected MockMvc mockMvc; + + //protected Repository repository; + + @BeforeEach + void setUp() { + //repository.deleteAll(); + } +} \ No newline at end of file diff --git a/src/test/java/de/hmmh/pmt/PostgresContextInitializer.java b/src/test/java/de/hmmh/pmt/PostgresContextInitializer.java new file mode 100644 index 0000000..4a4163e --- /dev/null +++ b/src/test/java/de/hmmh/pmt/PostgresContextInitializer.java @@ -0,0 +1,28 @@ +package de.hmmh.pmt; + +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.utility.DockerImageName; + +public class PostgresContextInitializer implements ApplicationContextInitializer { + + private static final PostgreSQLContainer postgres = new PostgreSQLContainer<>( + DockerImageName.parse("postgres:16") + ) + .withDatabaseName("test_db") + .withUsername("test-db-user") + .withPassword("test-db-password") + .withReuse(true); + + public void initialize(ConfigurableApplicationContext configurableApplicationContext) { + postgres.start(); + + TestPropertyValues.of( + "spring.datasource.url=" + postgres.getJdbcUrl(), + "spring.datasource.username=" + postgres.getUsername(), + "spring.datasource.password=" + postgres.getPassword() + ).applyTo(configurableApplicationContext.getEnvironment()); + } +} \ No newline at end of file diff --git a/src/test/resources/application-test.properties b/src/test/resources/application-test.properties new file mode 100644 index 0000000..b8de14f --- /dev/null +++ b/src/test/resources/application-test.properties @@ -0,0 +1,3 @@ +spring.datasource.url=set_by_test_containers +spring.datasource.username=set_by_test_containers +spring.datasource.password=set_by_test_containers \ No newline at end of file