From 88b886ffab6533c1a3714d95697f0d7b2aa56d07 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen <127725498+ntqdinh-axonivy@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:50:44 +0700 Subject: [PATCH 1/9] bugfix/MARP-694-Feedback-Anais-5-Language-switcher --- .../header/language-selection/language-selection.component.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/marketplace-ui/src/app/shared/components/header/language-selection/language-selection.component.scss b/marketplace-ui/src/app/shared/components/header/language-selection/language-selection.component.scss index a9b5a469d..d201fe9f8 100644 --- a/marketplace-ui/src/app/shared/components/header/language-selection/language-selection.component.scss +++ b/marketplace-ui/src/app/shared/components/header/language-selection/language-selection.component.scss @@ -15,4 +15,5 @@ .language-item.inactive { color: #757575; + font-weight: 400; } From 60bbdc118c5a6f76588324e0dc30bd01187e4ac8 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen <127725498+ntqdinh-axonivy@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:13:23 +0700 Subject: [PATCH 2/9] bugfix/MARP-696-Feedback-Anais-7-Size-of-Stars --- .../shared/components/star-rating/star-rating.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/marketplace-ui/src/app/shared/components/star-rating/star-rating.component.scss b/marketplace-ui/src/app/shared/components/star-rating/star-rating.component.scss index 2e994a517..f1a2f4b7b 100644 --- a/marketplace-ui/src/app/shared/components/star-rating/star-rating.component.scss +++ b/marketplace-ui/src/app/shared/components/star-rating/star-rating.component.scss @@ -19,7 +19,7 @@ } .adding-feedback-star { - font-size: 2.5rem; + font-size: 2.25rem; color: #dfdfdf; margin-right: 15px; .filled { From b92ce877f03a20fa9ad037e2ee4763e33da93ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=E1=BA=A7n=20V=C4=A9nh=20Thi=E1=BB=87n=20Ph=C3=BAc?= <143604440+tvtphuc-axonivy@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:26:54 +0700 Subject: [PATCH 3/9] Feature/marp 693 feedback anais 4 adjustment for search (#45) --- .../product/product-filter/product-filter.component.html | 4 ++-- .../product/product-filter/product-filter.component.scss | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/marketplace-ui/src/app/modules/product/product-filter/product-filter.component.html b/marketplace-ui/src/app/modules/product/product-filter/product-filter.component.html index e7679f254..f63101c8b 100644 --- a/marketplace-ui/src/app/modules/product/product-filter/product-filter.component.html +++ b/marketplace-ui/src/app/modules/product/product-filter/product-filter.component.html @@ -63,7 +63,7 @@

+ class="input-group-text text-primary bg-secondary h-100 border-0 rounded-end-0">
@@ -71,7 +71,7 @@

[(ngModel)]="searchText" (ngModelChange)="onSearchChanged($event)" type="text" - class="form-control input__search bg-secondary border-0 rounded-end-4 rounded-start-0 search-input" + class="form-control input__search bg-secondary border-0 rounded-start-0 ps-0 search-input" [placeholder]="translateService.get('common.search.placeholder') | async" [ariaLabel]="translateService.get('common.search.placeholder') | async" aria-describedby="search"/> diff --git a/marketplace-ui/src/app/modules/product/product-filter/product-filter.component.scss b/marketplace-ui/src/app/modules/product/product-filter/product-filter.component.scss index df6c488d0..2f6af7cb1 100644 --- a/marketplace-ui/src/app/modules/product/product-filter/product-filter.component.scss +++ b/marketplace-ui/src/app/modules/product/product-filter/product-filter.component.scss @@ -1,5 +1,14 @@ $rowHeight: 37px; +.input-group-text { + border-radius: 10px; + padding: 0 15px; +} + +.form-control { + border-radius: 10px; +} + .filter-container { height: $rowHeight; } From 2bb6a994f6ee32e63426540ac0b09a286ad87ae8 Mon Sep 17 00:00:00 2001 From: Hoan Nguyen <83745591+nqhoan-axonivy@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:30:10 +0700 Subject: [PATCH 4/9] MARP-224 Create dockerfiles for deployment of marketplace (#30) Co-authored-by: Hoan Nguyen Co-authored-by: ivyTeam Co-authored-by: tutn Co-authored-by: Dinh Nguyen --- .github/workflows/docker-build.yml | 40 ++++++++++++++ .github/workflows/docker-release.yml | 49 +++++++++++++++++ .github/workflows/service-ci-build.yml | 2 + .github/workflows/service-dev-build.yml | 42 --------------- .github/workflows/ui-ci-build.yml | 24 ++++++--- .github/workflows/ui-dev-build.yml | 28 ---------- README.md | 37 ++++--------- marketplace-build/.dockerignore | 2 + marketplace-build/.env | 8 +++ marketplace-build/Dockerfile | 1 - .../Marketplace Tomcat v10.1 Server.launch | 5 +- marketplace-build/README.md | 33 ++++++++++++ marketplace-build/config/mongodb/Dockerfile | 11 ++++ .../config/mongodb/docker-compose.yml | 18 +++++++ .../config/mongodb/mongo-init.js | 12 +++++ marketplace-build/config/mongodb/mongod.conf | 5 ++ marketplace-build/config/nginx/nginx.conf | 12 +++++ .../dev/sonar/docker-compose.yml | 44 +++++++++++++++ marketplace-build/dev/sonar/init-db.sh | 7 +++ marketplace-build/dev/sonar/init.sh | 2 + marketplace-build/docker-compose.yml | 54 ++++++++++++++++++- marketplace-build/release/.env | 8 +++ marketplace-build/release/docker-compose.yml | 37 +++++++++++++ marketplace-build/release/sprint-compose.yml | 37 +++++++++++++ marketplace-service/.dockerignore | 33 ++++++++++++ marketplace-service/Dockerfile | 21 ++++++++ .../axonivy/market/config/MongoConfig.java | 15 +++--- .../com/axonivy/market/config/WebConfig.java | 9 ++-- .../market/controller/ProductController.java | 22 ++++---- .../market/github/model/GitHubProperty.java | 20 +++++++ .../service/impl/GitHubServiceImpl.java | 40 +++++++------- .../src/main/resources/application.properties | 7 +-- .../src/main/resources/github.token | 1 - marketplace-ui/.dockerignore | 5 ++ marketplace-ui/Dockerfile | 11 ++++ .../src/environments/environment.ts | 3 +- 36 files changed, 550 insertions(+), 155 deletions(-) create mode 100644 .github/workflows/docker-build.yml create mode 100644 .github/workflows/docker-release.yml delete mode 100644 .github/workflows/service-dev-build.yml delete mode 100644 .github/workflows/ui-dev-build.yml create mode 100644 marketplace-build/.dockerignore create mode 100644 marketplace-build/.env delete mode 100644 marketplace-build/Dockerfile create mode 100644 marketplace-build/README.md create mode 100644 marketplace-build/config/mongodb/Dockerfile create mode 100644 marketplace-build/config/mongodb/docker-compose.yml create mode 100644 marketplace-build/config/mongodb/mongo-init.js create mode 100644 marketplace-build/config/mongodb/mongod.conf create mode 100644 marketplace-build/config/nginx/nginx.conf create mode 100644 marketplace-build/dev/sonar/docker-compose.yml create mode 100644 marketplace-build/dev/sonar/init-db.sh create mode 100644 marketplace-build/dev/sonar/init.sh create mode 100644 marketplace-build/release/.env create mode 100644 marketplace-build/release/docker-compose.yml create mode 100644 marketplace-build/release/sprint-compose.yml create mode 100644 marketplace-service/.dockerignore create mode 100644 marketplace-service/Dockerfile create mode 100644 marketplace-service/src/main/java/com/axonivy/market/github/model/GitHubProperty.java delete mode 100644 marketplace-service/src/main/resources/github.token create mode 100644 marketplace-ui/.dockerignore create mode 100644 marketplace-ui/Dockerfile diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 000000000..bbe173702 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,40 @@ +name: Docker Build + +on: + push: + branches: [ "develop" ] + workflow_dispatch: + workflow_call: + +jobs: + build: + runs-on: self-hosted + + steps: + - uses: actions/checkout@v4 + - name: Update environment variables for .env + env: + ENV_FILE: './marketplace-build/.env' + MONGODB_HOST: ${{ secrets.MONGODB_HOST }} + ROOT_USERNAME: ${{ secrets.MONGODB_ROOT_USERNAME }} + ROOT_PASSWORD: ${{ secrets.MONGODB_ROOT_PASSWORD }} + SERVICE_USERNAME: ${{ secrets.SERVICE_USERNAME }} + SERVICE_PASSWORD: ${{ secrets.SERVICE_PASSWORD }} + MONGODB_DATABASE: ${{ secrets.MONGODB_DATABASE }} + GH_TOKEN: ${{ secrets.GH_TOKEN }} + MARKETPLACE_INSTALLATION_URL: ${{ secrets.MARKETPLACE_INSTALLATION_URL }} + run: | + sed -i "s/^MONGODB_INITDB_ROOT_USERNAME=.*$/MONGODB_INITDB_ROOT_USERNAME=$ROOT_USERNAME/" $ENV_FILE + sed -i "s/^MONGODB_INITDB_ROOT_PASSWORD=.*$/MONGODB_INITDB_ROOT_PASSWORD=$ROOT_PASSWORD/" $ENV_FILE + sed -i "s/^SERVICE_MONGODB_HOST=.*$/SERVICE_MONGODB_HOST=$MONGODB_HOST/" $ENV_FILE + sed -i "s/^SERVICE_MONGODB_DATABASE=.*$/SERVICE_MONGODB_DATABASE=$MONGODB_DATABASE/" $ENV_FILE + sed -i "s/^SERVICE_MONGODB_USER=.*$/SERVICE_MONGODB_USER=$SERVICE_USERNAME/" $ENV_FILE + sed -i "s/^SERVICE_MONGODB_PASSWORD=.*$/SERVICE_MONGODB_PASSWORD=$SERVICE_PASSWORD/" $ENV_FILE + sed -i "s/^MARKET_GITHUB_TOKEN=.*$/MARKET_GITHUB_TOKEN=$GH_TOKEN/" $ENV_FILE + sed -i "s/^MARKETPLACE_INSTALLATION_URL=.*$/MARKETPLACE_INSTALLATION_URL=$MARKETPLACE_INSTALLATION_URL/" $ENV_FILE + + - name: Refresh Docker images + working-directory: ./marketplace-build + run: | + docker compose down + docker compose up -d diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml new file mode 100644 index 000000000..f316d0d91 --- /dev/null +++ b/.github/workflows/docker-release.yml @@ -0,0 +1,49 @@ +name: Docker Release + +on: + push: + branches: [ "master" ] + workflow_dispatch: + inputs: + image_version: + description: 'Marketplace Docker image version' + required: true + default: 'latest' + +env: + UI_IMAGE_NAME: marketplace-ui + SERVICE_IMAGE_NAME: marketplace-service + +jobs: + + build: + uses: ./.github/workflows/docker-build.yml + + release: + needs: build + runs-on: self-hosted + permissions: + packages: write + contents: read + + steps: + - name: Log in to registry + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + - name: Refine release version + run: | + # This strips the git ref prefix from the version. + VERSION=${{ github.event.inputs.image_version }} + # This uses the Docker `latest` tag convention. + [ "$VERSION" == "main" ] && VERSION=latest + echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Release Marketplace UI image + run: | + UI_IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$UI_IMAGE_NAME + docker tag $UI_IMAGE_NAME $UI_IMAGE_ID:$VERSION + docker push $UI_IMAGE_ID:$VERSION + + - name: Release Marketplace Service image + run: | + SERVICE_IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$SERVICE_IMAGE_NAME + docker tag $SERVICE_IMAGE_NAME $SERVICE_IMAGE_ID:$VERSION + docker push $SERVICE_IMAGE_ID:$VERSION \ No newline at end of file diff --git a/.github/workflows/service-ci-build.yml b/.github/workflows/service-ci-build.yml index e384445d2..ef121541e 100644 --- a/.github/workflows/service-ci-build.yml +++ b/.github/workflows/service-ci-build.yml @@ -3,6 +3,8 @@ run-name: Build Service on branch ${{github.ref_name}} triggered by ${{github.ac on: push: + paths: + - 'marketplace-service/**' workflow_dispatch: jobs: diff --git a/.github/workflows/service-dev-build.yml b/.github/workflows/service-dev-build.yml deleted file mode 100644 index 3700e5322..000000000 --- a/.github/workflows/service-dev-build.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Service DEV Build -run-name: Build and Deploy Marketplace-Service on branch ${{github.ref_name}} by ${{github.actor}} - -on: - push: - branches: [ "develop" ] - workflow_dispatch: - -jobs: - build: - name: Packge project and deploy to tomcat - runs-on: self-hosted - - steps: - - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'temurin' - cache: maven - - name: Update configuration - env: - APP_PROPERTIES_FILE: './marketplace-service/src/main/resources/application.properties' - GITHUB_TOKEN_FILE: './marketplace-service/src/main/resources/github.token' - MONGODB_HOST: ${{ secrets.MONGODB_HOST }} - MONGODB_DATABASE: ${{ secrets.MONGODB_DATABASE }} - GH_TOKEN: ${{ secrets.GH_TOKEN }} - run: | - sed -i "s/^spring.data.mongodb.host=.*$/spring.data.mongodb.host=$MONGODB_HOST/" $APP_PROPERTIES_FILE - sed -i "s/^spring.data.mongodb.database=.*$/spring.data.mongodb.database=$MONGODB_DATABASE/" $APP_PROPERTIES_FILE - sed -i '1d;$d' $GITHUB_TOKEN_FILE && echo $GH_TOKEN > $GITHUB_TOKEN_FILE - - name: Build with Maven - run: mvn clean package -DskipTests --file ./marketplace-service/pom.xml - - name: Prepare deployment directory - run: mkdir -p deployment && cp ./marketplace-service/target/*.war deployment/ - - name: Copy WAR to Tomcat server - run: sudo cp deployment/*.war /opt/tomcat/webapps/marketplace-service.war - - name: Restart Tomcat server - run: | - sudo systemctl stop tomcat - sudo systemctl start tomcat \ No newline at end of file diff --git a/.github/workflows/ui-ci-build.yml b/.github/workflows/ui-ci-build.yml index 8137daf8b..d792f34a8 100644 --- a/.github/workflows/ui-ci-build.yml +++ b/.github/workflows/ui-ci-build.yml @@ -3,9 +3,8 @@ run-name: Build on branch ${{github.ref_name}} triggered by ${{github.actor}} on: push: - branches-ignore: - - develop - - master + paths: + - 'marketplace-ui/**' workflow_dispatch: jobs: @@ -20,10 +19,15 @@ jobs: with: node-version: '20' cache: 'npm' + cache-dependency-path: ./marketplace-ui/package-lock.json - name: Install Dependencies - run: npm install + run: | + cd ./marketplace-ui + npm install - name: Build project - run: npm run build + run: | + cd ./marketplace-ui + npm run build analysis: name: Sonarqube @@ -36,22 +40,30 @@ jobs: steps: - name: Execute Tests - run: npm run test + run: | + cd ./marketplace-ui + npm run test - uses: sonarsource/sonarqube-scan-action@master env: SONAR_TOKEN: ${{ env.SONAR_TOKEN }} SONAR_HOST_URL: ${{ env.SONAR_HOST_URL }} with: + projectBaseDir: ./marketplace-ui args: -Dsonar.projectKey=${{ env.SONAR_PROJECT_KEY }} + -Dsonar.javascript.lcov.reportPaths=${{ github.workspace }}/marketplace-ui/coverage/lcov.info + - name: SonarQube Quality Gate check id: sonarqube-quality-gate-check uses: sonarsource/sonarqube-quality-gate-action@master + with: + scanMetadataReportFile: ${{ github.workspace }}/marketplace-ui/.scannerwork/report-task.txt timeout-minutes: 5 env: SONAR_TOKEN: ${{ env.SONAR_TOKEN }} SONAR_HOST_URL: ${{ env.SONAR_HOST_URL }} - name: Clean up + working-directory: marketplace-ui run: | rm -rf * diff --git a/.github/workflows/ui-dev-build.yml b/.github/workflows/ui-dev-build.yml deleted file mode 100644 index 506278838..000000000 --- a/.github/workflows/ui-dev-build.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: UI Dev Build -run-name: Build and Deploy Marketplace-UI on branch ${{github.ref_name}} by ${{github.actor}} - -on: - push: - branches: [ "develop" ] - workflow_dispatch: - -jobs: - build: - name: Build and deploy new code to Deployment directory - runs-on: self-hosted - - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: '18' - cache: 'npm' - - name: Install Dependencies - run: npm install - - name: Build Angular app - run: npm run build -- --configuration production --output-path=dist - - name: Execute Tests - run: npm run test - - name: Copy files to Deployment directory - if: success() - run: sudo cp -r dist/* /var/www/marketplace-ui diff --git a/README.md b/README.md index 4d546f33a..5ef75bcd7 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,17 @@ # Getting Started -### Reference Documentation -For further reference, please consider the following sections: - -* [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) -* [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/3.2.5/maven-plugin/reference/html/) -* [Spring Data MongoDB](https://docs.spring.io/spring-boot/docs/3.2.5/reference/htmlsingle/index.html#data.nosql.mongodb) -* [Spring Web](https://docs.spring.io/spring-boot/docs/3.2.5/reference/htmlsingle/index.html#web) +For AxonIvy Marketplace, we have 3 parts: marketplace-ui, marketplace-service, and marketplace-build: +* ``marketplace-ui``: is an Angular project, built on v18 and contains the frontend code for the website. +* ``marketplace-service``: is a SpringBoot project, built on v3.2.5 and includes the apis code for the website. +* ``marketplace-build``: is a folder to keep everything related to build and dockers. ### Guides -The following guides illustrate how to use some features concretely: - -* Installing mongodb, and access it as Url mongodb://localhost:27017/, and you can create and name whatever you want ,then you should put them to application.properties -* You can change the MongoDB configuration in file `application.properties` - ``` - spring.data.mongodb.host= - spring.data.mongodb.database= - ``` -* Update GitHub token in file `github.token` -* Run mvn clean install to build project -* Run mvn test to test all tests +* How to start the Marketplace UI refer to the [marketplace-ui guide][1] +* How to start the Marketplace Service refer to the [marketplace-service guide][2] -### Access Swagger URL: http://{your-host}/swagger-ui/index.html +* How to start the Marketplace Build refer to the [marketplace-build guide][3] -### Install Lombok for Eclipse IDE -* Download lombok here https://projectlombok.org/download -* run command "java -jar lombok.jar" then you can access file “eclipse.ini“ in eclipse folder where you install → there is a text like this: -javaagent:C:\Users\tvtphuc\eclipse\jee-2024-032\eclipse\lombok.jar → it means you are successful -* Start eclipse -* Import the project then in the eclipse , you should run the command “mvn clean install“ -* After that you go to class MarketplaceServiceApplication → right click to main method → click run as → choose Java Application -* Then you can send a request in postman -* If you want to run single test in class UserServiceImplTest. You can right-click to method testFindAllUser and right click → select Run as → choose JUnit Test \ No newline at end of file + [1]: marketplace-ui/README.md + [2]: marketplace-service/README.md + [3]: marketplace-build/README.md diff --git a/marketplace-build/.dockerignore b/marketplace-build/.dockerignore new file mode 100644 index 000000000..429ee38ff --- /dev/null +++ b/marketplace-build/.dockerignore @@ -0,0 +1,2 @@ +# Node +**/node_modules \ No newline at end of file diff --git a/marketplace-build/.env b/marketplace-build/.env new file mode 100644 index 000000000..8f0271811 --- /dev/null +++ b/marketplace-build/.env @@ -0,0 +1,8 @@ +MONGODB_INITDB_ROOT_USERNAME= +MONGODB_INITDB_ROOT_PASSWORD= +SERVICE_MONGODB_HOST= +SERVICE_MONGODB_USER= +SERVICE_MONGODB_PASSWORD= +SERVICE_MONGODB_DATABASE= +MARKET_GITHUB_TOKEN= +MARKETPLACE_INSTALLATION_URL= \ No newline at end of file diff --git a/marketplace-build/Dockerfile b/marketplace-build/Dockerfile deleted file mode 100644 index f6e0339af..000000000 --- a/marketplace-build/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -Placeholder \ No newline at end of file diff --git a/marketplace-build/Marketplace Tomcat v10.1 Server.launch b/marketplace-build/Marketplace Tomcat v10.1 Server.launch index 5e4b64925..e3efb4803 100644 --- a/marketplace-build/Marketplace Tomcat v10.1 Server.launch +++ b/marketplace-build/Marketplace Tomcat v10.1 Server.launch @@ -2,8 +2,9 @@ - - + + + diff --git a/marketplace-build/README.md b/marketplace-build/README.md new file mode 100644 index 000000000..741b59e02 --- /dev/null +++ b/marketplace-build/README.md @@ -0,0 +1,33 @@ +# Get starts with Marketplace build + +### Set up MongoDB with authentication mode +* Navigate to ``marketplace-build/config/mongodb`` and execute the ``docker-compose up -d`` to start MongoDB with non-auth mode and create a root admin user. + +* [Optional] Execute authentication test for the created user + ``` + use admin + db.auth('username','password') + ``` +This command should return the ``OK`` code + +* Down the non-authen instance to start the main docker compose file by run ``docker-compose down`` + +### Docker build for DEV environment +* Navigate to ``marketplace-build`` + +* Run ``docker-compose up -d --build`` to start a Marketplace DEV at the local + +### Docker release +To release a new version for marketplace images, please trigger the ``Docker Release`` actions. +* This GH Actions will trigger the ``Docker build`` on the master branch. +* Login to GitHub Registry Hub. +* Deploy new image to packages. +Please verify the result in the ``Package`` after the build is completed. + +### Start Docker compose for PROD deployment +* Navigate to ``marketplace-build/release`` run ``docker-compose up -d`` to clone the docker images from GitHub packages and start the website + +### Start Docker compose using SPRINT release version +* Navigate to ``marketplace-build/release`` run ``docker-compose -f sprint-compose.yml up`` to clone the docker images from GitHub packages and start the website + + diff --git a/marketplace-build/config/mongodb/Dockerfile b/marketplace-build/config/mongodb/Dockerfile new file mode 100644 index 000000000..23ea5c687 --- /dev/null +++ b/marketplace-build/config/mongodb/Dockerfile @@ -0,0 +1,11 @@ +# Use the base image for MongoDB +FROM mongodb/mongodb-community-server:7.0.0-ubi8 + +# Copy the custom MongoDB configuration file into the container +COPY mongod.conf /etc/mongod.conf + +# Expose MongoDB port +EXPOSE 27017 + +# Define the default command to run MongoDB with the custom configuration +CMD ["mongod", "--config", "/etc/mongod.conf"] diff --git a/marketplace-build/config/mongodb/docker-compose.yml b/marketplace-build/config/mongodb/docker-compose.yml new file mode 100644 index 000000000..606db72df --- /dev/null +++ b/marketplace-build/config/mongodb/docker-compose.yml @@ -0,0 +1,18 @@ +# This docker compose to init mongo for setup auth +name: marketplace + +services: + mongodb: + container_name: marketplace-mongodb-non-authen + build: + context: . + dockerfile: Dockerfile + restart: always + ports: + - "27017:27017" + volumes: + - mongodata:/data/db + - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro + +volumes: + mongodata: diff --git a/marketplace-build/config/mongodb/mongo-init.js b/marketplace-build/config/mongodb/mongo-init.js new file mode 100644 index 000000000..5cef1331f --- /dev/null +++ b/marketplace-build/config/mongodb/mongo-init.js @@ -0,0 +1,12 @@ +db = db.getSiblingDB('admin'); +db.createUser( + { + user: "username", + pwd: "password", + roles: [ + { role: "userAdminAnyDatabase", db: "admin" }, + { role: "readWriteAnyDatabase", db: "admin" }, + { role: 'root', db: 'admin' } + ] + } +) \ No newline at end of file diff --git a/marketplace-build/config/mongodb/mongod.conf b/marketplace-build/config/mongodb/mongod.conf new file mode 100644 index 000000000..18b901f07 --- /dev/null +++ b/marketplace-build/config/mongodb/mongod.conf @@ -0,0 +1,5 @@ +security: + authorization: enabled +net: + bindIpAll: true + port: 27017 diff --git a/marketplace-build/config/nginx/nginx.conf b/marketplace-build/config/nginx/nginx.conf new file mode 100644 index 000000000..e9fe9ac0c --- /dev/null +++ b/marketplace-build/config/nginx/nginx.conf @@ -0,0 +1,12 @@ +events{} + +http { + # include the default mime.types to map file extensions to MIME types + include /etc/nginx/mime.types; + + server { + root /usr/share/nginx/html; + + index index.html; + } +} diff --git a/marketplace-build/dev/sonar/docker-compose.yml b/marketplace-build/dev/sonar/docker-compose.yml new file mode 100644 index 000000000..415936562 --- /dev/null +++ b/marketplace-build/dev/sonar/docker-compose.yml @@ -0,0 +1,44 @@ + +services: + sonarqube: + image: sonarqube:latest + name: sonar_local + ports: + - '9000:9000' + environment: + - SONAR_JDBC_URL=jdbc:postgresql://postgres:5432/mydb + - SONAR_JDBC_USERNAME=sonar + - SONAR_JDBC_PASSWORD=sonar + volumes: + - sonarqube_data:/opt/sonarqube + - sonarqube_extensions:/opt/sonarqube/extensions + depends_on: + - init + - postgres + + postgres: + image: postgres:12 + container_name: postgres_sonar + environment: + - POSTGRES_DB=mydb + - POSTGRES_USER=sonar + - POSTGRES_PASSWORD=sonar + - POSTGRES_INITDB_ARGS=--data-checksums + volumes: + - postgres_data:/var/lib/postgresql/data + - ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh + ports: + - "5432:5432" + + init: + image: bash + privileged: true + user: root + volumes: + - ./init.sh:/init.sh + command: ["sh", "-e", "/init.sh"] + +volumes: + sonarqube_data: + sonarqube_extensions: + postgres_data: \ No newline at end of file diff --git a/marketplace-build/dev/sonar/init-db.sh b/marketplace-build/dev/sonar/init-db.sh new file mode 100644 index 000000000..758c2c205 --- /dev/null +++ b/marketplace-build/dev/sonar/init-db.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL + CREATE ROLE mysuper WITH SUPERUSER CREATEDB CREATEROLE NOLOGIN; + ALTER USER myuser WITH SUPERUSER; +EOSQL \ No newline at end of file diff --git a/marketplace-build/dev/sonar/init.sh b/marketplace-build/dev/sonar/init.sh new file mode 100644 index 000000000..5096e4f32 --- /dev/null +++ b/marketplace-build/dev/sonar/init.sh @@ -0,0 +1,2 @@ +sysctl -w vm.max_map_count=262144 +sysctl -w fs.file-max=131072 \ No newline at end of file diff --git a/marketplace-build/docker-compose.yml b/marketplace-build/docker-compose.yml index f6e0339af..5cf4f924e 100644 --- a/marketplace-build/docker-compose.yml +++ b/marketplace-build/docker-compose.yml @@ -1 +1,53 @@ -Placeholder \ No newline at end of file +name: marketplace + +services: + mongodb: + container_name: marketplace-mongodb-7.0.0 + build: + context: ./config/mongodb + dockerfile: Dockerfile + restart: always + ports: + - "27017:27017" + environment: + MONGODB_INITDB_ROOT_USERNAME: ${MONGODB_INITDB_ROOT_USERNAME} + MONGODB_INITDB_ROOT_PASSWORD: ${MONGODB_INITDB_ROOT_PASSWORD} + volumes: + - mongodata:/data/db + - ./config/mongodb/mongod.conf:/etc/mongod.conf + + ui: + container_name: marketplace-ui + build: + context: ../marketplace-ui + additional_contexts: + assets: ../marketplace-build/ + dockerfile: Dockerfile + restart: always + volumes: + - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf + ports: + - "4200:80" + depends_on: + - service + + service: + container_name: marketplace-service + restart: always + environment: + - MONGODB_HOST=${SERVICE_MONGODB_HOST} + - MONGODB_DATABASE=${SERVICE_MONGODB_DATABASE} + - MONGODB_USERNAME=${SERVICE_MONGODB_USER} + - MONGODB_PASSWORD=${SERVICE_MONGODB_PASSWORD} + - MARKET_GITHUB_TOKEN=${MARKET_GITHUB_TOKEN} + - MARKETPLACE_INSTALLATION_URL=${MARKETPLACE_INSTALLATION_URL} + build: + context: ../marketplace-service + dockerfile: Dockerfile + ports: + - "8080:8080" + depends_on: + - mongodb + +volumes: + mongodata: \ No newline at end of file diff --git a/marketplace-build/release/.env b/marketplace-build/release/.env new file mode 100644 index 000000000..8f0271811 --- /dev/null +++ b/marketplace-build/release/.env @@ -0,0 +1,8 @@ +MONGODB_INITDB_ROOT_USERNAME= +MONGODB_INITDB_ROOT_PASSWORD= +SERVICE_MONGODB_HOST= +SERVICE_MONGODB_USER= +SERVICE_MONGODB_PASSWORD= +SERVICE_MONGODB_DATABASE= +MARKET_GITHUB_TOKEN= +MARKETPLACE_INSTALLATION_URL= \ No newline at end of file diff --git a/marketplace-build/release/docker-compose.yml b/marketplace-build/release/docker-compose.yml new file mode 100644 index 000000000..983c94622 --- /dev/null +++ b/marketplace-build/release/docker-compose.yml @@ -0,0 +1,37 @@ +name: marketplace + +services: + mongodb: + build: + context: ../config/mongodb + dockerfile: Dockerfile + container_name: marketplace-mongodb-7.0.0 + restart: always + ports: + - "27017:27017" + environment: + MONGODB_INITDB_ROOT_USERNAME: ${MONGODB_INITDB_ROOT_USERNAME} + MONGODB_INITDB_ROOT_PASSWORD: ${MONGODB_INITDB_ROOT_PASSWORD} + volumes: + - mongodata:/data/db + - ../config/mongodb/mongod.conf:/etc/mongod.conf + + ui: + image: ghcr.io/axonivy-market/marketplace-ui:latest + restart: always + ports: + - "80:80" + + service: + image: ghcr.io/axonivy-market/marketplace-service:latest + restart: always + environment: + - MONGODB_HOST=${SERVICE_MONGODB_HOST} + - MONGODB_DATABASE=${SERVICE_MONGODB_DATABASE} + - MONGODB_USERNAME=${SERVICE_MONGODB_USER} + - MONGODB_PASSWORD=${SERVICE_MONGODB_PASSWORD} + - MARKET_GITHUB_TOKEN=${MARKET_GITHUB_TOKEN} + - MARKETPLACE_INSTALLATION_URL=${MARKETPLACE_INSTALLATION_URL} + +volumes: + mongodata: \ No newline at end of file diff --git a/marketplace-build/release/sprint-compose.yml b/marketplace-build/release/sprint-compose.yml new file mode 100644 index 000000000..85b42f243 --- /dev/null +++ b/marketplace-build/release/sprint-compose.yml @@ -0,0 +1,37 @@ +name: marketplace + +services: + mongodb: + container_name: marketplace-mongodb-7.0.0 + build: + context: ../config/mongodb + dockerfile: Dockerfile + restart: always + ports: + - "27017:27017" + environment: + MONGODB_INITDB_ROOT_USERNAME: ${MONGODB_INITDB_ROOT_USERNAME} + MONGODB_INITDB_ROOT_PASSWORD: ${MONGODB_INITDB_ROOT_PASSWORD} + volumes: + - mongodata:/data/db + - ../config/mongodb/mongod.conf:/etc/mongod.conf + + ui: + image: ghcr.io/axonivy-market/marketplace-ui:sprint + restart: always + ports: + - "95:80" + + service: + image: ghcr.io/axonivy-market/marketplace-service:sprint + restart: always + environment: + - MONGODB_HOST=${SERVICE_MONGODB_HOST} + - MONGODB_DATABASE=${SERVICE_MONGODB_DATABASE} + - MONGODB_USERNAME=${SERVICE_MONGODB_USER} + - MONGODB_PASSWORD=${SERVICE_MONGODB_PASSWORD} + - MARKET_GITHUB_TOKEN=${MARKET_GITHUB_TOKEN} + - MARKETPLACE_INSTALLATION_URL=${MARKETPLACE_INSTALLATION_URL} +volumes: + mongodata: + \ No newline at end of file diff --git a/marketplace-service/.dockerignore b/marketplace-service/.dockerignore new file mode 100644 index 000000000..0384b84cd --- /dev/null +++ b/marketplace-service/.dockerignore @@ -0,0 +1,33 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ +/bin/ diff --git a/marketplace-service/Dockerfile b/marketplace-service/Dockerfile new file mode 100644 index 000000000..8a963d725 --- /dev/null +++ b/marketplace-service/Dockerfile @@ -0,0 +1,21 @@ +# Stage 1: Maven build +FROM maven:3.8.1-openjdk-17 AS build-api +WORKDIR /app +COPY . . +RUN mvn clean install -DskipTests + +# Stage 2: Run the application +FROM tomcat:10.1-jdk17-openjdk-slim +WORKDIR /app +# Remove the default ROOT webapp to avoid conflicts +RUN rm -rf /usr/local/tomcat/webapps/ROOT + +# Copy the WAR file to the webapps directory in Tomcat +COPY --from=build-api /app/target/marketplace-service-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps/marketplace-service.war + +# Expose port 8080 +EXPOSE 8080 + +# Start Tomcat +CMD ["catalina.sh", "run"] + diff --git a/marketplace-service/src/main/java/com/axonivy/market/config/MongoConfig.java b/marketplace-service/src/main/java/com/axonivy/market/config/MongoConfig.java index 315b7384c..71df8b67b 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/config/MongoConfig.java +++ b/marketplace-service/src/main/java/com/axonivy/market/config/MongoConfig.java @@ -1,9 +1,5 @@ package com.axonivy.market.config; -import com.mongodb.ConnectionString; -import com.mongodb.MongoClientSettings; -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoClients; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -17,13 +13,18 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; +import com.mongodb.ConnectionString; +import com.mongodb.MongoClientSettings; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; + @Configuration @EnableMongoRepositories(basePackages = "com.axonivy.market.repository") @EnableMongoAuditing public class MongoConfig extends AbstractMongoClientConfiguration { - @Value("${spring.data.mongodb.host}") - private String host; + @Value("${spring.data.mongodb.uri}") + private String uri; @Value("${spring.data.mongodb.database}") private String databaseName; @@ -35,7 +36,7 @@ protected String getDatabaseName() { @Override public MongoClient mongoClient() { - ConnectionString connectionString = new ConnectionString(host); + ConnectionString connectionString = new ConnectionString(uri); MongoClientSettings mongoClientSettings = MongoClientSettings.builder().applyConnectionString(connectionString) .build(); diff --git a/marketplace-service/src/main/java/com/axonivy/market/config/WebConfig.java b/marketplace-service/src/main/java/com/axonivy/market/config/WebConfig.java index a781aa8ea..0ff332d8c 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/config/WebConfig.java +++ b/marketplace-service/src/main/java/com/axonivy/market/config/WebConfig.java @@ -12,13 +12,10 @@ public class WebConfig implements WebMvcConfigurer { private static final String[] EXCLUDE_PATHS = { "/", "/swagger-ui/**", "/api-docs/**" }; private static final String[] ALLOWED_HEADERS = { "Accept-Language", "Content-Type", "Authorization", "X-Requested-By", "x-requested-with", "X-Forwarded-Host", "x-xsrf-token" }; - private static final String[] ALLOWED_METHODS = { "GET", "POST", "PUT", "DELETE", "OPTIONS" }; + private static final String[] ALLOWED_METHODS = { "GET", "OPTIONS" }; private final MarketHeaderInterceptor headerInterceptor; - @Value("${market.cors.allowed.origin.patterns}") - private String marketCorsAllowedOriginPatterns; - @Value("${market.cors.allowed.origin.maxAge}") private int marketCorsAllowedOriginMaxAge; @@ -33,7 +30,7 @@ public void addInterceptors(InterceptorRegistry registry) { @Override public void addCorsMappings(CorsRegistry registry) { - registry.addMapping("/**").allowedOriginPatterns(marketCorsAllowedOriginPatterns).allowedMethods(ALLOWED_METHODS) - .allowedHeaders(ALLOWED_HEADERS).maxAge(marketCorsAllowedOriginMaxAge); + registry.addMapping("/**").allowedOrigins("*").allowedMethods(ALLOWED_METHODS).allowedHeaders(ALLOWED_HEADERS) + .maxAge(marketCorsAllowedOriginMaxAge); } } \ No newline at end of file diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductController.java b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductController.java index 498424e11..ededf95a3 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductController.java +++ b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductController.java @@ -1,12 +1,8 @@ package com.axonivy.market.controller; -import com.axonivy.market.assembler.ProductModelAssembler; -import com.axonivy.market.entity.Product; -import com.axonivy.market.enums.ErrorCode; -import com.axonivy.market.model.Message; -import com.axonivy.market.model.ProductModel; -import com.axonivy.market.service.ProductService; -import io.swagger.v3.oas.annotations.Operation; +import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT; +import static com.axonivy.market.constants.RequestMappingConstants.SYNC; + import org.apache.commons.lang3.time.StopWatch; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -15,14 +11,21 @@ import org.springframework.hateoas.PagedModel; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT; -import static com.axonivy.market.constants.RequestMappingConstants.SYNC; +import com.axonivy.market.assembler.ProductModelAssembler; +import com.axonivy.market.entity.Product; +import com.axonivy.market.enums.ErrorCode; +import com.axonivy.market.model.Message; +import com.axonivy.market.model.ProductModel; +import com.axonivy.market.service.ProductService; + +import io.swagger.v3.oas.annotations.Operation; @RestController @RequestMapping(PRODUCT) @@ -53,6 +56,7 @@ public ResponseEntity> findProducts(@RequestParam(name return new ResponseEntity<>(pageResources, HttpStatus.OK); } + @CrossOrigin(originPatterns = "http://localhost:[*]") @PutMapping(SYNC) public ResponseEntity syncProducts() { var stopWatch = new StopWatch(); diff --git a/marketplace-service/src/main/java/com/axonivy/market/github/model/GitHubProperty.java b/marketplace-service/src/main/java/com/axonivy/market/github/model/GitHubProperty.java new file mode 100644 index 000000000..e0e30f669 --- /dev/null +++ b/marketplace-service/src/main/java/com/axonivy/market/github/model/GitHubProperty.java @@ -0,0 +1,20 @@ +package com.axonivy.market.github.model; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Configuration +@ConfigurationProperties(prefix = "market.github") +public class GitHubProperty { + + private String token; +} diff --git a/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GitHubServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GitHubServiceImpl.java index ba63635ad..264134e5c 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GitHubServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GitHubServiceImpl.java @@ -1,13 +1,10 @@ package com.axonivy.market.github.service.impl; -import com.axonivy.market.constants.GitHubConstants; -import com.axonivy.market.entity.User; -import com.axonivy.market.enums.ErrorCode; -import com.axonivy.market.exceptions.model.NotFoundException; -import com.axonivy.market.exceptions.model.Oauth2ExchangeCodeException; -import com.axonivy.market.github.service.GitHubService; -import com.axonivy.market.model.GitHubAccessTokenResponse; -import com.axonivy.market.repository.UserRepository; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Map; + import org.kohsuke.github.GHContent; import org.kohsuke.github.GHOrganization; import org.kohsuke.github.GHRepository; @@ -24,34 +21,35 @@ import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.util.ResourceUtils; import org.springframework.web.client.RestTemplate; -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import com.axonivy.market.constants.GitHubConstants; +import com.axonivy.market.entity.User; +import com.axonivy.market.enums.ErrorCode; +import com.axonivy.market.exceptions.model.NotFoundException; +import com.axonivy.market.exceptions.model.Oauth2ExchangeCodeException; +import com.axonivy.market.github.model.GitHubProperty; +import com.axonivy.market.github.service.GitHubService; +import com.axonivy.market.model.GitHubAccessTokenResponse; +import com.axonivy.market.repository.UserRepository; @Service public class GitHubServiceImpl implements GitHubService { private final RestTemplate restTemplate; private final UserRepository userRepository; + private final GitHubProperty gitHubProperty; - private static final String GITHUB_TOKEN_FILE = "classpath:github.token"; - - public GitHubServiceImpl(RestTemplateBuilder restTemplateBuilder, UserRepository userRepository) { + public GitHubServiceImpl(RestTemplateBuilder restTemplateBuilder, UserRepository userRepository, + GitHubProperty gitHubProperty) { this.restTemplate = restTemplateBuilder.build(); this.userRepository = userRepository; + this.gitHubProperty = gitHubProperty; } @Override public GitHub getGitHub() throws IOException { - File gitHubToken = ResourceUtils.getFile(GITHUB_TOKEN_FILE); - var token = Files.readString(gitHubToken.toPath()); - return new GitHubBuilder().withOAuthToken(token.trim().strip()).build(); + return new GitHubBuilder().withOAuthToken(gitHubProperty.getToken().trim().strip()).build(); } @Override diff --git a/marketplace-service/src/main/resources/application.properties b/marketplace-service/src/main/resources/application.properties index aebb71018..17f6ab518 100644 --- a/marketplace-service/src/main/resources/application.properties +++ b/marketplace-service/src/main/resources/application.properties @@ -1,15 +1,16 @@ spring.application.name=marketplace-service -spring.data.mongodb.host=mongodb://localhost:27017/ -spring.data.mongodb.database=marketplace +spring.data.mongodb.uri=mongodb://${MONGODB_USERNAME}:${MONGODB_PASSWORD}@${MONGODB_HOST}:27017/ +spring.data.mongodb.database=${MONGODB_DATABASE} server.port=8080 logging.level.org.springframework.web=warn request.header=ivy server.forward-headers-strategy=framework springdoc.api-docs.path=/api-docs springdoc.swagger-ui.path=/swagger-ui.html -market.cors.allowed.origin.patterns=http://localhost:[*], http://10.193.8.78:[*], http://marketplace.server.ivy-cloud.com:[*] market.cors.allowed.origin.maxAge=3600 synchronized.installation.counts.path=${MARKETPLACE_INSTALLATION_URL} +market.github.token=${MARKET_GITHUB_TOKEN} +logging.level.org.springframework.security=DEBUG spring.security.oauth2.client.registration.github.client-id= spring.security.oauth2.client.registration.github.client-secret= jwt.secret= diff --git a/marketplace-service/src/main/resources/github.token b/marketplace-service/src/main/resources/github.token deleted file mode 100644 index 8433821ba..000000000 --- a/marketplace-service/src/main/resources/github.token +++ /dev/null @@ -1 +0,0 @@ -ghp_replace-with-your-token \ No newline at end of file diff --git a/marketplace-ui/.dockerignore b/marketplace-ui/.dockerignore new file mode 100644 index 000000000..acaadf758 --- /dev/null +++ b/marketplace-ui/.dockerignore @@ -0,0 +1,5 @@ +node_modules +dist +.git +.gitignore +Dockerfile diff --git a/marketplace-ui/Dockerfile b/marketplace-ui/Dockerfile new file mode 100644 index 000000000..e02ed0f60 --- /dev/null +++ b/marketplace-ui/Dockerfile @@ -0,0 +1,11 @@ +# Stage 1: Build Angular app +FROM node:20-alpine AS build-angular +WORKDIR /app +COPY . . +RUN npm install +RUN npm run build --prod + +# Stage 2: Serve Angular app using Nginx +FROM nginx:alpine +COPY --from=build-angular /app/dist/browser /usr/share/nginx/html +COPY --from=assets config/nginx/nginx.conf /etc/nginx/nginx.conf diff --git a/marketplace-ui/src/environments/environment.ts b/marketplace-ui/src/environments/environment.ts index 77ad2feba..9d002c724 100644 --- a/marketplace-ui/src/environments/environment.ts +++ b/marketplace-ui/src/environments/environment.ts @@ -1,7 +1,8 @@ export const environment = { production: true, - apiUrl: 'http://10.193.8.78:9090/marketplace-service', + apiUrl: 'http://marketplace.server.ivy-cloud.com:8080/marketplace-service', githubClientId: 'Ov23liVMliBxBqdQ7FnG', githubAuthCallbackUrl: 'http://marketplace.server.ivy-cloud.com:4200/auth/github/callback', dayInMiliseconds: 86400000 + }; From 9f115a0eac9f4a5eb83202a25c4d731417d47985 Mon Sep 17 00:00:00 2001 From: Hoan Nguyen Date: Mon, 22 Jul 2024 10:53:42 +0700 Subject: [PATCH 5/9] MARP-224: Fix GitHubService test --- .../market/github/service/impl/GitHubServiceImpl.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GitHubServiceImpl.java b/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GitHubServiceImpl.java index 264134e5c..4d7c7ecf7 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GitHubServiceImpl.java +++ b/marketplace-service/src/main/java/com/axonivy/market/github/service/impl/GitHubServiceImpl.java @@ -1,9 +1,12 @@ package com.axonivy.market.github.service.impl; +import static org.apache.commons.lang3.StringUtils.EMPTY; + import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import org.kohsuke.github.GHContent; import org.kohsuke.github.GHOrganization; @@ -49,7 +52,9 @@ public GitHubServiceImpl(RestTemplateBuilder restTemplateBuilder, UserRepository @Override public GitHub getGitHub() throws IOException { - return new GitHubBuilder().withOAuthToken(gitHubProperty.getToken().trim().strip()).build(); + return new GitHubBuilder() + .withOAuthToken(Optional.ofNullable(gitHubProperty).map(GitHubProperty::getToken).orElse(EMPTY).trim()) + .build(); } @Override From e3314fddd6e019306de3326979269a581cae7fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=E1=BA=A7n=20V=C4=A9nh=20Thi=E1=BB=87n=20Ph=C3=BAc?= Date: Mon, 22 Jul 2024 11:12:01 +0700 Subject: [PATCH 6/9] add mockTest env variables --- .../java/com/axonivy/market/service/SchedulingTasksTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/SchedulingTasksTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/SchedulingTasksTest.java index bdc720dfc..d436cf72e 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/SchedulingTasksTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/SchedulingTasksTest.java @@ -10,7 +10,8 @@ import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.verify; -@SpringBootTest(properties = { "MARKETPLACE_INSTALLATION_URL=D:/marketplace-installation.json" }) +@SpringBootTest(properties = { "MARKETPLACE_INSTALLATION_URL=marketplace-installation.json", "MONGODB_USERNAME=user", + "MONGODB_PASSWORD=password", "MONGODB_HOST=mongoHost", "MONGODB_DATABASE=product" }) class SchedulingTasksTest { @SpyBean From ee52b0f2f4676047c7ed4a00201a5ea1eb08bb3e Mon Sep 17 00:00:00 2001 From: Hoan Nguyen <83745591+nqhoan-axonivy@users.noreply.github.com> Date: Tue, 23 Jul 2024 22:40:38 +0700 Subject: [PATCH 7/9] Feature/MARP-224 Create dockerfile for deployment marketplace homepage (#56) - Added clean-up docker container and images - Added waiting for containers to start before tagging --- .github/workflows/docker-build.yml | 23 ++++++++++++++++++----- .github/workflows/docker-release.yml | 21 +++++++++++++++++++++ marketplace-build/config/nginx/nginx.conf | 4 ++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index bbe173702..694dcc597 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -7,11 +7,25 @@ on: workflow_call: jobs: - build: + cleanup: + name: Clean up docker container and images runs-on: self-hosted steps: - - uses: actions/checkout@v4 + - name: Bring down and remove containers and images + working-directory: ./marketplace-build + run: | + docker compose down --rmi all + + build-and-deploy: + name: Build and bring up docker containers + runs-on: self-hosted + needs: cleanup + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Update environment variables for .env env: ENV_FILE: './marketplace-build/.env' @@ -33,8 +47,7 @@ jobs: sed -i "s/^MARKET_GITHUB_TOKEN=.*$/MARKET_GITHUB_TOKEN=$GH_TOKEN/" $ENV_FILE sed -i "s/^MARKETPLACE_INSTALLATION_URL=.*$/MARKETPLACE_INSTALLATION_URL=$MARKETPLACE_INSTALLATION_URL/" $ENV_FILE - - name: Refresh Docker images + - name: Build and bring up containers without cache working-directory: ./marketplace-build run: | - docker compose down - docker compose up -d + docker compose up --build --force-recreate -d diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml index f316d0d91..8eeeb1cfb 100644 --- a/.github/workflows/docker-release.yml +++ b/.github/workflows/docker-release.yml @@ -17,9 +17,11 @@ env: jobs: build: + name: Build Docker images uses: ./.github/workflows/docker-build.yml release: + name: Tag and publish image to GH packages needs: build runs-on: self-hosted permissions: @@ -27,8 +29,26 @@ jobs: contents: read steps: + - name: Wait for containers to be up and running + working-directory: ./marketplace-build + run: | + # Wait for up to 300 seconds for the containers to be up + timeout=300 + start_time=$(date +%s) + while [ $(($(date +%s) - start_time)) -lt $timeout ]; do + if docker compose ps | grep -q "Up"; then + echo "Containers are up and running." + exit 0 + fi + echo "Waiting for containers to start..." + sleep 5 + done + echo "Containers did not start within the timeout period." + exit 1 + - name: Log in to registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + - name: Refine release version run: | # This strips the git ref prefix from the version. @@ -36,6 +56,7 @@ jobs: # This uses the Docker `latest` tag convention. [ "$VERSION" == "main" ] && VERSION=latest echo "VERSION=$VERSION" >> $GITHUB_ENV + - name: Release Marketplace UI image run: | UI_IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$UI_IMAGE_NAME diff --git a/marketplace-build/config/nginx/nginx.conf b/marketplace-build/config/nginx/nginx.conf index e9fe9ac0c..e8704aa0a 100644 --- a/marketplace-build/config/nginx/nginx.conf +++ b/marketplace-build/config/nginx/nginx.conf @@ -8,5 +8,9 @@ http { root /usr/share/nginx/html; index index.html; + + location / { + try_files $uri $uri/ /index.html; + } } } From b0d28cf9d5012751fb4e371eed4978bc4f558b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=E1=BA=A7n=20V=C4=A9nh=20Thi=E1=BB=87n=20Ph=C3=BAc?= <143604440+tvtphuc-axonivy@users.noreply.github.com> Date: Wed, 24 Jul 2024 09:56:48 +0700 Subject: [PATCH 8/9] Feature/marp 662 integration of installation frequency follow up for marp 473 (#50) --- .github/workflows/docker-build.yml | 2 -- marketplace-build/docker-compose.yml | 3 ++- marketplace-build/release/docker-compose.yml | 4 ++-- marketplace-build/release/sprint-compose.yml | 3 ++- .../axonivy/market/controller/ProductDetailsController.java | 5 +++-- .../src/main/resources/application.properties | 2 +- .../java/com/axonivy/market/service/SchedulingTasksTest.java | 4 ++-- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 694dcc597..8537e9ede 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -36,7 +36,6 @@ jobs: SERVICE_PASSWORD: ${{ secrets.SERVICE_PASSWORD }} MONGODB_DATABASE: ${{ secrets.MONGODB_DATABASE }} GH_TOKEN: ${{ secrets.GH_TOKEN }} - MARKETPLACE_INSTALLATION_URL: ${{ secrets.MARKETPLACE_INSTALLATION_URL }} run: | sed -i "s/^MONGODB_INITDB_ROOT_USERNAME=.*$/MONGODB_INITDB_ROOT_USERNAME=$ROOT_USERNAME/" $ENV_FILE sed -i "s/^MONGODB_INITDB_ROOT_PASSWORD=.*$/MONGODB_INITDB_ROOT_PASSWORD=$ROOT_PASSWORD/" $ENV_FILE @@ -45,7 +44,6 @@ jobs: sed -i "s/^SERVICE_MONGODB_USER=.*$/SERVICE_MONGODB_USER=$SERVICE_USERNAME/" $ENV_FILE sed -i "s/^SERVICE_MONGODB_PASSWORD=.*$/SERVICE_MONGODB_PASSWORD=$SERVICE_PASSWORD/" $ENV_FILE sed -i "s/^MARKET_GITHUB_TOKEN=.*$/MARKET_GITHUB_TOKEN=$GH_TOKEN/" $ENV_FILE - sed -i "s/^MARKETPLACE_INSTALLATION_URL=.*$/MARKETPLACE_INSTALLATION_URL=$MARKETPLACE_INSTALLATION_URL/" $ENV_FILE - name: Build and bring up containers without cache working-directory: ./marketplace-build diff --git a/marketplace-build/docker-compose.yml b/marketplace-build/docker-compose.yml index 5cf4f924e..71682a2fd 100644 --- a/marketplace-build/docker-compose.yml +++ b/marketplace-build/docker-compose.yml @@ -34,13 +34,14 @@ services: service: container_name: marketplace-service restart: always + volumes: + - /home/axonivy/marketplace/data/market-installations.json:/home/data/market-installation.json environment: - MONGODB_HOST=${SERVICE_MONGODB_HOST} - MONGODB_DATABASE=${SERVICE_MONGODB_DATABASE} - MONGODB_USERNAME=${SERVICE_MONGODB_USER} - MONGODB_PASSWORD=${SERVICE_MONGODB_PASSWORD} - MARKET_GITHUB_TOKEN=${MARKET_GITHUB_TOKEN} - - MARKETPLACE_INSTALLATION_URL=${MARKETPLACE_INSTALLATION_URL} build: context: ../marketplace-service dockerfile: Dockerfile diff --git a/marketplace-build/release/docker-compose.yml b/marketplace-build/release/docker-compose.yml index 983c94622..dfc95f0fb 100644 --- a/marketplace-build/release/docker-compose.yml +++ b/marketplace-build/release/docker-compose.yml @@ -25,13 +25,13 @@ services: service: image: ghcr.io/axonivy-market/marketplace-service:latest restart: always + volumes: + - /home/axonivy/marketplace/data/market-installations.json:/home/data/market-installation.json environment: - MONGODB_HOST=${SERVICE_MONGODB_HOST} - MONGODB_DATABASE=${SERVICE_MONGODB_DATABASE} - MONGODB_USERNAME=${SERVICE_MONGODB_USER} - MONGODB_PASSWORD=${SERVICE_MONGODB_PASSWORD} - MARKET_GITHUB_TOKEN=${MARKET_GITHUB_TOKEN} - - MARKETPLACE_INSTALLATION_URL=${MARKETPLACE_INSTALLATION_URL} - volumes: mongodata: \ No newline at end of file diff --git a/marketplace-build/release/sprint-compose.yml b/marketplace-build/release/sprint-compose.yml index 85b42f243..ff273c945 100644 --- a/marketplace-build/release/sprint-compose.yml +++ b/marketplace-build/release/sprint-compose.yml @@ -25,13 +25,14 @@ services: service: image: ghcr.io/axonivy-market/marketplace-service:sprint restart: always + volumes: + - /home/axonivy/marketplace/data/market-installations.json:/home/data/market-installation.json environment: - MONGODB_HOST=${SERVICE_MONGODB_HOST} - MONGODB_DATABASE=${SERVICE_MONGODB_DATABASE} - MONGODB_USERNAME=${SERVICE_MONGODB_USER} - MONGODB_PASSWORD=${SERVICE_MONGODB_PASSWORD} - MARKET_GITHUB_TOKEN=${MARKET_GITHUB_TOKEN} - - MARKETPLACE_INSTALLATION_URL=${MARKETPLACE_INSTALLATION_URL} volumes: mongodata: \ No newline at end of file diff --git a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java index b57f80e0f..2d89ffd0c 100644 --- a/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java +++ b/marketplace-service/src/main/java/com/axonivy/market/controller/ProductDetailsController.java @@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; - +import org.springframework.web.bind.annotation.CrossOrigin; import java.util.List; import static com.axonivy.market.constants.RequestMappingConstants.PRODUCT_DETAILS; @@ -40,7 +40,8 @@ public ResponseEntity findProductDetailsByVersion(@PathVaria return new ResponseEntity<>(detailModelAssembler.toModel(productDetail, tag), HttpStatus.OK); } - @Operation(summary = "increase installation count by 1", description = "increase installation count by 1") + @Operation(summary = "increase installation count by 1", description = "update installation count when click download product files by users") + @CrossOrigin(originPatterns = "*") @PutMapping("/installationcount/{key}") public ResponseEntity syncInstallationCount(@PathVariable("key") String key) { int result = productService.updateInstallationCountForProduct(key); diff --git a/marketplace-service/src/main/resources/application.properties b/marketplace-service/src/main/resources/application.properties index 17f6ab518..b2fd17582 100644 --- a/marketplace-service/src/main/resources/application.properties +++ b/marketplace-service/src/main/resources/application.properties @@ -8,7 +8,7 @@ server.forward-headers-strategy=framework springdoc.api-docs.path=/api-docs springdoc.swagger-ui.path=/swagger-ui.html market.cors.allowed.origin.maxAge=3600 -synchronized.installation.counts.path=${MARKETPLACE_INSTALLATION_URL} +synchronized.installation.counts.path=/home/data/market-installation.json market.github.token=${MARKET_GITHUB_TOKEN} logging.level.org.springframework.security=DEBUG spring.security.oauth2.client.registration.github.client-id= diff --git a/marketplace-service/src/test/java/com/axonivy/market/service/SchedulingTasksTest.java b/marketplace-service/src/test/java/com/axonivy/market/service/SchedulingTasksTest.java index d436cf72e..0407a7f75 100644 --- a/marketplace-service/src/test/java/com/axonivy/market/service/SchedulingTasksTest.java +++ b/marketplace-service/src/test/java/com/axonivy/market/service/SchedulingTasksTest.java @@ -10,8 +10,8 @@ import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.verify; -@SpringBootTest(properties = { "MARKETPLACE_INSTALLATION_URL=marketplace-installation.json", "MONGODB_USERNAME=user", - "MONGODB_PASSWORD=password", "MONGODB_HOST=mongoHost", "MONGODB_DATABASE=product" }) +@SpringBootTest(properties = { "MONGODB_USERNAME=user", "MONGODB_PASSWORD=password", "MONGODB_HOST=mongoHost", + "MONGODB_DATABASE=product" }) class SchedulingTasksTest { @SpyBean From 9067cf74fae6289872795aeff59f2fd070073608 Mon Sep 17 00:00:00 2001 From: Thuy Nguyen <145430420+nntthuy-axonivy@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:14:24 +0700 Subject: [PATCH 9/9] Bugfix/marp 691 no search results new design (#48) Alter not-found search results --- .../product-detail.component.html | 3 +-- .../modules/product/product.component.html | 13 ++++++++-- .../modules/product/product.component.scss | 24 ++++++++++++++++++- .../star-rating/star-rating.component.html | 1 + .../star-rating/star-rating.component.scss | 18 +++++++------- marketplace-ui/src/assets/i18n/de.yaml | 2 +- marketplace-ui/src/assets/i18n/en.yaml | 4 ++-- .../src/assets/images/misc/search-off.svg | 11 +++++++++ 8 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 marketplace-ui/src/assets/images/misc/search-off.svg diff --git a/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.html b/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.html index 8516b1bf8..acf3360ae 100644 --- a/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.html +++ b/marketplace-ui/src/app/modules/product/product-detail/product-detail.component.html @@ -49,8 +49,7 @@

-
+
}
} @else { -
- {{ 'common.nothingFound' | translate }} +
+
+ Search not found +
+
} diff --git a/marketplace-ui/src/app/modules/product/product.component.scss b/marketplace-ui/src/app/modules/product/product.component.scss index e01ebbe71..7e15fb0b1 100644 --- a/marketplace-ui/src/app/modules/product/product.component.scss +++ b/marketplace-ui/src/app/modules/product/product.component.scss @@ -2,6 +2,28 @@ min-height: 6em; } -.mt-8{ +.mt-8 { margin-top: 8rem; } + +.not-found-result { + max-width: 670px; + margin-bottom: 4rem; + + .not-found-text { + line-height: 140%; + color: var(--text-no-rating-color); + margin: 20px 0 0 0; + } +} + +@media (max-width: 430px) { + .no-result-image { + width: 60px; + height: 60px; + } + + .not-found-text { + font-size: 0.875rem; + } +} diff --git a/marketplace-ui/src/app/shared/components/star-rating/star-rating.component.html b/marketplace-ui/src/app/shared/components/star-rating/star-rating.component.html index 85f843feb..2175e8a8e 100644 --- a/marketplace-ui/src/app/shared/components/star-rating/star-rating.component.html +++ b/marketplace-ui/src/app/shared/components/star-rating/star-rating.component.html @@ -1,4 +1,5 @@ Ändere deinen Suchbegriff oder stöbere in unseren Kategorien nach ähnlichen Themen. header: download: Download footer: diff --git a/marketplace-ui/src/assets/i18n/en.yaml b/marketplace-ui/src/assets/i18n/en.yaml index 6b4d76a25..70876ac43 100644 --- a/marketplace-ui/src/assets/i18n/en.yaml +++ b/marketplace-ui/src/assets/i18n/en.yaml @@ -39,7 +39,7 @@ common: lowest: Lowest search: placeholder: Search a keyword - nothingFound: Nothing found + nothingFound: Your search did not yield any results.
Please modify your search terms or browse our categories for related content. header: download: Download footer: @@ -88,7 +88,7 @@ common: label: Choose artifact feedback: label: Feedback - successMessage: Your feedback has been successfully submitted! + successMessage: Your feedback has been successfully submitted! thankMessage: Thank you for your contribution addFeedbackTitle: Give your feedback! addFeedbackDescription: By giving your feedback you are enabling us to constantly improve our products and always deliver the best quality to both you and your team. diff --git a/marketplace-ui/src/assets/images/misc/search-off.svg b/marketplace-ui/src/assets/images/misc/search-off.svg new file mode 100644 index 000000000..0ecde8570 --- /dev/null +++ b/marketplace-ui/src/assets/images/misc/search-off.svg @@ -0,0 +1,11 @@ + + + + + + + + + + +