Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New CRD model #6

Merged
merged 11 commits into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package br.unifor.ppgia.resiliencebench.resources;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand All @@ -9,46 +12,57 @@ public final class ListExpansion {
public ListExpansion() {
throw new IllegalStateException("Utility class");
}
public static List<Map<String, Object>> generateConfig(Map<String, Object> configTemplate, List<Map.Entry<String, List<Object>>> keyExpansionList) {
List<Map<String, Object>> configList = new ArrayList<>();

if (!keyExpansionList.isEmpty()) {
Map.Entry<String, List<Object>> entry = keyExpansionList.get(0);
String key = entry.getKey();
List<Object> valList = entry.getValue();

if (configTemplate.containsKey(key)) {
for (Object val : valList) {
Map<String, Object> config = new HashMap<>(configTemplate);
config.put(key, val);
if (keyExpansionList.size() > 1) {
configList.addAll(generateConfig(config, keyExpansionList.subList(1, keyExpansionList.size())));
} else {
configList.add(config);
}

public static List<Map<String, Object>> expandConfigTemplate(PatternConfig patternConfigs) {
List<Map<String, Object>> resultList = new ArrayList<>();
resultList.add(new HashMap<>());

for (var config : patternConfigs) {
String key = config.getName();
JsonNode value = config.getValue();

if (value.isArray()) {
ArrayNode arrayNode = (ArrayNode) value;
resultList = multiplyList(resultList, key, arrayNode);
} else {
for (Map<String, Object> map : resultList) {
map.put(key, jsonNodeToObject(value));
}
}
}

return configList;
return resultList;
}

public static List<Map<String, Object>> expandConfigTemplate(Map<String, Object> configTemplate) {
List<Map.Entry<String, List<Object>>> keyExpansionList = new ArrayList<>();
private static List<Map<String, Object>> multiplyList(List<Map<String, Object>> currentList, String key, ArrayNode valueArray) {
List<Map<String, Object>> newList = new ArrayList<>();

for (Map.Entry<String, Object> entry : configTemplate.entrySet()) {
if (entry.getValue() instanceof List) {
List<Object> valList = (List<Object>) entry.getValue();
keyExpansionList.add(Map.entry(entry.getKey(), valList));
for (Map<String, Object> existingMap : currentList) {
for (JsonNode arrayItem : valueArray) {
Map<String, Object> newMap = new HashMap<>(existingMap);
newMap.put(key, jsonNodeToObject(arrayItem));
newList.add(newMap);
}
}

if (!keyExpansionList.isEmpty()) {
return generateConfig(configTemplate, keyExpansionList);
return newList;
}

private static Object jsonNodeToObject(JsonNode jsonNode) {
if (jsonNode.isTextual()) {
return jsonNode.asText();
} else if (jsonNode.isNumber()) {
if (jsonNode.isDouble() || jsonNode.isFloatingPointNumber()) {
return jsonNode.doubleValue();
} else if (jsonNode.isLong()) {
return jsonNode.longValue();
} else {
return jsonNode.intValue();
}
} else if (jsonNode.isBoolean()) {
return jsonNode.asBoolean();
} else {
List<Map<String, Object>> configList = new ArrayList<>();
configList.add(configTemplate);
return configList;
return jsonNode;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package br.unifor.ppgia.resiliencebench.resources;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.Arrays;

import static io.vertx.core.impl.ConversionHelper.toObject;
import static java.util.stream.Collectors.joining;

public class PatternConfig extends ArrayList<PatternConfig.Attribute> {
public PatternConfig() {
}

public PatternConfig(Attribute... params) {
this.addAll(Arrays.asList(params));
}

@Override
public String toString() {
var serialized = this.stream()
.map(Attribute::toString)
.collect(joining("."));
if (serialized.isEmpty()) {
serialized = "none";
}
return serialized;
}

public static class Attribute {
@JsonIgnore
private static final ObjectMapper mapper = new ObjectMapper();

private String name;
private JsonNode value;

public Attribute() {
}

public Attribute(String name, JsonNode value) {
this.name = name;
this.value = value;
}

public Attribute(String name, Object value) {
this(name, mapper.valueToTree(value));
}

public String getName() {
return name;
}

public JsonNode getValue() {
return value;
}

@JsonIgnore
public Object getValueAsObject() {
if (getValue().isTextual()) {
return getValue().asText();
} else if (getValue().isNumber()) {
if (getValue().isDouble() || getValue().isFloatingPointNumber()) {
return getValue().doubleValue();
} else if (getValue().isLong()) {
return getValue().longValue();
} else {
return getValue().intValue();
}
} else if (getValue().isBoolean()) {
return getValue().asBoolean();
} else if (getValue().isArray()) {
var list = new ArrayList<>();
getValue().elements().forEachRemaining(element -> list.add(toObject(element)));
return list;
} else {
return getValue();
}
}

@Override
public String toString() {
return getName() + "-" + getValueAsObject();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
package br.unifor.ppgia.resiliencebench.resources.benchmark;

import com.fasterxml.jackson.annotation.JsonIgnore;
import br.unifor.ppgia.resiliencebench.resources.PatternConfig;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class Source {

@JsonIgnore
private static final ObjectMapper mapper = new ObjectMapper();

private String service;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, JsonNode> patternConfig = new LinkedHashMap<>();
@JsonIgnore
private Map<String, Object> internalPatternConfig = new LinkedHashMap<>();

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private PatternConfig patternConfig = new PatternConfig();

public Source() { }

public Source(String service, Map<String, JsonNode> patternConfig) {
public Source(String service, PatternConfig patternConfig) {
this.service = service;
this.patternConfig = patternConfig;
}
Expand All @@ -34,49 +22,11 @@ public String getService() {
}


public void addToPatternConfig(String name, Object value) {
internalPatternConfig.put(name, mapper.valueToTree(value));
patternConfig.put("patternConfig", mapper.valueToTree(internalPatternConfig));
}

/**
* Returns a copy of the given expanded patternConfig
*/
public Map<String, Object> getPatternConfig() {
return toObjectMap(patternConfig.get("patternConfig"));
}

private static Map<String, Object> toObjectMap(JsonNode jsonNode) {
Map<String, Object> resultMap = new LinkedHashMap<>();
if (jsonNode != null && jsonNode.isObject()) {
jsonNode.fields().forEachRemaining(entry -> resultMap.put(entry.getKey(), toObject(entry.getValue())));
}
return resultMap;
public PatternConfig getPatternConfig() {
return patternConfig;
}

private static Object toObject(JsonNode jsonNode) {
if (jsonNode.isObject()) {
return toObjectMap(jsonNode);
} else if (jsonNode.isArray()) {
List<Object> list = new ArrayList<>();
jsonNode.elements().forEachRemaining(element -> list.add(toObject(element)));
return list;
} else if (jsonNode.isTextual()) {
return jsonNode.textValue();
} else if (jsonNode.isBoolean()) {
return jsonNode.booleanValue();
} else if (jsonNode.isNumber()) {
if (jsonNode.isDouble() || jsonNode.isFloatingPointNumber()) {
return jsonNode.doubleValue();
} else if (jsonNode.isInt()) {
return jsonNode.intValue();
} else {
return jsonNode.longValue();
}
} else if (jsonNode.isNull()) {
return null;
}

return jsonNode;
public void setPatternConfig(PatternConfig patternConfig) {
this.patternConfig = patternConfig;
}
}
Original file line number Diff line number Diff line change
@@ -1,42 +1,61 @@
package br.unifor.ppgia.resiliencebench.resources;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

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

public class ListExpansionTest {

private static final ObjectMapper objectMapper = new ObjectMapper();

@Test
public void should_expand_template() {
Map<String, Object> configTemplate = new HashMap<>();
configTemplate.put("slowCallRateThreshold", "100");
configTemplate.put("slowCallDurationThreshold", "1000");
configTemplate.put("waitDurationInOpenState", List.of("50", "100", "200"));
public void should_expand_template_as_patternConfig() {
PatternConfig configTemplate = new PatternConfig();

configTemplate.add(new PatternConfig.Attribute("slowCallRateThreshold", objectMapper.valueToTree(100)));
configTemplate.add(new PatternConfig.Attribute("slowCallDurationThreshold", objectMapper.valueToTree(1000)));
configTemplate.add(new PatternConfig.Attribute("waitDurationInOpenState", objectMapper.valueToTree(List.of(50, 100, 200))));

var expandedConfigs = ListExpansion.expandConfigTemplate(configTemplate);

Assertions.assertEquals(3, expandedConfigs.size());
Assertions.assertEquals(expandedConfigs.get(0).get("waitDurationInOpenState"), "50");
Assertions.assertEquals(expandedConfigs.get(1).get("waitDurationInOpenState"), "100");
Assertions.assertEquals(expandedConfigs.get(2).get("waitDurationInOpenState"), "200");
Assertions.assertEquals(expandedConfigs.get(0).get("waitDurationInOpenState"), 50);
Assertions.assertEquals(expandedConfigs.get(1).get("waitDurationInOpenState"), 100);
Assertions.assertEquals(expandedConfigs.get(2).get("waitDurationInOpenState"), 200);
}

@Test
public void should_expand_simple_template_as_patternConfig() {
PatternConfig configTemplate = new PatternConfig();

configTemplate.add(new PatternConfig.Attribute("slowCallRateThreshold",100));
configTemplate.add(new PatternConfig.Attribute("slowCallDurationThreshold",1000));
configTemplate.add(new PatternConfig.Attribute("waitDurationInOpenState", 200));

var expandedConfigs = ListExpansion.expandConfigTemplate(configTemplate);

Assertions.assertEquals(1, expandedConfigs.size());
Assertions.assertEquals(expandedConfigs.get(0).get("slowCallRateThreshold"), 100);
Assertions.assertEquals(expandedConfigs.get(0).get("slowCallDurationThreshold"), 1000);
Assertions.assertEquals(expandedConfigs.get(0).get("waitDurationInOpenState"), 200);
}

@Test
public void should_expand_multiple_templates() {
Map<String, Object> configTemplate = new HashMap<>();
configTemplate.put("slowCallRateThreshold", "100");
configTemplate.put("slowCallDurationThreshold", List.of("1000", "2000"));
configTemplate.put("waitDurationInOpenState", List.of("50", "100", "200"));
public void should_expand_multiple_templates_as_patternConfig() {
PatternConfig configTemplate = new PatternConfig();
configTemplate.add(new PatternConfig.Attribute("slowCallRateThreshold", 100));
configTemplate.add(new PatternConfig.Attribute("slowCallDurationThreshold", List.of(1000, 2000)));
configTemplate.add(new PatternConfig.Attribute("waitDurationInOpenState", List.of(50, 100, 200)));
var expandedConfigs = ListExpansion.expandConfigTemplate(configTemplate);

Assertions.assertEquals(6, expandedConfigs.size());
Assertions.assertEquals(expandedConfigs.get(0).get("waitDurationInOpenState"), "50");
Assertions.assertEquals(expandedConfigs.get(0).get("slowCallDurationThreshold"), "1000");
Assertions.assertEquals(expandedConfigs.get(1).get("waitDurationInOpenState"), "100");
Assertions.assertEquals(expandedConfigs.get(1).get("slowCallDurationThreshold"), "1000");
Assertions.assertEquals(expandedConfigs.get(0).get("waitDurationInOpenState"), 50);
Assertions.assertEquals(expandedConfigs.get(0).get("slowCallDurationThreshold"), 1000);
Assertions.assertEquals(expandedConfigs.get(1).get("waitDurationInOpenState"), 100);
Assertions.assertEquals(expandedConfigs.get(1).get("slowCallDurationThreshold"), 1000);
}
}

Loading