Skip to content

Commit

Permalink
Allow architectures to be loaded from git repository (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbouchenoire committed Jun 13, 2020
1 parent cb4edcf commit ecaeda8
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 21 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ dependencies {
implementation "com.fasterxml.jackson.module:jackson-module-afterburner"
implementation "org.apache.commons:commons-lang3"
implementation "commons-io:commons-io"
implementation "org.eclipse.jgit:org.eclipse.jgit:5.7.0.202003110725-r"
implementation "org.springframework.boot:spring-boot-loader-tools"
implementation "org.springframework.boot:spring-boot-starter-logging"
implementation "org.springframework.boot:spring-boot-starter-actuator"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,23 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;

@Repository
public class StaticArchitectureRepository {
//@Repository
@ConditionalOnProperty(prefix = "application.architectures.", value = "directory")
@ConditionalOnMissingBean(ArchitectureGitRepository.class)
public class ArchitectureDirectoryRepository implements ArchitectureRepository {

private static final Logger LOG = LoggerFactory.getLogger(StaticArchitectureRepository.class);
private static final Logger LOG = LoggerFactory.getLogger(ArchitectureDirectoryRepository.class);

private final Map<String, SoftwareArchitecture> architectures;

public StaticArchitectureRepository(
public ArchitectureDirectoryRepository(
@Value("${application.architectures.directory}") String architecturesDirectoryPath,
MasterManifestDeserializer masterManifestDeserializer) {

Expand All @@ -60,13 +59,15 @@ public StaticArchitectureRepository(
.getOrElseThrow(throwable -> new IllegalStateException("Could not load software architecture", throwable)))
.collect(Collectors.toMap(SoftwareArchitecture::getName, architecture -> architecture));

LOG.info("Loaded {} static architecture(s)", architectures.size());
LOG.info("Loaded {} architecture(s) from directory: {}", architectures.size(), architecturesDirectory);
}

@Override
public Optional<SoftwareArchitecture> findByName(String name) {
return Optional.ofNullable(architectures.get(name));
}

@Override
public List<SoftwareArchitecture> findAll() {
return new ArrayList<>(architectures.values());
}
Expand Down
68 changes: 68 additions & 0 deletions src/main/java/org/lowfer/repository/ArchitectureGitRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.lowfer.repository;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.lowfer.domain.common.SoftwareArchitecture;
import org.lowfer.serde.MasterManifestDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Repository;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;

@Repository
@ConditionalOnProperty(prefix = "application.architectures.", value = "repository.uri")
public class ArchitectureGitRepository implements ArchitectureRepository {

private static final Logger LOG = LoggerFactory.getLogger(ArchitectureGitRepository.class);

private final Git repository;
private final ArchitectureDirectoryRepository architectureDirectoryRepository;

public ArchitectureGitRepository(
MasterManifestDeserializer masterManifestDeserializer,
@Value("${application.architectures.repository.uri}") String uri,
@Value("${application.architectures.repository.branch:master}") String branch,
@Value("${application.architectures.repository.path:/}") String path,
@Value("${application.architectures.repository.username:}") String username,
@Value("${application.architectures.repository.password:}") String password) throws IOException, GitAPIException {

final File directoryFile = Files.createTempDirectory("lowfer-git").toFile();

LOG.info("Created temp directory ({}) for repository: {}", directoryFile, uri);

LOG.info("Cloning branch {} of git repository: {}...", branch, uri);

this.repository = Git.cloneRepository()
.setURI(uri)
.setDirectory(directoryFile)
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password))
.setBranch(branch)
.call();

LOG.info("Cloned git repository ({}) with {} branch(es)", uri, repository.branchList().call().size());

final Path fullPath = Path.of(directoryFile.getPath(), path);

this.architectureDirectoryRepository =
new ArchitectureDirectoryRepository(fullPath.toString(), masterManifestDeserializer);
}

@Override
public Optional<SoftwareArchitecture> findByName(String name) {
return architectureDirectoryRepository.findByName(name);
}

@Override
public List<SoftwareArchitecture> findAll() {
return architectureDirectoryRepository.findAll();
}
}
14 changes: 14 additions & 0 deletions src/main/java/org/lowfer/repository/ArchitectureRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.lowfer.repository;

import org.lowfer.domain.common.SoftwareArchitecture;

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

public interface ArchitectureRepository {

Optional<SoftwareArchitecture> findByName(String name);

List<SoftwareArchitecture> findAll();
}

14 changes: 7 additions & 7 deletions src/main/java/org/lowfer/service/ArchitectureService.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import org.lowfer.domain.common.SoftwareArchitecture;
import org.lowfer.domain.common.SoftwareComponentFilter;
import org.lowfer.domain.error.ArchitectureNotFoundException;
import org.lowfer.repository.StaticArchitectureRepository;
import org.lowfer.repository.ArchitectureRepository;
import org.lowfer.serde.ManifestEncoder;
import org.lowfer.serde.ManifestSerializer;
import org.lowfer.web.rest.vm.IssueView;
Expand All @@ -47,34 +47,34 @@ public class ArchitectureService {

private static final Logger LOG = LoggerFactory.getLogger(ArchitectureService.class);

private final StaticArchitectureRepository staticArchitectureRepository;
private final ArchitectureRepository architectureRepository;
private final ArchitectureTransformer architectureTransformer;
private final ManifestSerializer manifestSerializer;
private final ManifestEncoder manifestEncoder;

public ArchitectureService(
StaticArchitectureRepository staticArchitectureRepository,
ArchitectureRepository architectureRepository,
ArchitectureTransformer architectureTransformer,
ManifestSerializer manifestSerializer,
ManifestEncoder manifestEncoder) {

this.staticArchitectureRepository = staticArchitectureRepository;
this.architectureRepository = architectureRepository;
this.architectureTransformer = architectureTransformer;
this.manifestSerializer = manifestSerializer;
this.manifestEncoder = manifestEncoder;
}

public List<SoftwareArchitecture> findAll() {
return staticArchitectureRepository.findAll();
return architectureRepository.findAll();
}

public Try<SoftwareArchitecture> load(String name, String encoded) {
if (isNotBlank(name) && isNotBlank(encoded))
throw new IllegalArgumentException("Cannot load architecture when given both name and encoded representation");

if (isNotBlank(name)) {
LOG.debug("Finding static architecture with name='{}'...", name);
return staticArchitectureRepository.findByName(name)
LOG.debug("Finding architecture with name='{}'...", name);
return architectureRepository.findByName(name)
.map(Try::success)
.orElse(failure(new ArchitectureNotFoundException(name)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@

import static org.junit.jupiter.api.Assertions.*;

class StaticArchitectureRepositoryTest {
class ArchitectureDirectoryRepositoryTest {

@Test
public void testFindArchitectureByName() {
final StaticArchitectureRepository repository = new StaticArchitectureRepository(
final ArchitectureDirectoryRepository repository = new ArchitectureDirectoryRepository(
"src/test/resources/architectures/sample", new ManifestYamlParser());

final SoftwareArchitecture sample = repository.findByName("sample").orElseThrow();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.lowfer.repository;

import org.eclipse.jgit.api.errors.GitAPIException;
import org.junit.jupiter.api.Test;
import org.lowfer.domain.common.SoftwareArchitecture;
import org.lowfer.serde.ManifestYamlParser;

import java.io.IOException;
import java.util.List;

import static org.junit.Assert.assertFalse;

class ArchitectureGitRepositoryTestIT {

@Test
public void testInitializeArchitectureGitRepository() throws IOException, GitAPIException {
final ArchitectureGitRepository repository = new ArchitectureGitRepository(
new ManifestYamlParser(),
"https://github.com/mbouchenoire/lowfer.git",
"0.1.0",
"src/test/resources/architectures/demo",
"",
"");

final List<SoftwareArchitecture> architectures = repository.findAll();
assertFalse(architectures.isEmpty());
}
}
2 changes: 1 addition & 1 deletion src/test/resources/config/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,4 @@ jhipster:

application:
architectures:
directory: src/test/resources/architectures/spinnaker
directory: src/test/resources/architectures/demo

0 comments on commit ecaeda8

Please sign in to comment.