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

Event observer #646

Merged
merged 24 commits into from
Oct 11, 2021
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
68a70c5
Merge branch 'issue-581' into event_observer
robrobert99 Jul 29, 2021
e809790
Add Observer
robrobert99 Aug 2, 2021
51bbf1e
Merge branch 'develop' into event_observer
robrobert99 Aug 3, 2021
2e33f7c
Add KubernetesObserver
robrobert99 Aug 6, 2021
0606c90
change how observer factory creates observers (file/url based on as f…
Aug 6, 2021
6749412
Merge pull request #636 from dedica-team/event_observer_creation_change
robrobert99 Aug 6, 2021
7949a5c
Improve KubernetesObserver
robrobert99 Aug 10, 2021
83d6906
Change observer
robrobert99 Aug 11, 2021
05b82ec
Merge branch 'develop' into event_observer
robrobert99 Aug 11, 2021
adc455e
Improve observer
robrobert99 Aug 13, 2021
80d0274
Merge branch 'develop' into event_observer
robrobert99 Aug 13, 2021
5a2c600
Observer triggers refresh until all Items are GREEN
robrobert99 Aug 13, 2021
e289b69
Merge branch 'groups_without_item_copies' into event_observer
robrobert99 Oct 5, 2021
e4fe7be
Use hash value of k8s objects as checksum to detect changes
robrobert99 Oct 6, 2021
13e4068
Merge branch 'develop' into event_observer
robrobert99 Oct 6, 2021
4e584ab
Use hash value of k8s objects as checksum to detect changes
robrobert99 Oct 6, 2021
27c1b8e
Merge branch 'develop' into event_observer
robrobert99 Oct 6, 2021
17fbd94
Add a way to configure the delay on a per observer basis.
robrobert99 Oct 7, 2021
c7e949b
Merge branch 'develop' into event_observer
robrobert99 Oct 7, 2021
6717bff
Changed DEMO back to pet clinic
robrobert99 Oct 7, 2021
225c971
Observer config is now in application.yml and KubernetesObserver uses…
robrobert99 Oct 10, 2021
c166c6d
Fix typo in application.yml
robrobert99 Oct 10, 2021
2ee4ee9
Removed observerDelayConfig.json and change type of HashSet to HasMet…
robrobert99 Oct 11, 2021
16f522e
Improve tests, add Comment, add @Nonnull annotation
robrobert99 Oct 11, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/schema/.openapi-generator/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.2.0
5.2.1
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
public class KubernetesKPI implements KPI {
private static final Logger LOGGER = LoggerFactory.getLogger(KubernetesKPI.class);
public static final String IDENTIFIER = "k8s";

private boolean enabled = true;

@Override
Expand All @@ -27,7 +26,6 @@ public List<StatusValue> getStatusValues(Assessable assessable) {
if (!(assessable instanceof Labeled)) {
return new ArrayList<>();
}

var statusList = new ArrayList<StatusValue>();
var counter = new AtomicInteger(0);
((Labeled) assessable).getLabels(InputFormatHandlerKubernetes.LABEL_PREFIX).forEach((key, value) -> {
Expand Down Expand Up @@ -99,12 +97,12 @@ public boolean isEnabled() {

@Override
public Map<Status, RangeApiModel> getRanges() {
return null;
return Map.of();
}

@Override
public Map<Status, List<String>> getMatches() {
return null;
return Map.of();
}

public void setEnabled(boolean enabled) {
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/de/bonndan/nivio/input/IndexingDispatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import de.bonndan.nivio.input.dto.LandscapeDescription;
import de.bonndan.nivio.model.Landscape;
import de.bonndan.nivio.util.URLHelper;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -55,7 +54,6 @@ public LandscapeDescription fromIncoming(@NonNull final Landscape existing) {
LandscapeDescription dto = existing.getSource().getURL()
.map(landscapeDescriptionFactory::from)
.orElseGet(() -> landscapeDescriptionFactory.fromString(existing.getSource().getStaticSource(), existing.getIdentifier() + " source"));

IndexEvent event = new IndexEvent(dto, "index landscape");
publisher.publishEvent(event);
return dto;
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/de/bonndan/nivio/input/InputFormatHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import de.bonndan.nivio.input.dto.LandscapeDescription;
import de.bonndan.nivio.input.dto.SourceReference;
import de.bonndan.nivio.model.Landscape;
import de.bonndan.nivio.observation.InputFormatObserver;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

Expand Down Expand Up @@ -33,11 +35,17 @@ public interface InputFormatHandler {
/**
* Returns an observer for the source reference.
*
* @param inner an observer for files or urls
* @param eventPublisher the event publisher to notify
* @param landscape the current landscape
* @param sourceReference the {@link SourceReference} to observe
* @return observer that can handle the format or null if no observer is available
*/
@Nullable
InputFormatObserver getObserver(@NonNull final InputFormatObserver inner, @NonNull final SourceReference sourceReference);
default InputFormatObserver getObserver(@NonNull final ApplicationEventPublisher eventPublisher,
@NonNull final Landscape landscape,
@NonNull final SourceReference sourceReference
) {
return null;
}

}
6 changes: 4 additions & 2 deletions src/main/java/de/bonndan/nivio/input/Seed.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.bonndan.nivio.input;

import de.bonndan.nivio.config.ConfigurableEnvVars;
import de.bonndan.nivio.util.URLHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -67,12 +68,13 @@ public List<URL> getDemoFiles() {
if (!StringUtils.hasLength(demo)) {
return demoFiles;
}
String value = ConfigurableEnvVars.DEMO.value().orElse("");

Path currentRelativePath = Paths.get("");
String absPath = currentRelativePath.toAbsolutePath().toString();
try {
demoFiles.add(new File(absPath + "/src/test/resources/example/pet_clinic.yml").toURI().toURL());
if (demo.equalsIgnoreCase("all")) {
demoFiles.add(new File(absPath + "/src/test/resources/example/example_k8s.yml").toURI().toURL());
if (value.equalsIgnoreCase("all")) {
demoFiles.add(new File(absPath + "/src/test/resources/example/inout.yml").toURI().toURL());
demoFiles.add(new File(absPath + "/src/test/resources/example/internals.yml").toURI().toURL());
demoFiles.add(new File(absPath + "/src/test/resources/example/dedica_dot.yml").toURI().toURL());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
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.observation.InputFormatObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;
Expand All @@ -25,7 +24,7 @@
@Service
public class InputFormatHandlerCompose2 implements InputFormatHandler {

private static final Logger logger = LoggerFactory.getLogger(InputFormatHandler.class);
private static final Logger logger = LoggerFactory.getLogger(InputFormatHandlerCompose2.class);
private static final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());

static {
Expand Down Expand Up @@ -61,7 +60,7 @@ public void applyData(@NonNull SourceReference reference, URL baseUrl, Landscape
logger.error("Failed to read yml", e);
}
if (source == null) {
logger.warn("Got null out of yml string " + yml);
logger.warn("Got null out of yml string {}", yml);
return;
}

Expand All @@ -72,10 +71,4 @@ public void applyData(@NonNull SourceReference reference, URL baseUrl, Landscape

landscapeDescription.mergeItems(itemDescriptions);
}

@Override
public InputFormatObserver getObserver(@NonNull InputFormatObserver inner, @NonNull SourceReference sourceReference) {
return inner;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
import de.bonndan.nivio.input.dto.RelationDescription;
import de.bonndan.nivio.input.dto.SourceReference;
import de.bonndan.nivio.model.Relation;
import de.bonndan.nivio.observation.InputFormatObserver;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import java.io.StringReader;
Expand Down Expand Up @@ -100,12 +98,6 @@ public void applyData(@NonNull SourceReference reference, URL baseUrl, Landscape
landscapeDescription.mergeItems(itemDescriptions);
}

@Override
@Nullable
public InputFormatObserver getObserver(@NonNull InputFormatObserver inner, @NonNull SourceReference sourceReference) {
return inner;
}

private CSVReader getReader(SourceReference reference, String content) {
String separator = (String) Optional.ofNullable(reference.getProperty("separator")).orElse(";");
int skipLines = (int) Optional.ofNullable(reference.getProperty("skipLines")).orElse(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@
import de.bonndan.nivio.input.dto.RelationDescription;
import de.bonndan.nivio.input.dto.SourceReference;
import de.bonndan.nivio.model.RelationType;
import de.bonndan.nivio.observation.InputFormatObserver;
import guru.nidi.graphviz.model.MutableGraph;
import guru.nidi.graphviz.parse.Parser;
import guru.nidi.graphviz.parse.ParserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import java.io.IOException;
Expand Down Expand Up @@ -97,11 +95,4 @@ public void applyData(@NonNull SourceReference reference, URL baseUrl, Landscape
}
landscapeDescription.mergeItems(itemDescriptions);
}

@Override
@Nullable
public InputFormatObserver getObserver(@NonNull final InputFormatObserver inner, @NonNull final SourceReference sourceReference) {
return inner;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import de.bonndan.nivio.input.kubernetes.itemadapters.PersistentVolumeItemAdapter;
import de.bonndan.nivio.input.kubernetes.itemadapters.PodItemAdapter;
import de.bonndan.nivio.model.Label;
import de.bonndan.nivio.model.Landscape;
import de.bonndan.nivio.observation.InputFormatObserver;
import io.fabric8.kubernetes.api.model.OwnerReference;
import io.fabric8.kubernetes.client.Config;
Expand All @@ -17,6 +18,7 @@
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.lang.NonNull;

import java.net.URL;
Expand Down Expand Up @@ -54,7 +56,6 @@ public List<String> getFormats() {
*/
@Override
public void applyData(@NonNull SourceReference reference, URL baseUrl, LandscapeDescription landscapeDescription) {

this.client = getClient(reference.getUrl());

try {
Expand Down Expand Up @@ -132,7 +133,7 @@ private void crossReferenceLabel(ArrayList<K8sItem> itemList) {
itemList.forEach(ownedItem -> {
var ownerList = itemList.stream().filter(
ownerItem -> CollectionUtils.intersection(Objects.requireNonNullElse(ownedItem.getItemAdapter().getLabels(), new HashMap<String, String>()).values(),
Objects.requireNonNullElse(ownerItem.getItemAdapter().getLabels(), new HashMap<String, String>()).values())
Objects.requireNonNullElse(ownerItem.getItemAdapter().getLabels(), new HashMap<String, String>()).values())
.size() >= K8sJsonParser.getMinMatchingLevel() && ownerItem.getLevelDecorator().getLevel() != -1 && ownedItem.getLevelDecorator().getLevel() != -1 &&
(ownerItem.getLevelDecorator().getLevel() - ownedItem.getLevelDecorator().getLevel()) == 1).collect(Collectors.toList());
ownerList.forEach(ownedItem::addOwner);
Expand Down Expand Up @@ -170,8 +171,8 @@ private void crossReferenceService(List<K8sItem> service, List<K8sItem> owners)
}

@Override
public InputFormatObserver getObserver(@NonNull final InputFormatObserver inner, @NonNull final SourceReference sourceReference) {
return null;
public InputFormatObserver getObserver(@NonNull final ApplicationEventPublisher eventPublisher, @NonNull final Landscape landscape, @NonNull final SourceReference sourceReference) {
return new KubernetesObserver(landscape, eventPublisher, this.client);
}

private KubernetesClient getClient(String context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package de.bonndan.nivio.input.kubernetes;


import de.bonndan.nivio.model.Landscape;
import de.bonndan.nivio.observation.InputChangedEvent;
import de.bonndan.nivio.observation.InputFormatObserver;
import de.bonndan.nivio.observation.ObservedChange;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.lang.NonNull;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


public class KubernetesObserver implements InputFormatObserver {

private static final Logger LOGGER = LoggerFactory.getLogger(KubernetesObserver.class);

private final Landscape landscape;
private final ApplicationEventPublisher eventPublisher;
private final KubernetesClient kubernetesClient;
private final List<Long> eventUidList;

public KubernetesObserver(@NonNull final Landscape landscape,
@NonNull final ApplicationEventPublisher eventPublisher,
@NonNull final KubernetesClient kubernetesClient) {
this.landscape = landscape;
this.kubernetesClient = kubernetesClient;
this.eventPublisher = eventPublisher;
this.eventUidList = getK8sComponents();
}

@Override
public void run() {
var change = false;
while (!change) {
sleep(1000);
if ((eventUidList.stream().mapToLong(Long::longValue).sum() - getK8sComponents().stream().mapToLong(Long::longValue).sum()) != 0) {
change = true;
LOGGER.info("K8s change detected");
eventPublisher.publishEvent(new InputChangedEvent(new ObservedChange(landscape, "k8s cluster changed")));
}
}

}

@NonNull
private List<Long> getK8sComponents() {
try {
var componentList = kubernetesClient.apps().deployments().list().getItems().stream().map(deployment -> (long) deployment.hashCode()).collect(Collectors.toList());
componentList.addAll(kubernetesClient.persistentVolumeClaims().list().getItems().stream().map(persistentVolumeClaim -> (long) persistentVolumeClaim.hashCode()).collect(Collectors.toList()));
componentList.addAll(kubernetesClient.persistentVolumes().list().getItems().stream().map(persistentVolume -> (long) persistentVolume.hashCode()).collect(Collectors.toList()));
componentList.addAll(kubernetesClient.pods().list().getItems().stream().map(pod -> (long) pod.hashCode()).collect(Collectors.toList()));
componentList.addAll(kubernetesClient.apps().replicaSets().list().getItems().stream().map(replicaSet -> (long) replicaSet.hashCode()).collect(Collectors.toList()));
componentList.addAll(kubernetesClient.services().list().getItems().stream().map(service -> (long) service.hashCode()).collect(Collectors.toList()));
componentList.addAll(kubernetesClient.apps().statefulSets().list().getItems().stream().map(statefulSet -> (long) statefulSet.hashCode()).collect(Collectors.toList()));
return componentList;
} catch (KubernetesClientException n) {
LOGGER.error(n.getMessage());
LOGGER.error("Kubernetes might not be available");
}
return new ArrayList<>();
}

private void sleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import de.bonndan.nivio.input.FileFetcher;
import de.bonndan.nivio.input.InputFormatHandler;
import de.bonndan.nivio.input.Mappers;
import de.bonndan.nivio.input.ReadingException;
import de.bonndan.nivio.input.dto.ItemDescription;
import de.bonndan.nivio.input.dto.LandscapeDescription;
import de.bonndan.nivio.input.dto.SourceReference;
import de.bonndan.nivio.observation.InputFormatObserver;
import de.bonndan.nivio.input.Mappers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
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;

Expand All @@ -44,7 +40,6 @@ public List<String> getFormats() {
@Override
public void applyData(@NonNull SourceReference reference, URL baseUrl, LandscapeDescription description) {

List<ItemDescription> descriptions = new ArrayList<>();
String yml = fileFetcher.get(reference, baseUrl);
Source source;
try {
Expand All @@ -55,7 +50,7 @@ public void applyData(@NonNull SourceReference reference, URL baseUrl, Landscape
}

if (source == null) {
logger.warn("Got null out of yml string " + yml);
logger.warn("Got null out of yml string {}", yml);
return;
}

Expand All @@ -67,10 +62,4 @@ public void applyData(@NonNull SourceReference reference, URL baseUrl, Landscape
}

}

@Override
@Nullable
public InputFormatObserver getObserver(@NonNull InputFormatObserver inner, @NonNull SourceReference sourceReference) {
return inner;
}
}
Loading