Skip to content

Commit

Permalink
Add scenario resource
Browse files Browse the repository at this point in the history
  • Loading branch information
cmendesce committed Dec 5, 2023
1 parent ed92eba commit b91d978
Show file tree
Hide file tree
Showing 24 changed files with 510 additions and 145 deletions.
93 changes: 41 additions & 52 deletions sample.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: "resiliencebench.io/v1"
apiVersion: "resiliencebench.io/v1beta1"
kind: Workload
metadata:
name: stress-test
Expand All @@ -13,7 +13,7 @@ spec:

---

apiVersion: "resiliencebench.io/v1"
apiVersion: "resiliencebench.io/v1beta1"
kind: ResilientService
metadata:
name: api-gateway
Expand All @@ -24,7 +24,7 @@ spec:
matchLabels:
com.petclinic.service: api-gateway
---
apiVersion: "resiliencebench.io/v1"
apiVersion: "resiliencebench.io/v1beta1"
kind: ResilientService
metadata:
name: vets-service
Expand All @@ -35,7 +35,7 @@ spec:
matchLabels:
com.petclinic.service: vets-service
---
apiVersion: "resiliencebench.io/v1"
apiVersion: "resiliencebench.io/v1beta1"
kind: ResilientService
metadata:
name: visits-service
Expand All @@ -46,7 +46,7 @@ spec:
matchLabels:
com.petclinic.service: visits-service
---
apiVersion: "resiliencebench.io/v1"
apiVersion: "resiliencebench.io/v1beta1"
kind: ResilientService
metadata:
name: customers-service
Expand All @@ -59,52 +59,41 @@ spec:

---

apiVersion: "resiliencebench.io/v1"
kind: Workload
apiVersion: resiliencebench.io/v1beta1
kind: Benchmark
metadata:
name: ten-users-linear-load
name: example-benchmark
namespace: default
spec:
users: [ 10 ]
duration: 30
targetUrl: "http://server:9211/bytes/1000"
locustFileConfigMap: "locustfile.py"
#
#---
#
#apiVersion: "resiliencebench.io/v1"
#kind: Benchmark
#metadata:
# name: bm-1
#spec:
# rounds: 10
# workload: ten-users-linear-load
#
# scenarios:
# - name: all-services-with-retry
# connections:
# - name: aresta-1
# source:
# service: api-gateway
# patternConfig:
# maxAttempts: 6
# multiplier: 1.5
# initialIntervalMillis: [ 50 ]
# target:
# service: customer-services
# fault:
# delay:
# percentage: [ 50, 75 ]
# duration: 100
# - name: aresta-2
# source:
# service: api-gateway
# patternConfig:
# maxAttempts: 6
# multiplier: 1.5
# initialIntervalMillis: [ 50 ]
# target:
# service: vets-services
# fault:
# delay:
# percentage: [ 50, 75 ]
# duration: 100
connections:
- name: connection-1
source:
patternConfig:
patternKey1: value1
patternKey2: value2
service: api-gateway
target:
service: vets-service
fault:
percentage:
- 10
- 20
delay:
duration: 100

- name: connection-2
source:
patternConfig:
patternKey3: value3
patternKey4: value4
service: api-gateway
target:
service: visits-service
fault:
percentage:
- 10
abort:
httpStatus: 503

rounds: 5
workload: stress-test
Original file line number Diff line number Diff line change
@@ -1,19 +1,46 @@
package br.unifor.ppgia.resiliencebench;

import br.unifor.ppgia.resiliencebench.resources.CustomResourceRepository;
import br.unifor.ppgia.resiliencebench.resources.ScenarioFactory;
import br.unifor.ppgia.resiliencebench.resources.benchmark.Benchmark;
import br.unifor.ppgia.resiliencebench.resources.scenario.Scenario;
import br.unifor.ppgia.resiliencebench.resources.workload.Workload;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;

import java.util.Map;

import static java.util.Map.*;

