formatting

This commit is contained in:
Jonathan Shook 2025-01-02 12:15:33 -06:00
parent 442eae1c4e
commit 1e8bd3d044
5 changed files with 206 additions and 176 deletions

View File

@ -2,13 +2,13 @@ package io.nosqlbench.adapters.api.activityimpl.uniform.opwrappers;
/*
* Copyright (c) nosqlbench
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@ -25,7 +25,7 @@ public enum DiffType {
none(0),
/// Verify that fields named in the row are present in the reference map.
rowfields(0x1),
resultfields(0x1),
/// Verify that fields in the reference map are present in the row data.
reffields(0x1 << 1),

View File

@ -37,7 +37,9 @@ import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
public class NBBaseComponent extends NBBaseComponentMetrics implements NBComponent, NBTokenWords, NBComponentTimeline {
public class NBBaseComponent extends NBBaseComponentMetrics
implements NBComponent, NBTokenWords, NBComponentTimeline
{
private final static Logger logger = LogManager.getLogger("RUNTIME");
protected final NBComponent parent;
protected final NBLabels labels;
@ -66,8 +68,7 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
labelsAdvisor.validateAll(componentSpecificLabelsOnly.asMap().keySet());
labelsAdvisor.validateAll(componentSpecificLabelsOnly.asMap().values());
labelsAdvisor.setName("Labels", "Check label names and values")
.logName();
labelsAdvisor.setName("Labels", "Check label names and values").logName();
NBAdvisorResults advisorResults = getAdvisorResults();
advisorResults.evaluate();
@ -83,7 +84,12 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
state = (state == NBInvokableState.ERRORED) ? state : NBInvokableState.RUNNING;
}
public NBBaseComponent(NBComponent parentComponent, NBLabels componentSpecificLabelsOnly, Map<String, String> props) {
public NBBaseComponent(
NBComponent parentComponent,
NBLabels componentSpecificLabelsOnly,
Map<String, String> props
)
{
this(parentComponent, componentSpecificLabelsOnly);
props.forEach(this::setComponentProp);
}
@ -96,18 +102,34 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
@Override
public synchronized NBComponent attachChild(NBComponent... children) {
for (NBComponent child : children) {
logger.debug(() -> "attaching " + child.description() + " to parent " + this.description());
for (NBComponent adding : children) {
logger.debug(
() -> "attaching " + adding.description() + " to parent " + this.description());
for (NBComponent extant : this.children) {
NBLabels eachLabels = extant.getComponentOnlyLabels();
NBLabels newLabels = child.getComponentOnlyLabels();
NBLabels newLabels = adding.getComponentOnlyLabels();
if (eachLabels != null && newLabels != null && !eachLabels.isEmpty() && !newLabels.isEmpty() && child.getComponentOnlyLabels().equals(extant.getComponentOnlyLabels())) {
throw new RuntimeException("Adding second child under already-defined labels is not allowed:\n" + " extant: (" + extant.getClass().getSimpleName() + ") " + extant.description() + "\n" + " adding: (" + child.getClass().getSimpleName() + ") " + child.description());
if (eachLabels != null &&
newLabels != null &&
!eachLabels.isEmpty() &&
!newLabels.isEmpty() &&
adding.getComponentOnlyLabels().equals(extant.getComponentOnlyLabels()))
{
throw new RuntimeException("""
Adding second child under already-defined labels is not allowed:
parent: (PARENTCLASS) PARENTNAME
extant: (EXTANTCLASS) EXTANTNAME
adding: (ADDINGCLASS) ADDINGNAME
"""
.replaceAll("PARENTCLASS", this.getClass().getSimpleName())
.replaceAll("PARENTNAME", this.description())
.replaceAll("EXTANTCLASS", extant.getClass().getSimpleName())
.replaceAll("EXTANTNAME", extant.description())
.replaceAll("ADDINGCLASS", adding.getClass().getSimpleName())
.replaceAll("ADDINGNAME", adding.description()));
}
}
this.children.add(child);
this.children.add(adding);
}
return this;
}
@ -115,7 +137,10 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
@Override
public NBComponent detachChild(NBComponent... children) {
for (NBComponent child : children) {
logger.debug(() -> "notifyinb before detaching " + child.description() + " from " + this.description());
logger.debug(() -> "notifyinb before detaching " +
child.description() +
" from " +
this.description());
child.beforeDetach();
}
for (NBComponent child : children) {
@ -134,7 +159,9 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
@Override
public NBLabels getLabels() {
NBLabels effectiveLabels = (this.parent == null ? NBLabels.forKV() : parent.getLabels());
effectiveLabels = (this.labels == null) ? effectiveLabels : effectiveLabels.and(this.labels);
effectiveLabels = (this.labels == null) ?
effectiveLabels :
effectiveLabels.and(this.labels);
return effectiveLabels;
}
@ -192,15 +219,16 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
}
public void onError(Exception e) {
RuntimeException wrapped = new RuntimeException("While in state " + this.state + ", an error occured: " + e, e);
RuntimeException wrapped = new RuntimeException(
"While in state " + this.state + ", an error occured: " + e, e);
logger.error(wrapped);
this.error = wrapped;
state = NBInvokableState.ERRORED;
}
/**
* Override this method in your component implementations when you need to do something
* to close out your component.
Override this method in your component implementations when you need to do something
to close out your component.
*/
protected void teardown() {
logger.debug("tearing down " + description());
@ -237,7 +265,8 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
logger.debug(() -> description() + " handling event " + event.toString());
switch (event) {
case UpEvent ue -> {
if (parent != null) parent.onEvent(ue);
if (parent != null)
parent.onEvent(ue);
}
case DownEvent de -> {
for (NBComponent child : children) {
@ -277,11 +306,12 @@ public class NBBaseComponent extends NBBaseComponentMetrics implements NBCompone
}
/**
* This method is called by the engine to report a component going out of scope. The metrics for that component
* will bubble up through the component layers and can be buffered for reporting at multiple levels.
*
* @param m
* The metric to report
This method is called by the engine to report a component going out of scope. The metrics for
that component
will bubble up through the component layers and can be buffered for reporting at multiple
levels.
@param m
The metric to report
*/
@Override
public void reportExecutionMetric(NBMetric m) {

View File

@ -108,6 +108,7 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
NBReconfigurable
{
private static final Logger logger = LogManager.getLogger("ACTIVITY");
private final OpSequence<OpDispenser<? extends CycleOp<?>>> sequence;
private final ConcurrentHashMap<String, DriverAdapter<CycleOp<?>, Space>> adapters
= new ConcurrentHashMap<>();
@ -260,18 +261,15 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
create().gauge(
"ops_pending", () -> this.getProgressMeter().getSummary().pending(),
MetricCategory.Core,
"The current number of operations which have not been dispatched for processing yet."
);
"The current number of operations which have not been dispatched for" +
" processing yet.");
create().gauge(
"ops_active", () -> this.getProgressMeter().getSummary().current(), MetricCategory.Core,
"The current number of operations which have been dispatched for processing, but which have not yet completed."
);
"The current number of operations which have been dispatched for" +
" processing, but which have not yet completed.");
create().gauge(
"ops_complete", () -> this.getProgressMeter().getSummary().complete(),
MetricCategory.Core, "The current number of operations which have been completed"
);
MetricCategory.Core, "The current number of operations which have been completed");
}
protected <O extends LongFunction> OpSequence<OpDispenser<? extends CycleOp<?>>> createOpSourceFromParsedOps2(List<DriverAdapter<CycleOp<?>, Space>> adapters,
@ -312,21 +310,19 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
Dryrun dryrun = pop.takeEnumFromFieldOr(Dryrun.class, Dryrun.none, "dryrun");
dispenser = OpFunctionComposition.wrapOptionally(
adapter, dispenser, pop, dryrun, opLookup);
adapter, dispenser, pop,
dryrun, opLookup);
// if (strict) {
// optemplate.assertConsumed();
// }
planner.addOp((OpDispenser<? extends CycleOp<?>>) dispenser, ratio);
} catch (Exception e) {
throw new OpConfigError(
"Error while mapping op from template named '" + pop.getName() + "': " + e.getMessage(),
e
);
"Error while mapping op from template named '" +
pop.getName() +
"': " +
e.getMessage(), e);
}
}
return planner.resolve();
} catch (Exception e) {
@ -336,12 +332,6 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
throw new OpConfigError(e.getMessage(), workloadSource, e);
}
}
}
public ParameterMap getParams() {
return activityDef.getParams();
}
// private ParsedOp upconvert(
@ -411,26 +401,26 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
// }
public void initActivity() {
initOrUpdateRateLimiters(this.activityDef);
initOrUpdateRateLimiters();
setDefaultsFromOpSequence(sequence);
}
public OpSequence<OpDispenser<? extends CycleOp<?>>> getOpSequence() {
return sequence;
}
// /**
// * When an adapter needs to identify an error uniquely for the purposes of
// * routing it to the correct error handler, or naming it in logs, or naming
// * metrics, override this method in your activity.
// *
// * @return A function that can reliably and safely map an instance of Throwable to a stable name.
// */
// @Override
// public final Function<Throwable, String> getErrorNameMapper() {
// return adapter.getErrorNameMapper();
// }
// /**
// * When an adapter needs to identify an error uniquely for the purposes of
// * routing it to the correct error handler, or naming it in logs, or naming
// * metrics, override this method in your activity.
// *
// * @return A function that can reliably and safely map an instance of Throwable to a
// stable name.
// */
// @Override
// public final Function<Throwable, String> getErrorNameMapper() {
// return adapter.getErrorNameMapper();
// }
@Override
public OpTemplates getSyntheticOpTemplates(OpTemplates opsDocList, Map<String, Object> cfg) {
@ -465,7 +455,6 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
return super.getLabels();
}
@Override
public void onEvent(NBEvent event) {
switch (event) {
@ -584,7 +573,8 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
if (threads > cycles) {
threads = (int) cycles;
logger.info(
"setting threads to {} (auto) [10xCORES, cycle count limited]", threads);
"setting threads to {} (auto) [10xCORES, cycle count limited]",
threads);
} else {
logger.info("setting threads to {} (auto) [10xCORES]", threads);
}
@ -625,67 +615,69 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
}
}
// /**
// Given a function that can create an op of type <O> from an OpTemplate, generate
// an indexed sequence of ready to call operations.
// <p>
// This method uses the following conventions to derive the sequence:
//
// <OL>
// <LI>If an 'op', 'stmt', or 'statement' parameter is provided, then it's value is
// taken as the only provided statement.</LI>
// <LI>If a 'yaml, or 'workload' parameter is provided, then the statements in that file
// are taken with their ratios </LI>
// <LI>Any provided tags filter is used to select only the op templates which have matching
// tags. If no tags are provided, then all the found op templates are included.</LI>
// <LI>The ratios and the 'seq' parameter are used to build a sequence of the ready operations,
// where the sequence length is the sum of the ratios.</LI>
// </OL>
// @param <O>
// A holder for an executable operation for the native driver used by this activity.
// @param opinit
// A function to map an OpTemplate to the executable operation form required by
// the native driver for this activity.
// @param defaultAdapter
// The adapter which will be used for any op templates with no explicit adapter
// @return The sequence of operations as determined by filtering and ratios
// */
// @Deprecated(forRemoval = true)
// protected <O> OpSequence<OpDispenser<? extends O>> createOpSequence(
// Function<OpTemplate, OpDispenser<? extends O>> opinit, boolean strict,
// DriverAdapter<?, ?> defaultAdapter
// ) {
//
// List<OpTemplate> stmts = loadOpTemplates(defaultAdapter, true, false);
//
// List<Long> ratios = new ArrayList<>(stmts.size());
//
// for (OpTemplate opTemplate : stmts) {
// long ratio = opTemplate.removeParamOrDefault("ratio", 1);
// ratios.add(ratio);
// }
//
// SequencerType sequencerType = getParams().getOptionalString("seq").map(
// SequencerType::valueOf).orElse(SequencerType.bucket);
//
// SequencePlanner<OpDispenser<? extends O>> planner = new SequencePlanner<>(sequencerType);
//
// try {
// for (int i = 0; i < stmts.size(); i++) {
// long ratio = ratios.get(i);
// OpTemplate optemplate = stmts.get(i);
// OpDispenser<? extends O> driverSpecificReadyOp = opinit.apply(optemplate);
// if (strict) {
// optemplate.assertConsumed();
// }
// planner.addOp(driverSpecificReadyOp, ratio);
// }
// } catch (Exception e) {
// throw new OpConfigError(e.getMessage(), workloadSource, e);
// }
//
// return planner.resolve();
// }
// /**
// Given a function that can create an op of type <O> from an OpTemplate, generate
// an indexed sequence of ready to call operations.
// <p>
// This method uses the following conventions to derive the sequence:
//
// <OL>
// <LI>If an 'op', 'stmt', or 'statement' parameter is provided, then it's value is
// taken as the only provided statement.</LI>
// <LI>If a 'yaml, or 'workload' parameter is provided, then the statements in that file
// are taken with their ratios </LI>
// <LI>Any provided tags filter is used to select only the op templates which have matching
// tags. If no tags are provided, then all the found op templates are included.</LI>
// <LI>The ratios and the 'seq' parameter are used to build a sequence of the ready
// operations,
// where the sequence length is the sum of the ratios.</LI>
// </OL>
// @param <O>
// A holder for an executable operation for the native driver used by this activity.
// @param opinit
// A function to map an OpTemplate to the executable operation form required by
// the native driver for this activity.
// @param defaultAdapter
// The adapter which will be used for any op templates with no explicit adapter
// @return The sequence of operations as determined by filtering and ratios
// */
// @Deprecated(forRemoval = true)
// protected <O> OpSequence<OpDispenser<? extends O>> createOpSequence(
// Function<OpTemplate, OpDispenser<? extends O>> opinit, boolean strict,
// DriverAdapter<?, ?> defaultAdapter
// ) {
//
// List<OpTemplate> stmts = loadOpTemplates(defaultAdapter, true, false);
//
// List<Long> ratios = new ArrayList<>(stmts.size());
//
// for (OpTemplate opTemplate : stmts) {
// long ratio = opTemplate.removeParamOrDefault("ratio", 1);
// ratios.add(ratio);
// }
//
// SequencerType sequencerType = getParams().getOptionalString("seq").map(
// SequencerType::valueOf).orElse(SequencerType.bucket);
//
// SequencePlanner<OpDispenser<? extends O>> planner = new
// SequencePlanner<>(sequencerType);
//
// try {
// for (int i = 0; i < stmts.size(); i++) {
// long ratio = ratios.get(i);
// OpTemplate optemplate = stmts.get(i);
// OpDispenser<? extends O> driverSpecificReadyOp = opinit.apply(optemplate);
// if (strict) {
// optemplate.assertConsumed();
// }
// planner.addOp(driverSpecificReadyOp, ratio);
// }
// } catch (Exception e) {
// throw new OpConfigError(e.getMessage(), workloadSource, e);
// }
//
// return planner.resolve();
// }
/// TODO: Move this out, adjacent to [OpsLoader]
protected OpTemplates loadOpTemplates() {
@ -756,7 +748,8 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
public synchronized void initOrUpdateRateLimiters() {
// cycleratePerThread = activityDef.getParams().takeBoolOrDefault("cyclerate_per_thread", false);
// cycleratePerThread =
// activityDef.getParams().takeBoolOrDefault("cyclerate_per_thread", false);
config.getOptional("striderate").map(StrideRateSpec::new)
.ifPresent(sr -> this.onEvent(new ParamChange<>(sr)));
@ -845,9 +838,9 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
}
// public void registerAutoCloseable(AutoCloseable closeable) {
// this.closeables.add(closeable);
// }
//
// this.closeables.add(closeable);
// }
//
public synchronized ErrorMetrics getExceptionMetrics() {
if (null == this.errorMetrics) {
errorMetrics = new ErrorMetrics(this);
@ -855,7 +848,6 @@ public class Activity<R extends java.util.function.LongFunction, S> extends NBSt
return errorMetrics;
}
public String getAlias() {
return config.getAlias();
}

View File

@ -2,13 +2,13 @@ package io.nosqlbench.engine.api.activityimpl.uniform;
/*
* Copyright (c) nosqlbench
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@ -36,7 +36,7 @@ public class ActivityMetrics {
public static final String RESPONSE_TIME = "_responsetime";
public static final String SERVICE_TIME = "_servicetime";
public final Activity<?,?> activity;
public final Activity<?, ?> activity;
public final int hdrdigits;
public NBMetricCounter pendingOpsCounter;
public NBMetricTimer bindTimer;
@ -50,7 +50,7 @@ public class ActivityMetrics {
public NBMetricTimer cycleResponseTimer;
public NBMetricHistogram triesHistogram;
public <S, R extends LongFunction> ActivityMetrics(Activity<?,?> activity) {
public <S, R extends LongFunction> ActivityMetrics(Activity<?, ?> activity) {
this.activity = activity;
this.hdrdigits = activity.getComponentProp("hdr_digits").map(Integer::parseInt).orElse(3);
initMetrics();
@ -60,8 +60,8 @@ public class ActivityMetrics {
this.pendingOpsCounter = activity.create().counter(
"pending_ops", MetricCategory.Core,
"Indicate the number of operations which have been started, but which have not been completed." + " This starts "
);
"Indicate the number of operations which have been started, but which have not been completed." +
" This starts ");
/// The bind timer keeps track of how long it takes for NoSQLBench to create an instance
@ -71,8 +71,7 @@ public class ActivityMetrics {
/// a cycle to an operation".
this.bindTimer = activity.create().timer(
"bind", hdrdigits, MetricCategory.Core,
"Time the step within a cycle which binds generated data to an op template to synthesize an executable operation."
);
"Time the step within a cycle which binds generated data to an op template to synthesize an executable operation.");
/// The execute timer keeps track of how long it takes to submit an operation to be executed
/// to an underlying native driver. For asynchronous APIs, such as those which return a
@ -82,14 +81,13 @@ public class ActivityMetrics {
/// and the result timer to measure the blocking calls to aquire the result.
this.executeTimer = activity.create().timer(
"execute", hdrdigits, MetricCategory.Core,
"Time how long it takes to submit a request and receive a result, including reading the result in the client."
);
"Time how long it takes to submit a request and receive a result, including reading the result in the client.");
/// The cycles service timer measures how long it takes to complete a cycle of work.
this.cycleServiceTimer = activity.create().timer(
"cycles" + SERVICE_TIME, hdrdigits, MetricCategory.Core,
"service timer for a cycle, including all of bind, execute, result and result_success;" + " service timers measure the time between submitting a request and receiving the response"
);
"service timer for a cycle, including all of bind, execute, result and result_success;" +
" service timers measure the time between submitting a request and receiving the response");
/// The result timer keeps track of how long it takes a native driver to service a request once submitted.
@ -99,8 +97,8 @@ public class ActivityMetrics {
/// cover each attempt at an operation through a native driver. Retries are not to be combined in this measurement.
this.resultTimer = activity.create().timer(
"result", hdrdigits, MetricCategory.Core,
"Time how long it takes to submit a request, receive a result, including binding, reading results, " + "and optionally verifying them, including all operations whether successful or not, for each attempted request."
);
"Time how long it takes to submit a request, receive a result, including binding, reading results, " +
"and optionally verifying them, including all operations whether successful or not, for each attempted request.");
/// The result-success timer keeps track of operations which had no exception. The measurements for this timer should
/// be exactly the same values as used for the result timer ({@link #getOrCreateResultTimer()}, except that
@ -109,23 +107,20 @@ public class ActivityMetrics {
/// the error handler logic.
this.resultSuccessTimer = activity.create().timer(
"result_success", hdrdigits, MetricCategory.Core,
"The execution time of successful operations, which includes submitting the operation, waiting for a response, and reading the result"
);
"The execution time of successful operations, which includes submitting the operation, waiting for a response, and reading the result");
/// The input timer measures how long it takes to get the cycle value to be used for
/// an operation.
this.inputTimer = activity.create().timer(
"read_input", activity.getComponentProp("hdr_digits").map(Integer::parseInt).orElse(3),
MetricCategory.Internals,
"measures overhead of acquiring a cycle range for an activity thread"
);
"measures overhead of acquiring a cycle range for an activity thread");
/// The strides service timer measures how long it takes to complete a stride of work.
this.stridesServiceTimer = activity.create().timer(
"strides", activity.getComponentProp("hdr_digits").map(Integer::parseInt).orElse(3),
MetricCategory.Core,
"service timer for a stride, which is the same as the op sequence length by default"
);
"service timer for a stride, which is the same as the op sequence length by default");
if (null != activity.getStrideLimiter()) {
/// The strides response timer measures the total response time from the scheduled
@ -134,8 +129,8 @@ public class ActivityMetrics {
/// there is no strides rate limiter.
this.stridesResponseTimer = activity.create().timer(
"strides" + RESPONSE_TIME, hdrdigits, MetricCategory.Core,
"response timer for a stride, which is the same as the op sequence length by default;" + " response timers include scheduling delays which occur when an activity falls behind its target rate"
);
"response timer for a stride, which is the same as the op sequence length by default;" +
" response timers include scheduling delays which occur when an activity falls behind its target rate");
} else {
stridesResponseTimer = null;
}
@ -151,8 +146,8 @@ public class ActivityMetrics {
if (null != activity.getCycleLimiter()) {
this.cycleResponseTimer = activity.create().timer(
"cycles" + RESPONSE_TIME, hdrdigits, MetricCategory.Core,
"response timer for a cycle, including all of bind, execute, result and result_success;" + " response timers include scheduling delays which occur when an activity falls behind its target rate"
);
"response timer for a cycle, including all of bind, execute, result and result_success;" +
" response timers include scheduling delays which occur when an activity falls behind its target rate");
} else {
cycleResponseTimer = null;
}
@ -167,9 +162,15 @@ public class ActivityMetrics {
/// This metric should be measured around every retry loop for a native operation.
this.triesHistogram = activity.create().histogram(
"tries", hdrdigits, MetricCategory.Core,
"A histogram of all tries for an activity. Perfect results mean all quantiles return 1." + " Slight saturation is indicated by p99 or p95 returning higher values." + " Lower quantiles returning more than 1, or higher values at high quantiles indicate incremental overload."
);
"A histogram of all tries for an activity. Perfect results mean all quantiles return 1." +
" Slight saturation is indicated by p99 or p95 returning higher values." +
" Lower quantiles returning more than 1, or higher values at high quantiles indicate incremental overload.");
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("ActivityMetrics{");
sb.append(this.activity.description());
return sb.toString();
}
}

View File

@ -41,8 +41,10 @@ import java.util.stream.Collectors;
public class ActivityTypeLoader {
private static final Logger logger = LogManager.getLogger(ActivityTypeLoader.class);
private final SimpleServiceLoader<DriverAdapter> DRIVERADAPTER_SPI_FINDER = new SimpleServiceLoader<>(DriverAdapter.class, Maturity.Any);
private final SimpleServiceLoader<DriverAdapterLoader> DRIVERADAPTERLOADER_SPI_FINDER = new SimpleServiceLoader<>(DriverAdapterLoader.class, Maturity.Any);
private final SimpleServiceLoader<DriverAdapter> DRIVERADAPTER_SPI_FINDER
= new SimpleServiceLoader<>(DriverAdapter.class, Maturity.Any);
private final SimpleServiceLoader<DriverAdapterLoader> DRIVERADAPTERLOADER_SPI_FINDER
= new SimpleServiceLoader<>(DriverAdapterLoader.class, Maturity.Any);
private final Set<URL> jarUrls = new HashSet<>();
public ActivityTypeLoader setMaturity(final Maturity maturity) {
@ -52,15 +54,19 @@ public class ActivityTypeLoader {
public ActivityTypeLoader() {
final List<String> libpaths = NBEnvironment.INSTANCE.interpolateEach(":", '$' + NBEnvironment.NBLIBS);
final List<String> libpaths = NBEnvironment.INSTANCE.interpolateEach(
":", '$' + NBEnvironment.NBLIBS);
Set<URL> urlsToAdd = new HashSet<>();
for (final String libpaths_entry : libpaths) {
final Path libpath = Path.of(libpaths_entry);
if (Files.isDirectory(libpath)) urlsToAdd = this.addLibDir(urlsToAdd, libpath);
else if (Files.isRegularFile(libpath) && libpath.toString().toLowerCase().endsWith(".zip"))
if (Files.isDirectory(libpath))
urlsToAdd = this.addLibDir(urlsToAdd, libpath);
else if (Files.isRegularFile(libpath) &&
libpath.toString().toLowerCase().endsWith(".zip"))
urlsToAdd = this.addZipDir(urlsToAdd, libpath);
else if (Files.isRegularFile(libpath) && libpath.toString().toLowerCase().endsWith(".jar"))
else if (Files.isRegularFile(libpath) &&
libpath.toString().toLowerCase().endsWith(".jar"))
urlsToAdd = this.addJarFile(urlsToAdd, libpath);
}
this.extendClassLoader(urlsToAdd);
@ -89,10 +95,12 @@ public class ActivityTypeLoader {
this.jarUrls.add(url);
}
final URL[] newUrlAry = newUrls.toArray(new URL[]{});
final URLClassLoader ucl = URLClassLoader.newInstance(newUrlAry, Thread.currentThread().getContextClassLoader());
final URLClassLoader ucl = URLClassLoader.newInstance(
newUrlAry, Thread.currentThread().getContextClassLoader());
Thread.currentThread().setContextClassLoader(ucl);
ActivityTypeLoader.logger.debug("Extended class loader layering with {}", newUrls);
} else ActivityTypeLoader.logger.debug("All URLs specified were already in a class loader.");
} else
ActivityTypeLoader.logger.debug("All URLs specified were already in a class loader.");
}
private Set<URL> addJarFile(final Set<URL> urls, final Path libpath) {
@ -109,11 +117,8 @@ public class ActivityTypeLoader {
}
private Set<URL> addLibDir(final Set<URL> urlsToAdd, final Path libpath) {
final Set<URL> urls = NBIO.local()
.searchPrefixes(libpath.toString())
.extensionSet(".jar")
.list().stream().map(Content::getURL)
.collect(Collectors.toSet());
final Set<URL> urls = NBIO.local().searchPrefixes(libpath.toString()).extensionSet(".jar")
.list().stream().map(Content::getURL).collect(Collectors.toSet());
urlsToAdd.addAll(urls);
return urlsToAdd;
}
@ -133,7 +138,7 @@ public class ActivityTypeLoader {
return urls;
}).ifPresent(this::extendClassLoader);
return getDriverAdapter(driverName,activityDef,parent);
return getDriverAdapter(driverName, activityDef, parent);
}
@ -149,18 +154,20 @@ public class ActivityTypeLoader {
if (oda.isPresent()) {
final DriverAdapter<?, ?> driverAdapter = oda.get();
final StandardActivityType activityType = new StandardActivityType<>(driverAdapter, activityDef, parent);
final StandardActivityType activityType = new StandardActivityType<>(
driverAdapter, activityDef, parent);
return Optional.of(activityType);
}
return Optional.empty();
}
public Set<String> getAllSelectors() {
// final Map<String, Maturity> allSelectors = this.ACTIVITYTYPE_SPI_FINDER.getAllSelectors();
// final Map<String, Maturity> allAdapters = this.DRIVERADAPTER_SPI_FINDER.getAllSelectors();
final Map<String, Maturity> allAdapterLoaders = this.DRIVERADAPTERLOADER_SPI_FINDER.getAllSelectors();
// final Map<String, Maturity> allSelectors = this.ACTIVITYTYPE_SPI_FINDER.getAllSelectors();
// final Map<String, Maturity> allAdapters = this.DRIVERADAPTER_SPI_FINDER.getAllSelectors();
final Map<String, Maturity> allAdapterLoaders
= this.DRIVERADAPTERLOADER_SPI_FINDER.getAllSelectors();
final Set<String> all = new LinkedHashSet<>();
// all.addAll(allSelectors.keySet());
// all.addAll(allSelectors.keySet());
all.addAll(allAdapterLoaders.keySet());
return all;
}