mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
new decorator API: share Scenario metadata to interested types
This commit is contained in:
parent
bbeee5cb1a
commit
8c6d0cfe57
@ -5,7 +5,7 @@ import io.nosqlbench.engine.clients.grafana.GStitcher;
|
||||
import io.nosqlbench.engine.clients.grafana.GrafanaClient;
|
||||
import io.nosqlbench.engine.clients.grafana.GrafanaClientConfig;
|
||||
import io.nosqlbench.engine.clients.grafana.transfer.*;
|
||||
import io.nosqlbench.nb.api.SystemId;
|
||||
import io.nosqlbench.nb.api.metadata.SystemId;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
|
@ -6,7 +6,7 @@ import io.nosqlbench.engine.clients.grafana.transfer.GAnnotation;
|
||||
import io.nosqlbench.nb.annotations.Service;
|
||||
import io.nosqlbench.nb.api.NBEnvironment;
|
||||
import io.nosqlbench.nb.api.OnError;
|
||||
import io.nosqlbench.nb.api.SystemId;
|
||||
import io.nosqlbench.nb.api.metadata.SystemId;
|
||||
import io.nosqlbench.nb.api.annotations.Annotation;
|
||||
import io.nosqlbench.nb.api.annotations.Annotator;
|
||||
import io.nosqlbench.nb.api.config.*;
|
||||
|
@ -25,6 +25,9 @@ import io.nosqlbench.engine.core.lifecycle.ScenarioController;
|
||||
import io.nosqlbench.engine.core.lifecycle.ScenarioResult;
|
||||
import io.nosqlbench.engine.core.annotation.Annotators;
|
||||
import io.nosqlbench.engine.core.metrics.PolyglotMetricRegistryBindings;
|
||||
import io.nosqlbench.nb.api.metadata.ScenarioMetadata;
|
||||
import io.nosqlbench.nb.api.metadata.ScenarioMetadataAware;
|
||||
import io.nosqlbench.nb.api.metadata.SystemId;
|
||||
import io.nosqlbench.nb.api.annotations.Layer;
|
||||
import io.nosqlbench.nb.api.annotations.Annotation;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@ -46,10 +49,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -63,6 +63,7 @@ public class Scenario implements Callable<ScenarioResult> {
|
||||
private State state = State.Scheduled;
|
||||
private volatile ScenarioShutdownHook scenarioShutdownHook;
|
||||
private Exception error;
|
||||
private ScenarioMetadata scenarioMetadata;
|
||||
|
||||
|
||||
public enum State {
|
||||
@ -236,12 +237,23 @@ public class Scenario implements Callable<ScenarioResult> {
|
||||
metricRegistry,
|
||||
scriptEnv
|
||||
);
|
||||
ScenarioMetadataAware.apply(extensionObject,getScenarioMetadata());
|
||||
logger.trace("Adding extension object: name=" + extensionDescriptor.getBaseVariableName() +
|
||||
" class=" + extensionObject.getClass().getSimpleName());
|
||||
scriptEngine.put(extensionDescriptor.getBaseVariableName(), extensionObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private synchronized ScenarioMetadata getScenarioMetadata() {
|
||||
if (this.scenarioMetadata==null) {
|
||||
this.scenarioMetadata = new ScenarioMetadata(
|
||||
this.startedAtMillis,
|
||||
this.scenarioName,
|
||||
SystemId.getNodeId(),
|
||||
SystemId.getNodeFingerprint()
|
||||
);
|
||||
}
|
||||
return scenarioMetadata;
|
||||
}
|
||||
|
||||
public void runScenario() {
|
||||
|
@ -0,0 +1,47 @@
|
||||
package io.nosqlbench.nb.api.metadata;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* If an object is ScenarioMetadata, then they will be updated with a map of
|
||||
* scenario metadata. Supported types are:
|
||||
* <UL>
|
||||
* <LI>ScriptingPluginInfo</LI>
|
||||
* </UL>
|
||||
*/
|
||||
public class ScenarioMetadata {
|
||||
private final long startedAt;
|
||||
private final String sessionName;
|
||||
private final String systemId;
|
||||
private final String systemFingerprint;
|
||||
|
||||
public ScenarioMetadata(long startedAt, String sessionName, String systemId, String systemFingerprint) {
|
||||
this.startedAt = startedAt;
|
||||
this.sessionName = sessionName;
|
||||
this.systemId = systemId;
|
||||
this.systemFingerprint = systemFingerprint;
|
||||
}
|
||||
|
||||
public long getStartedAt() {
|
||||
return startedAt;
|
||||
}
|
||||
|
||||
public String getSessionName() {
|
||||
return sessionName;
|
||||
}
|
||||
|
||||
public String getSystemId() {
|
||||
return systemId;
|
||||
}
|
||||
|
||||
public String getSystemFingerprint() {
|
||||
return systemFingerprint;
|
||||
}
|
||||
|
||||
public Map<String,String> asMap() {
|
||||
return Map.of("STARTED_AT",String.valueOf(startedAt),
|
||||
"SESSION_NAME",sessionName,
|
||||
"SYSTEM_ID",systemId,
|
||||
"SYSTEM_FINGERPRINT", systemFingerprint);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package io.nosqlbench.nb.api.metadata;
|
||||
|
||||
/**
|
||||
* Where supported, the following named fields are injected into object which
|
||||
* implement this interface:
|
||||
* <UL>
|
||||
* <LI>SCENARIO_NAME - The full scenario name, used for logging, metrics, etc</LI>
|
||||
* <LI>STARTED_AT_MILLIS - The millisecond timestamp used to create the scenario name</LI>
|
||||
* <LI>SYSTEM_ID - A stable identifier based on the available ip addresses</LI></LK>
|
||||
* <LI>SYSTEM_FINGERPRINT - a stable and pseudonymous identifier based on SYSTEM_ID</LI>
|
||||
* </UL>
|
||||
*/
|
||||
public interface ScenarioMetadataAware {
|
||||
void setScenarioMetadata(ScenarioMetadata metadata);
|
||||
|
||||
static void apply(Object target, ScenarioMetadata metadata) {
|
||||
if (target instanceof ScenarioMetadataAware) {
|
||||
((ScenarioMetadataAware)target).setScenarioMetadata(metadata);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package io.nosqlbench.nb.api;
|
||||
package io.nosqlbench.nb.api.metadata;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
@ -7,10 +7,25 @@ import oshi.hardware.CentralProcessor;
|
||||
import oshi.hardware.HardwareAbstractionLayer;
|
||||
import oshi.hardware.NetworkIF;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.*;
|
||||
|
||||
public class SystemId {
|
||||
|
||||
/**
|
||||
* Return the address of a node which is likely to be unique enough to identify
|
||||
* it within a given subnet, after filtering out all local addresses. This is useful
|
||||
* when you are managing configuration or results for a set of systems which
|
||||
* share a common IP addressing scheme. This identifier should be stable as long
|
||||
* as the node's addresses do not change.
|
||||
*
|
||||
* If you are needing an identifier for a node but wish to expose any address data,
|
||||
* you can use the {@link #getNodeFingerprint()} which takes this value and hashes
|
||||
* it with SHA-1 to produce a hex string.
|
||||
* @return A address for the node, likely to be unique and stable for its lifetime
|
||||
*/
|
||||
public static String getNodeId() {
|
||||
SystemInfo sysinfo = new SystemInfo();
|
||||
HardwareAbstractionLayer hal = sysinfo.getHardware();
|
||||
@ -38,6 +53,28 @@ public class SystemId {
|
||||
return systemID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce a stable string identifier consisting of hexadecimal characters.
|
||||
* The internal data used for this value is based on a stable ordering of non-local
|
||||
* ip addresses available on the system.
|
||||
* @return A stable node identifier
|
||||
*/
|
||||
public static String getNodeFingerprint() {
|
||||
String addrId = getNodeId();
|
||||
try {
|
||||
MessageDigest sha1_digest = MessageDigest.getInstance("SHA-1");
|
||||
byte[] addrBytes = sha1_digest.digest(addrId.getBytes(StandardCharsets.UTF_8));
|
||||
String fingerprint = "";
|
||||
for (int i=0; i < addrBytes.length; i++) {
|
||||
fingerprint +=
|
||||
Integer.toString( ( addrBytes[i] & 0xff ) + 0x100, 16).substring( 1 );
|
||||
}
|
||||
return fingerprint.toUpperCase(Locale.ROOT);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getHostSummary() {
|
||||
SystemInfo sysinfo = new SystemInfo();
|
||||
HardwareAbstractionLayer hal = sysinfo.getHardware();
|
@ -1,7 +1,10 @@
|
||||
package io.nosqlbench.nb.api;
|
||||
|
||||
import io.nosqlbench.nb.api.metadata.SystemId;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class SystemIdTest {
|
||||
|
||||
@Test
|
||||
@ -9,4 +12,17 @@ public class SystemIdTest {
|
||||
String info = SystemId.getHostSummary();
|
||||
System.out.println(info);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNostId() {
|
||||
String info = SystemId.getNodeId();
|
||||
assertThat(info).matches("\\d+\\.\\d+\\.\\d+\\.\\d+");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNodeFingerprint() {
|
||||
String hash = SystemId.getNodeFingerprint();
|
||||
assertThat(hash).matches("[A-Z0-9]+");
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user