diff --git a/microservice-visualization-webapp/src/app/api/application-api.model.ts b/microservice-visualization-webapp/src/app/api/application-api.model.ts index a81b936..f11251f 100644 --- a/microservice-visualization-webapp/src/app/api/application-api.model.ts +++ b/microservice-visualization-webapp/src/app/api/application-api.model.ts @@ -1,3 +1,10 @@ +export interface DependencyManagement { + groupId: string, + artifactId: string, + version: string, + dependencies: string[] +} + export interface ApplicationDto { id: number, name: string, @@ -7,7 +14,7 @@ export interface ApplicationDto { owner: string, tags: Map, dependencies: string[], - managementDependencies: string[] + dependencyManagements: DependencyManagement[] } export interface ApplicationLiteDto { diff --git a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/domain/model/Application.java b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/domain/model/Application.java index 026c17a..c121a46 100644 --- a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/domain/model/Application.java +++ b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/domain/model/Application.java @@ -54,9 +54,6 @@ public class Application { @ElementCollection private List<@NotNull DependencyEntity> fullDependencies; - - @ElementCollection - private List<@NotEmpty String> managementDependencies; @ToString.Exclude @ElementCollection diff --git a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/ProjectLoaderService.java b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/ProjectLoaderService.java index 07cfc66..8ea763a 100644 --- a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/ProjectLoaderService.java +++ b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/ProjectLoaderService.java @@ -158,62 +158,70 @@ protected Set createProjectRelevantTags(Project project) { return tags; } - protected Application convertApplicationDependencyToApplication(ApplicationDependency applicationDependency, ApplicationType type) { - Application application = new Application(); - application.setName(applicationDependency.name()); - String description = StringUtils.hasText(applicationDependency.description()) ? - applicationDependency.description() : String.format("%s application", applicationDependency.name()); - application.setDescription(description); - application.setLocation(applicationDependency.location()); - // Owner - String owner = applicationDependency.owner(); - if (StringUtils.hasText(owner)) { - application.setOwners(Arrays.stream(owner.split(";")) - .map(String::trim) - .filter(StringUtils::hasText) - .collect(Collectors.toSet())); - } + protected Optional convertApplicationDependencyToApplication(ApplicationDependency applicationDependency, ApplicationType type) { + try { + Application application = new Application(); + application.setName(applicationDependency.name()); + String description = StringUtils.hasText(applicationDependency.description()) ? + applicationDependency.description() : String.format("%s application", applicationDependency.name()); + application.setDescription(description); + application.setLocation(applicationDependency.location()); + // Owner + String owner = applicationDependency.owner(); + if (StringUtils.hasText(owner)) { + application.setOwners(Arrays.stream(owner.split(";")) + .map(String::trim) + .filter(StringUtils::hasText) + .collect(Collectors.toSet())); + } - application.setLabel(applicationDependency.label()); - application.setGroup(applicationDependency.group()); - application.setVersion(applicationDependency.version()); - application.setDependencies(applicationDependency.dependencies()); + application.setLabel(applicationDependency.label()); + application.setGroup(applicationDependency.group()); + application.setVersion(applicationDependency.version()); + application.setDependencies(applicationDependency.dependencies()); - Set dependencyManagements; + List dependencyManagements = new ArrayList<>(); - if (!CollectionUtils.isEmpty(applicationDependency.dependencyManagement())) { - application.setDependencyManagements(applicationDependency.dependencyManagement().entrySet().stream() - .map(entry -> ConverterUtils.mapToDependencyManagement(entry.getKey(), entry.getValue())).collect(Collectors.toList())); + if (!CollectionUtils.isEmpty(applicationDependency.dependencyManagement())) { + dependencyManagements = applicationDependency.dependencyManagement().entrySet().stream() + .map(entry -> ConverterUtils.mapToDependencyManagement(entry.getKey(), entry.getValue())).collect(Collectors.toList()); + } else if (!CollectionUtils.isEmpty(applicationDependency.managementDependencies())) { + dependencyManagements = applicationDependency.managementDependencies().stream() + .map(entry -> ConverterUtils.mapToDependencyManagement(entry, new HashMap<>())) + .collect(Collectors.toList()); + } + application.setDependencyManagements(dependencyManagements); - dependencyManagements = application.getDependencyManagements().stream() + Set fullDependencyManagements = application.getDependencyManagements().stream() .map(DependencyManagement::getDependencies) .flatMap(List::stream).collect(Collectors.toSet()); - } else { - dependencyManagements = new HashSet<>(); - } - if (!CollectionUtils.isEmpty(applicationDependency.fullDependencies())) { - application.setFullDependencies(applicationDependency.fullDependencies().stream() - .map(dependencyString -> getDependencyEntity(dependencyString, dependencyManagements)) - .collect(Collectors.toList())); - } else if (!CollectionUtils.isEmpty(applicationDependency.dependencies())) { - application.setFullDependencies(applicationDependency.dependencies().stream() - .map(dependencyString -> getDependencyEntity(dependencyString, dependencyManagements)) - .collect(Collectors.toList())); - } + if (!CollectionUtils.isEmpty(applicationDependency.fullDependencies())) { + application.setFullDependencies(applicationDependency.fullDependencies().stream() + .map(dependencyString -> getDependencyEntity(dependencyString, fullDependencyManagements)) + .collect(Collectors.toList())); + } else if (!CollectionUtils.isEmpty(applicationDependency.dependencies())) { + application.setFullDependencies(applicationDependency.dependencies().stream() + .map(dependencyString -> getDependencyEntity(dependencyString, fullDependencyManagements)) + .collect(Collectors.toList())); + } - Map tags = new HashMap<>(applicationDependency.tags()); + Map tags = new HashMap<>(applicationDependency.tags()); - Map relevantTags = properties.getTags(); + Map relevantTags = properties.getTags(); - // Management dependencies - tags.putAll(findTags(applicationDependency.managementDependencies(), relevantTags)); + // Management dependencies + tags.putAll(findTags(applicationDependency.managementDependencies(), relevantTags)); - // Dependencies - tags.putAll(findTags(applicationDependency.dependencies(), relevantTags)); - application.setTags(tags); - application.setType(type); - return application; + // Dependencies + tags.putAll(findTags(applicationDependency.dependencies(), relevantTags)); + application.setTags(tags); + application.setType(type); + return Optional.of(application); + } catch (Exception e) { + log.error("Failed convert ApplicationDependency {} -> Application", applicationDependency.name(), e); + return Optional.empty(); + } } private static DependencyEntity getDependencyEntity(String dependencyString, Set dependencyManagements) { @@ -242,15 +250,28 @@ private Map findTags(List dependencies, Map getApplicationDependency(String fileContent) { try { - return objectMapper.readValue(fileContent, ApplicationDependency.class); + return Optional.of(objectMapper.readValue(fileContent, ApplicationDependency.class)); } catch (IOException e) { log.error("Failed read application file", e); - return null; + return Optional.empty(); } } + protected Optional convertContentToApplication(String fileContent, ApplicationType defaultType) { + return getApplicationDependency(fileContent) + .flatMap(appDep -> convertApplicationDependencyToApplication(appDep, defaultType)); + } + + protected List convertContentToApplication(List filesContent, ApplicationType defaultType) { + return filesContent.stream() + .map(content -> convertContentToApplication(content, defaultType)) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + } + /** * Get Project Configuration from content */ diff --git a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/bitbucket/BitbucketProjectLoaderService.java b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/bitbucket/BitbucketProjectLoaderService.java index 0e0909e..04b8768 100644 --- a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/bitbucket/BitbucketProjectLoaderService.java +++ b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/bitbucket/BitbucketProjectLoaderService.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; @Slf4j @@ -66,19 +67,31 @@ private Project getProjectByVersion(LoaderDetails loaderDetails, String versionI return project; } - private List getApplicationsByFolder(LoaderDetails loaderDetails, String versionId, BitBucketV1Api api, String folderName, ApplicationType appType) { + private List getApplicationsByFolder(LoaderDetails loaderDetails, String versionId, BitBucketV1Api api, String folderName, ApplicationType defaultType) { try { List allApplicationsByBranch = api.getAllApplicationsByBranch(loaderDetails.getProject(), loaderDetails.getRepo(), versionId, folderName); - return allApplicationsByBranch.stream().map(applicationFileName -> - convertApplicationDependencyToApplication(getApplicationDependency(api.getApplicationByBranch(loaderDetails.getProject(), loaderDetails.getRepo(), versionId, folderName, applicationFileName)), - appType)) - .toList(); + + return allApplicationsByBranch.stream() + .map(applicationFileName -> readContent(loaderDetails, versionId, api, folderName, applicationFileName) + .flatMap(contentString -> convertContentToApplication(contentString, defaultType))) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); } catch (Exception e) { log.error("Failed load folder: '{}'", folderName, e); return List.of(); } } + protected Optional readContent(LoaderDetails loaderDetails, String versionId, BitBucketV1Api api, String folderName, String applicationFileName) { + try { + return Optional.of(api.getApplicationByBranch(loaderDetails.getProject(), loaderDetails.getRepo(), versionId, folderName, applicationFileName)); + } catch (Exception e) { + log.error("Failed read application file {}/{}", folderName, applicationFileName, e); + return Optional.empty(); + } + } + @Override protected String getFullName(MicroserviceVisualizationProperties.ProjectDetails projectProperty) { return BitbucketConverterUtils.getFullName(projectProperty.getProject(), projectProperty.getRepo()); diff --git a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/github/GithubProjectLoaderService.java b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/github/GithubProjectLoaderService.java index dbd0de6..3c64c95 100644 --- a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/github/GithubProjectLoaderService.java +++ b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/github/GithubProjectLoaderService.java @@ -21,7 +21,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; @Slf4j @@ -82,26 +82,30 @@ private Project getProjectByVersion(String versionId, String version, GHReposito return project; } - private List getApplicationsByFolder(GHRepository projectRepository, String versionId, String folderName, ApplicationType appType) { + private List getApplicationsByFolder(GHRepository projectRepository, String versionId, String folderName, ApplicationType defaultType) { try { List directoryContent = projectRepository.getDirectoryContent(folderName, versionId); - return directoryContent.stream().map(ghContent -> { - try { - String encodedContent = projectRepository.getFileContent(ghContent.getPath(), versionId).getContent(); - return convertApplicationDependencyToApplication(getApplicationDependency(encodedContent), appType); - } catch (IOException e) { - log.error("Failed retrieve content of '{}'", ghContent.getPath(), e); - return null; - } - }).filter(Objects::nonNull) - .toList(); + return directoryContent.stream().map(applicationFileName -> readContent(projectRepository, applicationFileName.getPath(), versionId) + .flatMap(contentString -> convertContentToApplication(contentString, defaultType))) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); } catch (Exception e) { log.error("Failed load folder: '{}'", folderName, e); return List.of(); } } + protected Optional readContent(GHRepository projectRepository, String path, String versionId) { + try { + return Optional.of(projectRepository.getFileContent(path, versionId).getContent()); + } catch (Exception e) { + log.error("Failed read application file {}", path, e); + return Optional.empty(); + } + } + @Override protected String getFullName(MicroserviceVisualizationProperties.ProjectDetails projectProperty) { return BitbucketConverterUtils.getFullName(projectProperty.getProject(), projectProperty.getRepo()); diff --git a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/local/LocalProjectLoaderService.java b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/local/LocalProjectLoaderService.java index 1ccc82f..de67489 100644 --- a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/local/LocalProjectLoaderService.java +++ b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/loaders/local/LocalProjectLoaderService.java @@ -8,7 +8,6 @@ import com.github.rbaul.microservice_visualization.domain.model.Project; import com.github.rbaul.microservice_visualization.service.loaders.ProjectLoaderService; import com.github.rbaul.microservice_visualization.service.loaders.ProjectLoaderType; -import com.github.rbaul.microservice_visualization.service.model.ApplicationDependency; import com.github.rbaul.microservice_visualization.service.model.ProjectConfig; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -22,7 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; @Slf4j @@ -60,13 +59,15 @@ public Project getProjectVersion(LoaderDetails loaderDetails, String versionId, return project; } - private List getApplicationsByType(String dir, String applicationsFolder, ApplicationType type) { + private List getApplicationsByType(String dir, String applicationsFolder, ApplicationType defaultType) { Path folder = Paths.get(MessageFormat.format("{0}/{1}", dir, applicationsFolder)); File[] listApplicationFiles = folder.toFile().listFiles(File::isFile); return listApplicationFiles == null ? List.of() : Arrays.stream(listApplicationFiles) - .map(file -> getApplication(Paths.get(file.toURI()), type)) - .filter(Objects::nonNull) + .map(file -> readContent(Paths.get(file.toURI())) + .flatMap(contentString -> convertContentToApplication(contentString, defaultType))) + .filter(Optional::isPresent) + .map(Optional::get) .toList(); } @@ -80,12 +81,12 @@ public ProjectLoaderType getType() { return ProjectLoaderType.local; } - protected ApplicationDependency getApplicationDependency(Path path) { + protected Optional readContent(Path path) { try { - return getApplicationDependency(Files.readString(path)); + return Optional.of(Files.readString(path)); } catch (IOException e) { log.error("Failed read application file {}", path, e); - return null; + return Optional.empty(); } } @@ -98,12 +99,4 @@ protected ProjectConfig getProjectConfiguration(Path path) { } } - protected Application getApplication(Path path, ApplicationType type) { - ApplicationDependency applicationDependency = getApplicationDependency(path); - if (applicationDependency != null) { - return convertApplicationDependencyToApplication(applicationDependency, type); - } - return null; - } - } diff --git a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/model/ApplicationDependency.java b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/model/ApplicationDependency.java index 5359e36..3d9f162 100644 --- a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/model/ApplicationDependency.java +++ b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/service/model/ApplicationDependency.java @@ -9,6 +9,7 @@ public record ApplicationDependency( String name, String label, + String type, String description, String group, String version, diff --git a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/web/dto/ApplicationFullDto.java b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/web/dto/ApplicationFullDto.java index 4cf1c39..96b14d0 100644 --- a/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/web/dto/ApplicationFullDto.java +++ b/microservice-visualization/src/main/java/com/github/rbaul/microservice_visualization/web/dto/ApplicationFullDto.java @@ -18,8 +18,6 @@ public class ApplicationFullDto extends ApplicationLiteDto { private List dependencies; - - private List managementDependencies; private List dependencyManagements; } diff --git a/plugins/gradle/dependencies-util.gradle b/plugins/gradle/dependencies-util.gradle index a928073..28132b2 100644 --- a/plugins/gradle/dependencies-util.gradle +++ b/plugins/gradle/dependencies-util.gradle @@ -68,11 +68,16 @@ Map getManagementDependencies(Map dependencies) Map bomDetails = [:] - def boms = dependencyManagement.getPomConfigurer().dependencyManagement.importedBoms + def dependencyManagement = dependencyManagement.getPomConfigurer().dependencyManagement + def boms = dependencyManagement.importedBoms if (boms.size() > 0) { - def poms = dependencyManagement.getPomConfigurer().dependencyManagement.pomResolver.resolvePoms(boms, boms[0].getProperties()) - poms.each { - + def resolvedBoms + if (boms[0].class.getSimpleName() == "Pom") { // Already resolved (1.0.11.RELEASE) + resolvedBoms = boms + } else { // Not resolved + resolvedBoms = dependencyManagement.pomResolver.resolvePomsLeniently(boms) + } + resolvedBoms.each { def pomCoordinates = getDependencyFormatted(it.getCoordinates().groupId, it.getCoordinates().artifactId, it.getCoordinates().version) Map dependency = [:] it.getManagedDependencies().each { @@ -81,7 +86,6 @@ Map getManagementDependencies(Map dependencies) dependency.put(dependencyVersion, it.getCoordinates().version) } } - bomDetails.put(pomCoordinates, dependency) } }