Skip to content
This repository has been archived by the owner on Nov 3, 2022. It is now read-only.

Commit

Permalink
[#14] supported formats are detected at runtime using Spring services
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Pozzi committed Nov 10, 2019
1 parent afc932d commit 360f505
Show file tree
Hide file tree
Showing 22 changed files with 204 additions and 161 deletions.
14 changes: 8 additions & 6 deletions src/main/java/de/bonndan/nivio/api/ApiController.java
Expand Up @@ -5,7 +5,6 @@
import de.bonndan.nivio.input.*;
import de.bonndan.nivio.input.dto.LandscapeDescription;
import de.bonndan.nivio.input.dto.ItemDescription;
import de.bonndan.nivio.input.dto.SourceFormat;
import de.bonndan.nivio.input.dto.SourceReference;
import de.bonndan.nivio.model.*;
import de.bonndan.nivio.util.URLHelper;
Expand All @@ -29,12 +28,14 @@
public class ApiController {

private final LandscapeRepository landscapeRepository;
private final ItemDescriptionFormatFactory formatFactory;
private final Indexer indexer;
private final FileFetcher fileFetcher;

@Autowired
public ApiController(LandscapeRepository landscapeRepository, Indexer indexer, FileFetcher fileFetcher) {
public ApiController(LandscapeRepository landscapeRepository, ItemDescriptionFormatFactory formatFactory, Indexer indexer, FileFetcher fileFetcher) {
this.landscapeRepository = landscapeRepository;
this.formatFactory = formatFactory;
this.indexer = indexer;
this.fileFetcher = fileFetcher;
}
Expand Down Expand Up @@ -90,12 +91,13 @@ public ProcessLog indexLandscape(
env.setIdentifier(identifier);
env.setIsPartial(true);

SourceReference sourceReference = new SourceReference(SourceFormat.from(format));
sourceReference.setUrl(null);
SourceReference sourceReference = new SourceReference(null, format);
sourceReference.setContent(body);

ItemDescriptionFactory factory = ItemDescriptionFormatFactory.getFactory(sourceReference, env);
List<ItemDescription> itemDescriptions = factory.getDescriptions(sourceReference);
ItemDescriptionFactory factory = formatFactory.getFactory(sourceReference, env);
URL baseUrl = URLHelper.getParentPath(env.getSource());

List<ItemDescription> itemDescriptions = factory.getDescriptions(sourceReference, baseUrl);

env.setItemDescriptions(itemDescriptions);

Expand Down
5 changes: 4 additions & 1 deletion src/main/java/de/bonndan/nivio/input/Indexer.java
Expand Up @@ -20,13 +20,16 @@ public class Indexer {
private static final Logger _logger = LoggerFactory.getLogger(Indexer.class);

private final LandscapeRepository landscapeRepo;
private final ItemDescriptionFormatFactory formatFactory;
private final NotificationService notificationService;


public Indexer(LandscapeRepository landscapeRepository,
ItemDescriptionFormatFactory formatFactory,
NotificationService notificationService
) {
this.landscapeRepo = landscapeRepository;
this.formatFactory = formatFactory;
this.notificationService = notificationService;
}

Expand All @@ -48,7 +51,7 @@ public ProcessLog reIndex(final LandscapeDescription input) {

try {
Map<ItemDescription, List<String>> templatesAndTargets = new HashMap<>();
new SourceReferencesResolver(logger).resolve(input, templatesAndTargets);
new SourceReferencesResolver(formatFactory, logger).resolve(input, templatesAndTargets);
new TemplateResolver().processTemplates(input, templatesAndTargets);
new RelationResolver(logger).processRelations(input);
input.getGroups().forEach((identifier, groupItem) -> {
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/de/bonndan/nivio/input/ItemDescriptionFactory.java
Expand Up @@ -3,13 +3,22 @@
import de.bonndan.nivio.input.dto.ItemDescription;
import de.bonndan.nivio.input.dto.SourceReference;

import java.net.URL;
import java.util.List;

import static de.bonndan.nivio.util.SafeAssign.assignSafe;

/**
* Processors of input sources must implement this interface.
*
*
*/
public interface ItemDescriptionFactory {

List<ItemDescription> getDescriptions(SourceReference reference);
List<String> getFormats();

List<ItemDescription> getDescriptions(SourceReference reference, URL baseUrl);


static void assignNotNull(ItemDescription existing, ItemDescription increment) {

Expand Down
@@ -1,44 +1,58 @@
package de.bonndan.nivio.input;

import de.bonndan.nivio.input.compose2.ItemDescriptionFactoryCompose2;
import de.bonndan.nivio.ProcessingException;
import de.bonndan.nivio.input.dto.LandscapeDescription;
import de.bonndan.nivio.input.dto.SourceReference;
import de.bonndan.nivio.input.http.HttpService;
import de.bonndan.nivio.input.kubernetes.ItemDescriptionFactoryKubernetes;
import de.bonndan.nivio.input.nivio.ItemDescriptionFactoryNivio;
import de.bonndan.nivio.input.rancher1.ItemDescriptionFactoryRancher1;
import de.bonndan.nivio.util.URLHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class ItemDescriptionFormatFactory {

private final Map<ItemDescriptionFactory, List<String>> factoryListMap = new ConcurrentHashMap<>();

public static ItemDescriptionFormatFactory with(ItemDescriptionFactory factory) {
return new ItemDescriptionFormatFactory(new ArrayList<>(Arrays.asList(factory)));
}

public ItemDescriptionFormatFactory(List<ItemDescriptionFactory> factories) {
factories.forEach(itemDescriptionFactory -> factoryListMap.put(itemDescriptionFactory, itemDescriptionFactory.getFormats()));
}

/**
* Returns the proper factory to generate/parse service descriptions based on the input format.
*
* @param reference the reference pointing at a file or url
* @param reference the reference pointing at a file or url
* @param landscapeDescription landscape, may contain a base url
* @return the factory
*/
public static ItemDescriptionFactory getFactory(SourceReference reference, LandscapeDescription landscapeDescription) {

URL baseUrl = URLHelper.getParentPath(landscapeDescription.getSource());

FileFetcher fetcher = new FileFetcher(new HttpService());

if (reference == null || reference.getFormat() == null)
return new ItemDescriptionFactoryNivio(fetcher, baseUrl);

//TODO use SourceFormat.from or similar
switch (reference.getFormat()) {
case DOCKER_COMPOSE2:
return new ItemDescriptionFactoryCompose2(new FileFetcher(new HttpService()), baseUrl);
case KUBERNETES:
return new ItemDescriptionFactoryKubernetes(reference);
case RANCHER1_PROMETHEUS:
return new ItemDescriptionFactoryRancher1(baseUrl);
public ItemDescriptionFactory getFactory(SourceReference reference, LandscapeDescription landscapeDescription) {

List<ItemDescriptionFactory> factories = new ArrayList<>();
factoryListMap.entrySet().stream()
.filter(entry -> entry.getValue().stream().map(s -> {
if (StringUtils.isEmpty(s))
return "";
return s.toLowerCase();
}).anyMatch(s -> s.equals(reference.getFormat()) || (StringUtils.isEmpty(s) && StringUtils.isEmpty(reference.getFormat()))))
.forEach(entry -> factories.add(entry.getKey()));

if (factories.isEmpty()) {
List<String> knownFormats = new ArrayList<>();
factoryListMap.values().forEach(knownFormats::addAll);
String msg = "Unknown source reference format: '" + reference.getFormat() + "', known formats are: "
+ StringUtils.collectionToDelimitedString(knownFormats, ", ");
throw new ProcessingException(landscapeDescription, msg);
}

return new ItemDescriptionFactoryNivio(fetcher, baseUrl);
//last one wins
return factories.get(factories.size() - 1);
}
}
Expand Up @@ -3,7 +3,9 @@
import de.bonndan.nivio.ProcessingException;
import de.bonndan.nivio.input.dto.LandscapeDescription;
import de.bonndan.nivio.input.dto.ItemDescription;
import de.bonndan.nivio.util.URLHelper;

import java.net.URL;
import java.util.List;
import java.util.Map;

Expand All @@ -15,18 +17,21 @@
*/
public class SourceReferencesResolver {

private final ItemDescriptionFormatFactory formatFactory;
private final ProcessLog log;

public SourceReferencesResolver(ProcessLog logger) {
public SourceReferencesResolver(ItemDescriptionFormatFactory formatFactory, ProcessLog logger) {
this.formatFactory = formatFactory;
this.log = logger;
}

public void resolve(final LandscapeDescription landscapeDescription, Map<ItemDescription, List<String>> templatesAndTargets) {

URL baseUrl = URLHelper.getParentPath(landscapeDescription.getSource());
landscapeDescription.getSourceReferences().forEach(ref -> {
try {
ItemDescriptionFactory factory = ItemDescriptionFormatFactory.getFactory(ref, landscapeDescription);
landscapeDescription.addItems(factory.getDescriptions(ref));
ItemDescriptionFactory factory = formatFactory.getFactory(ref, landscapeDescription);
landscapeDescription.addItems(factory.getDescriptions(ref, baseUrl));
ref.getAssignTemplates().forEach((key, identifiers) -> templatesAndTargets.put(landscapeDescription.getTemplates().get(key), identifiers));
} catch (ProcessingException ex) {
log.warn("Failed to resolve source reference " + ref, ex);
Expand Down
Expand Up @@ -9,14 +9,18 @@
import de.bonndan.nivio.input.ItemDescriptionFactory;
import de.bonndan.nivio.input.dto.ItemDescription;
import de.bonndan.nivio.input.dto.SourceReference;
import de.bonndan.nivio.input.http.HttpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class ItemDescriptionFactoryCompose2 implements ItemDescriptionFactory {

private static final Logger logger = LoggerFactory.getLogger(ItemDescriptionFactory.class);
Expand All @@ -28,14 +32,22 @@ public class ItemDescriptionFactoryCompose2 implements ItemDescriptionFactory {
}

private final FileFetcher fileFetcher;
private final URL baseUrl;

public ItemDescriptionFactoryCompose2(FileFetcher fileFetcher, URL baseUrl) {
public ItemDescriptionFactoryCompose2(FileFetcher fileFetcher) {
this.fileFetcher = fileFetcher;
this.baseUrl = baseUrl;
}

public List<ItemDescription> getDescriptions(SourceReference reference) {
public static ItemDescriptionFactory forTesting() {
return new ItemDescriptionFactoryCompose2(new FileFetcher(new HttpService()));
}


@Override
public List<String> getFormats() {
return Arrays.asList("docker-compose-v2");
}

public List<ItemDescription> getDescriptions(SourceReference reference, URL baseUrl) {

List<ItemDescription> itemDescriptions = new ArrayList<>();
String yml = fileFetcher.get(reference, baseUrl);
Expand Down
46 changes: 0 additions & 46 deletions src/main/java/de/bonndan/nivio/input/dto/SourceFormat.java

This file was deleted.

11 changes: 4 additions & 7 deletions src/main/java/de/bonndan/nivio/input/dto/SourceReference.java
Expand Up @@ -14,7 +14,7 @@ public class SourceReference {

private LandscapeDescription landscapeDescription;

private SourceFormat format;
private String format;

private String basicAuthUsername;
private String basicAuthPassword;
Expand All @@ -34,7 +34,8 @@ public SourceReference(String url) {
this.url = url;
}

public SourceReference(SourceFormat format) {
public SourceReference(String url, String format) {
this.url = url;
this.format = format;
}

Expand All @@ -50,15 +51,11 @@ public void setLandscapeDescription(LandscapeDescription landscapeDescription) {
this.landscapeDescription = landscapeDescription;
}

public SourceFormat getFormat() {
public String getFormat() {
return format;
}

public void setFormat(String format) {
this.format = SourceFormat.from(format);
}

public void setFormat(SourceFormat format) {
this.format = format;
}

Expand Down
@@ -1,6 +1,8 @@
package de.bonndan.nivio.input.kubernetes;

import de.bonndan.nivio.input.FileFetcher;
import de.bonndan.nivio.input.ItemDescriptionFactory;
import de.bonndan.nivio.input.ItemDescriptionFormatFactory;
import de.bonndan.nivio.input.dto.ItemDescription;
import de.bonndan.nivio.input.dto.RelationDescription;
import de.bonndan.nivio.input.dto.SourceReference;
Expand All @@ -20,6 +22,7 @@
import java.net.URL;
import java.util.*;

@org.springframework.stereotype.Service
public class ItemDescriptionFactoryKubernetes implements ItemDescriptionFactory {

public static final String NAMESPACE = "namespace";
Expand All @@ -29,7 +32,23 @@ public class ItemDescriptionFactoryKubernetes implements ItemDescriptionFactory
private String groupLabel = null;
private KubernetesClient client;

public ItemDescriptionFactoryKubernetes(SourceReference reference) {

public ItemDescriptionFactoryKubernetes() {

}

public ItemDescriptionFactoryKubernetes(KubernetesClient client) {
this.client = client;
}

@Override
public List<String> getFormats() {
return Arrays.asList("kubernetes", "k8s");
}

@Override
public List<ItemDescription> getDescriptions(SourceReference reference, URL baseUrl) {

try {
if (!StringUtils.isEmpty(reference.getUrl())) {
URL url = new URL(reference.getUrl());
Expand All @@ -42,15 +61,7 @@ public ItemDescriptionFactoryKubernetes(SourceReference reference) {
} catch (MalformedURLException ignored) {

}
}

public ItemDescriptionFactoryKubernetes(SourceReference reference, KubernetesClient client) {
this(reference);
this.client = client;
}

@Override
public List<ItemDescription> getDescriptions(SourceReference reference) {
KubernetesClient client = getClient(reference.getUrl());

List<ItemDescription> descriptions = new ArrayList<>();
Expand Down

0 comments on commit 360f505

Please sign in to comment.