Skip to content

Commit

Permalink
feature/marp 661 open marketplace from within axon ivy
Browse files Browse the repository at this point in the history
  • Loading branch information
ntqdinh-axonivy authored Aug 1, 2024
1 parent 08a67ff commit 3bf8097
Show file tree
Hide file tree
Showing 36 changed files with 644 additions and 280 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package com.axonivy.market.assembler;

import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.GitHubConstants;
import com.axonivy.market.controller.ProductDetailsController;
import com.axonivy.market.entity.Product;
import com.axonivy.market.entity.ProductModuleContent;
import com.axonivy.market.enums.NonStandardProduct;
import com.axonivy.market.model.ProductDetailModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.hateoas.server.mvc.RepresentationModelAssemblerSupport;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;

import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
Expand All @@ -26,11 +30,12 @@ public ProductDetailModelAssembler(ProductModelAssembler productModelAssembler)

@Override
public ProductDetailModel toModel(Product product) {
return createModel(product, null);
return createModel(product, StringUtils.EMPTY);
}

public ProductDetailModel toModel(Product product, String tag) {
return createModel(product, tag);
public ProductDetailModel toModel(Product product, String version) {
String productId = Optional.ofNullable(product).map(Product::getId).orElse(StringUtils.EMPTY);
return createModel(product, convertVersionToTag(productId, version));
}

private ProductDetailModel createModel(Product product, String tag) {
Expand Down Expand Up @@ -70,4 +75,17 @@ private void createDetailResource(ProductDetailModel model, Product product, Str
private ProductModuleContent getProductModuleContentByTag(List<ProductModuleContent> contents, String tag) {
return contents.stream().filter(content -> StringUtils.equals(content.getTag(), tag)).findAny().orElse(null);
}

public String convertVersionToTag(String productId, String version) {
if (StringUtils.isBlank(version)) {
return version;
}
String[] versionParts = version.split(CommonConstants.SPACE_SEPARATOR);
String versionNumber = versionParts[versionParts.length - 1];
NonStandardProduct product = NonStandardProduct.findById(productId);
if (product.isVersionTagNumberOnly()) {
return versionNumber;
}
return GitHubConstants.STANDARD_TAG_PREFIX.concat(versionNumber);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ public class GitHubConstants {
public static final String GITHUB_PROVIDER_NAME = "GitHub";
public static final String GITHUB_GET_ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
public static final String README_FILE_LOCALE_REGEX = "_(..)";
public static final String STANDARD_TAG_PREFIX = "v";
public static final String COMMON_IMAGES_FOLDER_NAME = "images";

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public static class Json {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public ResponseEntity<Integer> syncInstallationCount(@PathVariable(ID) String ke
@GetMapping(BY_ID)
public ResponseEntity<ProductDetailModel> findProductDetails(@PathVariable(ID) String id) {
var productDetail = productService.fetchProductDetail(id);
return new ResponseEntity<>(detailModelAssembler.toModel(productDetail, null), HttpStatus.OK);
return new ResponseEntity<>(detailModelAssembler.toModel(productDetail), HttpStatus.OK);
}

@GetMapping(VERSIONS_BY_ID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public enum FileStatus {
MODIFIED("modified"), ADDED("added"), REMOVED("removed");

private String code;
private final String code;

public static FileStatus of(String code) {
for (var status : values()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public enum FileType {
META("meta.json"), LOGO("logo.png");

private String fileName;
private final String fileName;

public static FileType of(String name) {
for (var type : values()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.axonivy.market.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.axonivy.market.constants.GitHubConstants.COMMON_IMAGES_FOLDER_NAME;

@Getter
@AllArgsConstructor
public enum NonStandardProduct {
PORTAL("portal", true, COMMON_IMAGES_FOLDER_NAME, "AxonIvyPortal/portal-product"),
MICROSOFT_REPO_NAME("msgraph-connector", false, COMMON_IMAGES_FOLDER_NAME, ""),
MICROSOFT_365("msgraph", false, COMMON_IMAGES_FOLDER_NAME, "msgraph-connector-product/products/msgraph-connector"), // No meta.json
MICROSOFT_CALENDAR("msgraph-calendar", false, COMMON_IMAGES_FOLDER_NAME, "msgraph-connector-product/products/msgraph-calendar"), // no fix product json
MICROSOFT_MAIL("msgraph-mail", false, COMMON_IMAGES_FOLDER_NAME, "msgraph-connector-product/products/msgraph-mail"),// no fix product json
MICROSOFT_TEAMS("msgraph-chat", false, COMMON_IMAGES_FOLDER_NAME, "msgraph-connector-product/products/msgraph-chat"),// no fix product json
MICROSOFT_TODO("msgraph-todo", false, COMMON_IMAGES_FOLDER_NAME, "msgraph-connector-product/products/msgraph-todo"),// no fix product json
CONNECTIVITY_FEATURE("connectivity-demo", false, COMMON_IMAGES_FOLDER_NAME, "connectivity/connectivity-demos-product"),
EMPLOYEE_ONBOARDING("employee-onboarding", false, COMMON_IMAGES_FOLDER_NAME, ""), // Invalid meta.json
ERROR_HANDLING("error-handling-demo", false, COMMON_IMAGES_FOLDER_NAME, "error-handling/error-handling-demos-product"),
RULE_ENGINE_DEMOS("rule-engine-demo", false, COMMON_IMAGES_FOLDER_NAME, "rule-engine/rule-engine-demos-product"),
WORKFLOW_DEMO("workflow-demo", false, COMMON_IMAGES_FOLDER_NAME, "workflow/workflow-demos-product"),
HTML_DIALOG_DEMO("html-dialog-demo", false, COMMON_IMAGES_FOLDER_NAME, "html-dialog/html-dialog-demos-product"),
PROCESSING_VALVE_DEMO("processing-valve-demo", false, COMMON_IMAGES_FOLDER_NAME, ""),// no product json
OPENAI_CONNECTOR("openai-connector", false, COMMON_IMAGES_FOLDER_NAME, "openai-connector-product"),
OPENAI_ASSISTANT("openai-assistant", false, "docs", "openai-assistant-product"),
// Non standard image folder name
EXCEL_IMPORTER("excel-importer", false, "doc", ""),
EXPRESS_IMPORTER("express-importer", false, "img", ""),
GRAPHQL_DEMO("graphql-demo", false, "assets", ""),
DEEPL_CONNECTOR("deepl-connector", false, "img", ""),
DEFAULT("", false, COMMON_IMAGES_FOLDER_NAME, "");

private final String id;
private final boolean isVersionTagNumberOnly;
private final String pathToImageFolder;
private final String pathToProductFolder;
private static final Map<String, NonStandardProduct> NON_STANDARD_PRODUCT_MAP;

static {
NON_STANDARD_PRODUCT_MAP = Arrays.stream(NonStandardProduct.values()).collect(Collectors.toMap(NonStandardProduct::getId, Function.identity()));
}

public static NonStandardProduct findById(String id) {
return NON_STANDARD_PRODUCT_MAP.getOrDefault(id,DEFAULT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public enum TypeOption {
ALL("all", ""), CONNECTORS("connectors", "connector"), UTILITIES("utilities", "util"),
SOLUTIONS("solutions", "solution"), DEMOS("demos", "demo");

private String option;
private String code;
private final String option;
private final String code;

private TypeOption(String option, String code) {
this.option = option;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.GitHubConstants;
import com.axonivy.market.constants.MavenConstants;
import com.axonivy.market.constants.NonStandardProductPackageConstants;
import com.axonivy.market.constants.ProductJsonConstants;
import com.axonivy.market.constants.ReadmeConstants;
import com.axonivy.market.entity.Product;
import com.axonivy.market.entity.ProductModuleContent;
import com.axonivy.market.enums.Language;
import com.axonivy.market.enums.NonStandardProduct;
import com.axonivy.market.github.model.MavenArtifact;
import com.axonivy.market.github.service.GHAxonIvyProductRepoService;
import com.axonivy.market.github.service.GitHubService;
Expand Down Expand Up @@ -293,8 +293,8 @@ private List<GHContent> getProductFolderContents(Product product, GHRepository g
}

private boolean hasChildConnector(GHRepository ghRepository) {
return NonStandardProductPackageConstants.MICROSOFT_REPO_NAME.equals(ghRepository.getName())
|| NonStandardProductPackageConstants.OPENAI_CONNECTOR.equals(ghRepository.getName());
return NonStandardProduct.MICROSOFT_REPO_NAME.getId().equals(ghRepository.getName())
|| NonStandardProduct.OPENAI_CONNECTOR.getId().equals(ghRepository.getName());
}

private boolean hasImageDirectives(String readmeContents) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.axonivy.market.github.util;

import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.NonStandardProductPackageConstants;
import com.axonivy.market.enums.NonStandardProduct;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
Expand Down Expand Up @@ -63,72 +63,11 @@ public static String convertArtifactIdToName(String artifactId) {
}

public static String getNonStandardProductFilePath(String productId) {
switch (productId) {
case NonStandardProductPackageConstants.PORTAL:
pathToProductFolderFromTagContent = "AxonIvyPortal/portal-product";
break;
case NonStandardProductPackageConstants.CONNECTIVITY_FEATURE:
pathToProductFolderFromTagContent = "connectivity/connectivity-demos-product";
break;
case NonStandardProductPackageConstants.ERROR_HANDLING:
pathToProductFolderFromTagContent = "error-handling/error-handling-demos-product";
break;
case NonStandardProductPackageConstants.WORKFLOW_DEMO:
pathToProductFolderFromTagContent = "workflow/workflow-demos-product";
break;
case NonStandardProductPackageConstants.MICROSOFT_365:
pathToProductFolderFromTagContent = "msgraph-connector-product/products/msgraph-connector";
break;
case NonStandardProductPackageConstants.MICROSOFT_CALENDAR:
pathToProductFolderFromTagContent = "msgraph-connector-product/products/msgraph-calendar";
break;
case NonStandardProductPackageConstants.MICROSOFT_TEAMS:
pathToProductFolderFromTagContent = "msgraph-connector-product/products/msgraph-chat";
break;
case NonStandardProductPackageConstants.MICROSOFT_MAIL:
pathToProductFolderFromTagContent = "msgraph-connector-product/products/msgraph-mail";
break;
case NonStandardProductPackageConstants.MICROSOFT_TODO:
pathToProductFolderFromTagContent = "msgraph-connector-product/products/msgraph-todo";
break;
case NonStandardProductPackageConstants.HTML_DIALOG_DEMO:
pathToProductFolderFromTagContent = "html-dialog/html-dialog-demos-product";
break;
case NonStandardProductPackageConstants.RULE_ENGINE_DEMOS:
pathToProductFolderFromTagContent = "rule-engine/rule-engine-demos-product";
break;
case NonStandardProductPackageConstants.OPENAI_CONNECTOR:
pathToProductFolderFromTagContent = "openai-connector-product";
break;
case NonStandardProductPackageConstants.OPENAI_ASSISTANT:
pathToProductFolderFromTagContent = "openai-assistant-product";
break;
default:
break;
}
return pathToProductFolderFromTagContent;
return NonStandardProduct.findById(productId).getPathToProductFolder();
}

public static String getNonStandardImageFolder(String productId) {
String pathToImageFolder;
switch (productId) {
case NonStandardProductPackageConstants.EXCEL_IMPORTER:
pathToImageFolder = "doc";
break;
case NonStandardProductPackageConstants.EXPRESS_IMPORTER, NonStandardProductPackageConstants.DEEPL_CONNECTOR:
pathToImageFolder = "img";
break;
case NonStandardProductPackageConstants.GRAPHQL_DEMO:
pathToImageFolder = "assets";
break;
case NonStandardProductPackageConstants.OPENAI_ASSISTANT:
pathToImageFolder = "docs";
break;
default:
pathToImageFolder = "images";
break;
}
return pathToImageFolder;
return NonStandardProduct.findById(productId).getPathToImageFolder();
}

public static String extractMessageFromExceptionMessage(String exceptionMessage) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import com.axonivy.market.constants.CommonConstants;
import com.axonivy.market.constants.GitHubConstants;
import com.axonivy.market.constants.MavenConstants;
import com.axonivy.market.constants.NonStandardProductPackageConstants;
import com.axonivy.market.entity.MavenArtifactModel;
import com.axonivy.market.entity.MavenArtifactVersion;
import com.axonivy.market.entity.Product;
import com.axonivy.market.enums.NonStandardProduct;
import com.axonivy.market.github.model.ArchivedArtifact;
import com.axonivy.market.github.model.MavenArtifact;
import com.axonivy.market.github.service.GHAxonIvyProductRepoService;
Expand Down Expand Up @@ -257,7 +257,7 @@ public List<MavenArtifact> getProductJsonByVersion(String version) {

public String getVersionTag(String version) {
String versionTag = "v" + version;
if (NonStandardProductPackageConstants.PORTAL.equals(productId)) {
if (NonStandardProduct.PORTAL.getId().equals(productId)) {
versionTag = version;
}
return versionTag;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.axonivy.market.assembler;

import com.axonivy.market.enums.NonStandardProduct;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.springframework.test.context.junit.jupiter.SpringExtension;


@ExtendWith(SpringExtension.class)
class ProductDetailModelAssemblerTest {
@InjectMocks
private ProductDetailModelAssembler assembler;

@BeforeEach
void setup() {
assembler = new ProductDetailModelAssembler(new ProductModelAssembler());
}

@Test
void testConvertVersionToTag() {

String rawVersion = StringUtils.EMPTY;
Assertions.assertEquals(rawVersion, assembler.convertVersionToTag(StringUtils.EMPTY, rawVersion));

rawVersion = "Version 11.0.0";
String targetVersion = "11.0.0";
Assertions.assertEquals(targetVersion, assembler.convertVersionToTag(NonStandardProduct.PORTAL.getId(), rawVersion));

targetVersion = "v11.0.0";
Assertions.assertEquals(targetVersion, assembler.convertVersionToTag(NonStandardProduct.GRAPHQL_DEMO.getId(), rawVersion));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class ProductDetailsControllerTest {
@Test
void testProductDetails() {
Mockito.when(productService.fetchProductDetail(Mockito.anyString())).thenReturn(mockProduct());
Mockito.when(detailModelAssembler.toModel(mockProduct(), null)).thenReturn(createProductMockWithDetails());
Mockito.when(detailModelAssembler.toModel(mockProduct())).thenReturn(createProductMockWithDetails());
ResponseEntity<ProductDetailModel> mockExpectedResult = new ResponseEntity<>(createProductMockWithDetails(),
HttpStatus.OK);

Expand All @@ -60,7 +60,7 @@ void testProductDetails() {
assertEquals(result, mockExpectedResult);

verify(productService, times(1)).fetchProductDetail(DOCKER_CONNECTOR_ID);
verify(detailModelAssembler, times(1)).toModel(mockProduct(), null);
verify(detailModelAssembler, times(1)).toModel(mockProduct());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void testMappingLogo() throws IOException {
}

@Test
void testExtractSourceUrl() throws IOException {
void testExtractSourceUrl() {
Product product = new Product();
Meta meta = new Meta();
ProductFactory.extractSourceUrl(product, meta);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void testFetchMarketItemsBySHA1Range() throws IOException {
}

@Test
void testGetLastCommit() throws IOException {
void testGetLastCommit() {
var lastCommit = axonIvyMarketRepoServiceImpl.getLastCommit(0L);
assertNull(lastCommit);
}
Expand Down
Loading

0 comments on commit 3bf8097

Please sign in to comment.