diff --git a/.github/workflows/JavaMavenCI.yml b/.github/workflows/JavaMavenCI.yml new file mode 100644 index 0000000..690e6e9 --- /dev/null +++ b/.github/workflows/JavaMavenCI.yml @@ -0,0 +1,114 @@ +name: Java CI with Maven + +on: + pull_request: + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: maven + - name: Compile with maven + run: mvn clean compile + + - name: Update dependency graph + uses: advanced-security/maven-dependency-submission-action@571e99aab1055c2e71a1e2309b9691de18d6b7d6 + + checkstyle: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: maven + - name: Compile with maven + run: mvn checkstyle:check + + testing: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: maven + - name: Compile maven project + run: mvn clean compile + - name: Test maven project + run: mvn test + - name: Add coverage to PR + id: jacoco + uses: madrapps/jacoco-report@v1.6.1 + with: + paths: | + ${{ github.workspace }}/**/target/site/jacoco/*.xml + token: ${{ secrets.TEST_SECRET }} + min-coverage-overall: 50 + min-coverage-changed-files: 50 + - name: Upload coverage report + uses: actions/upload-artifact@v4 + with: + name: jacoco-report + path: ${{ github.workspace }}/**/target/site/jacoco/ + + - name: Fail PR if overall coverage is less than 50% + if: ${{ steps.jacoco.outputs.coverage-overall < 50.0 }} + uses: actions/github-script@v6 + with: + script: | + core.setFailed('Overall coverage is less than 50%!') + + docker: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v4 + - + name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + cache: maven + - + name: Package + run: mvn clean package + - + name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - + name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + - + name: Build and push + uses: docker/build-push-action@v5 + with: + context: ./api/. + push: true + tags: asavershin/api:latest diff --git a/api/Dockerfile b/api/Dockerfile index fd4a080..79aace5 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:22 +FROM openjdk:21 WORKDIR /app diff --git a/api/pom.xml b/api/pom.xml index 38e9914..8fbee14 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -12,8 +12,8 @@ api - 22 - 22 + 21 + 21 UTF-8 3.19.3 2.1.0 diff --git a/api/src/main/java/com/github/asavershin/api/application/in/services/image/impl/ImageServiceImpl.java b/api/src/main/java/com/github/asavershin/api/application/in/services/image/impl/ImageServiceImpl.java index 0dcfe82..eb2fc9a 100644 --- a/api/src/main/java/com/github/asavershin/api/application/in/services/image/impl/ImageServiceImpl.java +++ b/api/src/main/java/com/github/asavershin/api/application/in/services/image/impl/ImageServiceImpl.java @@ -17,7 +17,6 @@ import java.io.Serializable; import java.util.List; -import java.util.UUID; @Service @RequiredArgsConstructor @@ -63,10 +62,7 @@ public ImageId storeImage(final UserId userId, ), multipartFile.getSize() ); - // TODO Why minio service store before postgreSQL? - var imageId = new ImageId( - UUID.fromString(minioService.saveFile(multipartFile)) - ); + var imageId = ImageId.nextIdentity(); storeImageOfUser.storeImageOfUser( new Image( imageId, @@ -74,6 +70,7 @@ public ImageId storeImage(final UserId userId, userId ) ); + minioService.saveFile(multipartFile, imageId.value().toString()); return imageId; } diff --git a/api/src/main/java/com/github/asavershin/api/application/out/FileService.java b/api/src/main/java/com/github/asavershin/api/application/out/FileService.java index 03d3d05..2691519 100644 --- a/api/src/main/java/com/github/asavershin/api/application/out/FileService.java +++ b/api/src/main/java/com/github/asavershin/api/application/out/FileService.java @@ -2,14 +2,15 @@ import java.util.List; -public interface FileService { +public interface FileService { /** * Saves a file to the storage. * - * @param file The file object to be saved. - * @return The saved file object. + * @param file The file object to be saved. + * @param filename The name of the file to be saved. + * Must be unique. */ - T saveFile(K file); + void saveFile(K file, String filename); /** * Retrieves the content of a file from the storage. * diff --git a/api/src/main/java/com/github/asavershin/api/application/out/MinioService.java b/api/src/main/java/com/github/asavershin/api/application/out/MinioService.java index 5fb906e..93835cb 100644 --- a/api/src/main/java/com/github/asavershin/api/application/out/MinioService.java +++ b/api/src/main/java/com/github/asavershin/api/application/out/MinioService.java @@ -2,5 +2,5 @@ import org.springframework.web.multipart.MultipartFile; -public interface MinioService extends FileService { +public interface MinioService extends FileService { } diff --git a/api/src/main/java/com/github/asavershin/api/infrastructure/out/storage/MinioServiceIml.java b/api/src/main/java/com/github/asavershin/api/infrastructure/out/storage/MinioServiceIml.java index 87454b2..055f46b 100644 --- a/api/src/main/java/com/github/asavershin/api/infrastructure/out/storage/MinioServiceIml.java +++ b/api/src/main/java/com/github/asavershin/api/infrastructure/out/storage/MinioServiceIml.java @@ -16,7 +16,6 @@ import java.io.InputStream; import java.util.List; -import java.util.UUID; @Service public class MinioServiceIml implements MinioService { @@ -47,7 +46,7 @@ public MinioServiceIml(final MinioClient aMinioClient, * Not final to allow spring use proxy. */ @Override - public String saveFile(final MultipartFile image) { + public void saveFile(final MultipartFile image, final String filename) { if (!bucketExists(minioProperties.getBucket())) { throw new FileException( @@ -58,7 +57,6 @@ public String saveFile(final MultipartFile image) { if (image.isEmpty() || image.getOriginalFilename() == null) { throw new FileException("File must have name"); } - var link = generateFileName(); InputStream inputStream; try { inputStream = image.getInputStream(); @@ -66,8 +64,7 @@ public String saveFile(final MultipartFile image) { throw new FileException("File upload failed: " + e.getMessage()); } - saveImage(inputStream, link); - return link; + saveFile(inputStream, filename); } /** * Not final to allow spring use proxy. @@ -124,7 +121,7 @@ private void createBucket() { } @SneakyThrows - private void saveImage( + private void saveFile( final InputStream inputStream, final String fileName ) { @@ -135,10 +132,6 @@ private void saveImage( .build()); } - private String generateFileName() { - return UUID.randomUUID().toString(); - } - @SneakyThrows(Exception.class) private boolean bucketExists(final String bucketName) { return minioClient.bucketExists( diff --git a/pom.xml b/pom.xml index ebe7e31..8a09635 100644 --- a/pom.xml +++ b/pom.xml @@ -19,8 +19,8 @@ - 22 - 22 + 21 + 21 UTF-8 1.18.30 3.3.1