@ControllerConfiguration
public class BenchmarkReconciler implements Reconciler<Benchmark> {

@Override
public UpdateControl<Benchmark> reconcile(Benchmark benchmark, Context<Benchmark> context) {
var scenarioRepository = new CustomResourceRepository<>(context.getClient(), Scenario.class);

var workload = context.getClient().resources(Workload.class).inNamespace(benchmark.getMetadata().getNamespace()).withName(benchmark.getSpec().getWorkload()).get();
var scenariosList = ScenarioFactory.create(benchmark, workload);

for (var scenario : scenariosList) {
var meta = new ObjectMeta();
meta.setName(scenario.toString());
meta.setNamespace(benchmark.getMetadata().getNamespace());
meta.setAnnotations(of("resiliencebench.io/owned-by", benchmark.getMetadata().getName()));
scenario.setMetadata(meta);
var foundScenario = scenarioRepository.get(meta);
if (foundScenario != null) {
scenarioRepository.update(scenario);
} else {
scenarioRepository.create(scenario);
}

}

// var scenariosList = ScenarioFactory.create(benchmark);
// var status = new BenchmarkStatus(scenariosList.size());
// benchmark.setStatus(status);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package br.unifor.ppgia.resiliencebench.resources;

import io.fabric8.kubernetes.api.model.KubernetesResourceList;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.dsl.MixedOperation;
import io.fabric8.kubernetes.client.dsl.NonNamespaceOperation;
import io.fabric8.kubernetes.client.dsl.Replaceable;
import io.fabric8.kubernetes.client.dsl.Resource;

import java.util.List;

public class CustomResourceRepository<T extends CustomResource> {

private final KubernetesClient kubernetesClient;
private final Class<T> resourceClass;
private final MixedOperation<T, KubernetesResourceList<T>, Resource<T>> resources;

@SuppressWarnings("unchecked")
public CustomResourceRepository(KubernetesClient kubernetesClient, Class<T> resourceClass) {
this.kubernetesClient = kubernetesClient;
this.resourceClass = resourceClass;
this.resources = kubernetesClient.resources(resourceClass);
}

private NonNamespaceOperation<T, KubernetesResourceList<T>, Resource<T>> inNamespace(T resource) {
return this.resources.inNamespace(resource.getMetadata().getNamespace());
}

public T create(T resource) {
return inNamespace(resource).resource(resource).create();
}

public T update(T resource) {
return inNamespace(resource).resource(resource).createOr(Replaceable::update);
}

public void delete(T resource) {
inNamespace(resource).resource(resource).delete();
}

public T get(ObjectMeta meta) {
return this.resources.inNamespace(meta.getNamespace()).withName(meta.getName()).get();
}

public List<T> list(String namespace) {
return this.resources.inNamespace(namespace).list().getItems();
}

// public boolean exists(ObjectMeta metadata) {
// return this.get(metadata) != null;
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
import br.unifor.ppgia.resiliencebench.resources.workload.Workload;
import com.fasterxml.jackson.databind.JsonNode;

import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static br.unifor.ppgia.resiliencebench.resources.ListExpansion.expandConfigTemplate;
import static java.util.Collections.*;
import static java.util.stream.Collectors.*;

public final class ScenarioFactory {
private static Map<String, Object> convertJsonNodeToMap(JsonNode jsonNode) {
Expand Down Expand Up @@ -50,8 +51,9 @@ public static Object convertJsonNode(JsonNode jsonNode) {
return jsonNode;
}

static List<Map<String, Object>> expandServices(Source serviceSource) {
var patternConfigTemplate = convertJsonNodeToMap(serviceSource.getPatternConfig().get("patternConfig"));
public static List<Map<String, Object>> expandServiceParameters(Source serviceSource) {
var patternConfigTemplate =
convertJsonNodeToMap(serviceSource.getPatternConfig().get("patternConfig"));
return expandConfigTemplate(patternConfigTemplate);
}

Expand All @@ -65,27 +67,34 @@ public static List<Scenario> create(Benchmark benchmark, Workload workload) {
var source = connection.getSource();

for (var faultPercentage : target.getFault().getPercentage()) {
var fault = new ScenarioFaultTemplate(faultPercentage, target.getFault().getDelay(),
target.getFault().getAbort());
var fault =
ScenarioFaultTemplate.from(faultPercentage, target.getFault().getDelay(), target.getFault().getAbort());

for (var sourcePatternsParameters : expandServices(source)) {
for (var sourcePatternsParameters : expandServiceParameters(source)) {
for (var workloadUser : workloadUsers) {
scenarios.add(createScenario(workloadName, target, source, fault, sourcePatternsParameters, workloadUser));
}
}
}
}
return scenarios.stream().flatMap(obj -> nCopies(benchmark.getSpec().getRounds(), obj).stream()).collect(toList());
return scenarios;
}

private static Scenario createScenario(String workloadName, Target target, Source source, ScenarioFaultTemplate fault, Map<String, Object> sourcePatternsParameters, Integer workloadUser) {
private static Scenario createScenario(
String workloadName,
Target target,
Source source,
ScenarioFaultTemplate fault,
Map<String, Object> sourcePatternsParameters, Integer workloadUser
) {
return new Scenario(
new ScenarioSpec(
target.getService(),
source.getService(),
sourcePatternsParameters,
new ScenarioWorkload(workloadName, workloadUser),
fault)
fault
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@

import java.util.List;

import br.unifor.ppgia.resiliencebench.resources.fault.AbortFault;
import br.unifor.ppgia.resiliencebench.resources.fault.DelayFault;
import br.unifor.ppgia.resiliencebench.resources.fault.FaultTemplate;

public class BenchmarkFaultTemplate extends FaultTemplate<List<Integer>> {


public BenchmarkFaultTemplate() {
}

public BenchmarkFaultTemplate(List<Integer> percentage, DelayFault delay) {
super(percentage, delay);
}

public BenchmarkFaultTemplate(List<Integer> percentage, AbortFault abort) {
super(percentage, abort);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ public class BenchmarkSpec {
private String workload;
private List<Connection> connections = new ArrayList<>();

public BenchmarkSpec() {
}

public BenchmarkSpec(int rounds, String workload, List<Connection> connections) {
this();
this.rounds = rounds;
this.workload = workload;
this.connections = connections;
}

public int getRounds() {
return rounds;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ public class Connection {
private Source source;
private Target target;

public Connection() {
}

public Connection(String name, Source source, Target target) {
this.name = name;
this.source = source;
this.target = target;
}

public String getName() {
return name;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ public class Source {
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, JsonNode> patternConfig = new LinkedHashMap<>();

public Source() { }

public Source(String service, Map<String, JsonNode> patternConfig) {
this.service = service;
this.patternConfig = patternConfig;
}

public String getService() {
return service;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ public class Target {
private String service;
private BenchmarkFaultTemplate fault;

public Target() {
}

public Target(String service, BenchmarkFaultTemplate fault) {
this.service = service;
this.fault = fault;
}

public BenchmarkFaultTemplate getFault() {
return fault;
}
Expand Down
Loading

0 comments on commit b91d978

Please sign in to comment.