diff options
author | gjoranv <gv@verizonmedia.com> | 2021-02-17 16:29:27 +0100 |
---|---|---|
committer | gjoranv <gv@verizonmedia.com> | 2021-02-17 17:13:44 +0100 |
commit | dd166441907ebebbdc5363350e506cf5e668aeda (patch) | |
tree | 9f7c2552124be2912be8ee7aa059f2bb1b0463c9 | |
parent | 2effab0aa97eb8bcf91e4563334f3e7b5508a265 (diff) |
Remove the 'processing' module, now merged into container-core.
87 files changed, 0 insertions, 8231 deletions
diff --git a/processing/.gitignore b/processing/.gitignore deleted file mode 100644 index 3cc25b51fc4..00000000000 --- a/processing/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/pom.xml.build -/target diff --git a/processing/CMakeLists.txt b/processing/CMakeLists.txt deleted file mode 100644 index 7bb25e6a420..00000000000 --- a/processing/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -install_config_definitions() diff --git a/processing/OWNERS b/processing/OWNERS deleted file mode 100644 index d36fc40ac9f..00000000000 --- a/processing/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -bratseth -gjoranv - diff --git a/processing/README b/processing/README deleted file mode 100644 index 8c422ed9101..00000000000 --- a/processing/README +++ /dev/null @@ -1,10 +0,0 @@ -Java library for request-response data processing. - -This library defines request-response processing as an operation which -accepts a Request and produces a Response containing Data by executing -a Chain of processing components in a single worker thread using method -calls for chaining, i.e a synchronous processing model. -Data for the Response may optionally be produced asynchronously. - -The processing model can be implemented by subtyping in frameworks defining -a processing model (with a richer, more specific API) for a particular domain.
\ No newline at end of file diff --git a/processing/abi-spec.json b/processing/abi-spec.json deleted file mode 100644 index 1a28d053ed0..00000000000 --- a/processing/abi-spec.json +++ /dev/null @@ -1,799 +0,0 @@ -{ - "com.yahoo.component.chain.Chain": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(java.lang.String, java.util.List)", - "public void <init>(com.yahoo.component.ComponentId, java.util.List)", - "public void <init>(java.util.List)", - "public varargs void <init>(com.yahoo.component.chain.ChainedComponent[])", - "public varargs void <init>(java.lang.String, com.yahoo.component.chain.ChainedComponent[])", - "public varargs void <init>(com.yahoo.component.ComponentId, com.yahoo.component.chain.ChainedComponent[])", - "public void <init>(com.yahoo.component.ComponentId, java.util.Collection, java.util.Collection)", - "public com.yahoo.component.ComponentId getId()", - "public java.util.List components()", - "public java.lang.String toString()", - "public boolean equals(java.lang.Object)", - "public int hashCode()" - ], - "fields": [] - }, - "com.yahoo.component.chain.ChainedComponent": { - "superClass": "com.yahoo.component.AbstractComponent", - "interfaces": [], - "attributes": [ - "public", - "abstract" - ], - "methods": [ - "public void <init>(com.yahoo.component.ComponentId)", - "protected void <init>()", - "public void initDependencies(com.yahoo.component.chain.dependencies.Dependencies)", - "public com.yahoo.component.chain.dependencies.Dependencies getDependencies()", - "protected com.yahoo.component.chain.dependencies.Dependencies getDefaultAnnotatedDependencies()", - "protected com.yahoo.component.chain.dependencies.Dependencies getAnnotatedDependencies(java.lang.Class, java.lang.Class, java.lang.Class)" - ], - "fields": [] - }, - "com.yahoo.component.chain.ChainsConfigurer": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()", - "public static void prepareChainRegistry(com.yahoo.component.provider.ComponentRegistry, com.yahoo.component.chain.model.ChainsModel, com.yahoo.component.provider.ComponentRegistry)" - ], - "fields": [] - }, - "com.yahoo.component.chain.Phase": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(java.lang.String, java.util.Set, java.util.Set)", - "public void <init>(java.lang.String, com.yahoo.component.chain.dependencies.Dependencies)", - "public java.lang.String getName()", - "public java.util.Set before()", - "public java.util.Set after()", - "public com.yahoo.component.chain.Phase union(com.yahoo.component.chain.Phase)" - ], - "fields": [ - "public final com.yahoo.component.chain.dependencies.Dependencies dependencies" - ] - }, - "com.yahoo.component.chain.dependencies.After": { - "superClass": "java.lang.Object", - "interfaces": [ - "java.lang.annotation.Annotation" - ], - "attributes": [ - "public", - "interface", - "abstract", - "annotation" - ], - "methods": [ - "public abstract java.lang.String[] value()" - ], - "fields": [] - }, - "com.yahoo.component.chain.dependencies.Before": { - "superClass": "java.lang.Object", - "interfaces": [ - "java.lang.annotation.Annotation" - ], - "attributes": [ - "public", - "interface", - "abstract", - "annotation" - ], - "methods": [ - "public abstract java.lang.String[] value()" - ], - "fields": [] - }, - "com.yahoo.component.chain.dependencies.Dependencies": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(java.util.Collection, java.util.Collection, java.util.Collection)", - "public static com.yahoo.component.chain.dependencies.Dependencies emptyDependencies()", - "public com.yahoo.component.chain.dependencies.Dependencies union(com.yahoo.component.chain.dependencies.Dependencies)", - "public java.lang.String toString()", - "public java.util.Set provides()", - "public java.util.Set before()", - "public java.util.Set after()" - ], - "fields": [] - }, - "com.yahoo.component.chain.dependencies.Provides": { - "superClass": "java.lang.Object", - "interfaces": [ - "java.lang.annotation.Annotation" - ], - "attributes": [ - "public", - "interface", - "abstract", - "annotation" - ], - "methods": [ - "public abstract java.lang.String[] value()" - ], - "fields": [] - }, - "com.yahoo.processing.IllegalInputException": { - "superClass": "java.lang.IllegalArgumentException", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(java.lang.String)", - "public void <init>(java.lang.Throwable)", - "public void <init>(java.lang.String, java.lang.Throwable)" - ], - "fields": [] - }, - "com.yahoo.processing.Processor": { - "superClass": "com.yahoo.component.chain.ChainedComponent", - "interfaces": [], - "attributes": [ - "public", - "abstract" - ], - "methods": [ - "public void <init>()", - "public abstract com.yahoo.processing.Response process(com.yahoo.processing.Request, com.yahoo.processing.execution.Execution)" - ], - "fields": [] - }, - "com.yahoo.processing.Request": { - "superClass": "com.yahoo.component.provider.FreezableClass", - "interfaces": [ - "java.lang.Cloneable" - ], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()", - "public void <init>(com.yahoo.processing.request.Properties)", - "public com.yahoo.processing.request.Properties properties()", - "public java.util.List errors()", - "public com.yahoo.processing.Request clone()", - "public bridge synthetic com.yahoo.component.provider.FreezableClass clone()", - "public bridge synthetic java.lang.Object clone()" - ], - "fields": [ - "public static final com.yahoo.processing.request.CompoundName CHAIN", - "public static final com.yahoo.processing.request.CompoundName JDISC_REQUEST" - ] - }, - "com.yahoo.processing.Response": { - "superClass": "com.yahoo.component.provider.ListenableFreezableClass", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(com.yahoo.processing.Request)", - "public void <init>(com.yahoo.processing.response.DataList)", - "public void <init>(com.yahoo.processing.Request, com.yahoo.processing.request.ErrorMessage)", - "public void mergeWith(com.yahoo.processing.Response)", - "public com.yahoo.processing.response.DataList data()", - "public static com.google.common.util.concurrent.ListenableFuture recursiveComplete(com.yahoo.processing.response.DataList)" - ], - "fields": [] - }, - "com.yahoo.processing.execution.AsyncExecution": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(com.yahoo.processing.Processor, com.yahoo.processing.execution.Execution)", - "public void <init>(com.yahoo.component.chain.Chain, com.yahoo.processing.execution.Execution)", - "public void <init>(com.yahoo.processing.execution.Execution)", - "public com.yahoo.processing.response.FutureResponse process(com.yahoo.processing.Request)", - "public static java.util.List waitForAll(java.util.Collection, long)" - ], - "fields": [] - }, - "com.yahoo.processing.execution.Execution$Environment": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public static com.yahoo.processing.execution.Execution$Environment createEmpty()", - "public com.yahoo.processing.execution.Execution$Environment nested()", - "public void <init>(com.yahoo.processing.execution.chain.ChainRegistry)", - "public com.yahoo.processing.execution.chain.ChainRegistry chainRegistry()" - ], - "fields": [] - }, - "com.yahoo.processing.execution.Execution$Trace$Level": { - "superClass": "java.lang.Enum", - "interfaces": [], - "attributes": [ - "public", - "final", - "enum" - ], - "methods": [ - "public static com.yahoo.processing.execution.Execution$Trace$Level[] values()", - "public static com.yahoo.processing.execution.Execution$Trace$Level valueOf(java.lang.String)", - "public int value()", - "public boolean includes(int)" - ], - "fields": [ - "public static final enum com.yahoo.processing.execution.Execution$Trace$Level Step", - "public static final enum com.yahoo.processing.execution.Execution$Trace$Level Timestamp", - "public static final enum com.yahoo.processing.execution.Execution$Trace$Level Dependencies" - ] - }, - "com.yahoo.processing.execution.Execution$Trace$LogValue": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(java.lang.String, java.lang.String)", - "public java.lang.String getKey()", - "public java.lang.String getValue()", - "public java.lang.String toString()" - ], - "fields": [] - }, - "com.yahoo.processing.execution.Execution$Trace": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public static com.yahoo.processing.execution.Execution$Trace createRoot(int)", - "public com.yahoo.processing.execution.Execution$Trace createChild()", - "public int getTraceLevel()", - "public void setTraceLevel(int)", - "public void setForceTimestamps(boolean)", - "public boolean getForceTimestamps()", - "public void trace(java.lang.String, int)", - "public void trace(java.lang.Object, int)", - "public void logValue(java.lang.String, java.lang.String)", - "public java.util.Iterator logValueIterator()", - "public com.yahoo.yolean.trace.TraceVisitor accept(com.yahoo.yolean.trace.TraceVisitor)", - "public void setProperty(java.lang.String, java.lang.Object)", - "public java.lang.Object getProperty(java.lang.String)", - "public com.yahoo.yolean.trace.TraceNode traceNode()", - "public java.lang.String toString()" - ], - "fields": [] - }, - "com.yahoo.processing.execution.Execution": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(com.yahoo.processing.Processor, com.yahoo.processing.execution.Execution)", - "public static com.yahoo.processing.execution.Execution createRoot(com.yahoo.processing.Processor, int, com.yahoo.processing.execution.Execution$Environment)", - "public static com.yahoo.processing.execution.Execution createRoot(com.yahoo.component.chain.Chain, int, com.yahoo.processing.execution.Execution$Environment)", - "public void <init>(com.yahoo.component.chain.Chain, com.yahoo.processing.execution.Execution)", - "public void <init>(com.yahoo.processing.execution.Execution)", - "protected void <init>(com.yahoo.component.chain.Chain, int, com.yahoo.processing.execution.Execution$Trace, com.yahoo.processing.execution.Execution$Environment)", - "public com.yahoo.processing.Response process(com.yahoo.processing.Request)", - "protected int nextIndex()", - "protected void onInvoking(com.yahoo.processing.Request, com.yahoo.processing.Processor)", - "protected void onReturning(com.yahoo.processing.Request, com.yahoo.processing.Processor, com.yahoo.processing.Response)", - "protected void previousProcessor()", - "protected void nextProcessor()", - "protected com.yahoo.processing.Processor next()", - "public com.yahoo.component.chain.Chain chain()", - "protected com.yahoo.processing.Response defaultResponse(com.yahoo.processing.Request)", - "public java.lang.String toString()", - "public com.yahoo.processing.execution.Execution$Trace trace()", - "public com.yahoo.processing.execution.Execution$Environment environment()" - ], - "fields": [] - }, - "com.yahoo.processing.execution.ExecutionWithResponse": { - "superClass": "com.yahoo.processing.execution.Execution", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(com.yahoo.component.chain.Chain, com.yahoo.processing.Response, com.yahoo.processing.execution.Execution)", - "protected com.yahoo.processing.Response defaultResponse(com.yahoo.processing.Request)" - ], - "fields": [] - }, - "com.yahoo.processing.execution.ResponseReceiver": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public", - "interface", - "abstract" - ], - "methods": [ - "public abstract void setResponse(com.yahoo.processing.Response)" - ], - "fields": [] - }, - "com.yahoo.processing.execution.RunnableExecution": { - "superClass": "java.lang.Object", - "interfaces": [ - "java.lang.Runnable" - ], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(com.yahoo.processing.Request, com.yahoo.processing.execution.Execution)", - "public void run()", - "public com.yahoo.processing.Response getResponse()", - "public java.lang.Throwable getException()" - ], - "fields": [] - }, - "com.yahoo.processing.execution.chain.ChainRegistry": { - "superClass": "com.yahoo.component.provider.ComponentRegistry", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()" - ], - "fields": [] - }, - "com.yahoo.processing.request.CloneHelper": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()", - "public final java.lang.Object clone(java.lang.Object)", - "protected java.lang.Object objectClone(java.lang.Object)", - "public java.util.Map cloneMap(java.util.Map)" - ], - "fields": [] - }, - "com.yahoo.processing.request.CompoundName": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public", - "final" - ], - "methods": [ - "public void <init>(java.lang.String)", - "public static varargs com.yahoo.processing.request.CompoundName fromComponents(java.lang.String[])", - "public void <init>(java.util.List)", - "public com.yahoo.processing.request.CompoundName append(java.lang.String)", - "public com.yahoo.processing.request.CompoundName append(com.yahoo.processing.request.CompoundName)", - "public varargs com.yahoo.processing.request.CompoundName prepend(java.lang.String[])", - "public java.lang.String last()", - "public java.lang.String first()", - "public com.yahoo.processing.request.CompoundName first(int)", - "public com.yahoo.processing.request.CompoundName rest()", - "public com.yahoo.processing.request.CompoundName rest(int)", - "public int size()", - "public java.lang.String get(int)", - "public com.yahoo.processing.request.CompoundName set(int, java.lang.String)", - "public boolean isCompound()", - "public boolean isEmpty()", - "public boolean hasPrefix(com.yahoo.processing.request.CompoundName)", - "public java.util.List asList()", - "public int hashCode()", - "public boolean equals(java.lang.Object)", - "public java.lang.String toString()", - "public java.lang.String getLowerCasedName()" - ], - "fields": [ - "public static final com.yahoo.processing.request.CompoundName empty" - ] - }, - "com.yahoo.processing.request.ErrorMessage": { - "superClass": "java.lang.Object", - "interfaces": [ - "java.lang.Cloneable" - ], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(java.lang.String)", - "public void <init>(int, java.lang.String)", - "public void <init>(java.lang.String, java.lang.String)", - "public void <init>(int, java.lang.String, java.lang.String)", - "public void <init>(java.lang.String, java.lang.Throwable)", - "public void <init>(int, java.lang.String, java.lang.Throwable)", - "public void <init>(java.lang.String, java.lang.String, java.lang.Throwable)", - "public void <init>(int, java.lang.String, java.lang.String, java.lang.Throwable)", - "public int getCode()", - "public java.lang.String getMessage()", - "public java.lang.String getDetailedMessage()", - "public java.lang.Throwable getCause()", - "public java.lang.String toString()", - "public int hashCode()", - "public boolean equals(java.lang.Object)", - "public com.yahoo.processing.request.ErrorMessage clone()", - "public bridge synthetic java.lang.Object clone()" - ], - "fields": [] - }, - "com.yahoo.processing.request.Properties": { - "superClass": "java.lang.Object", - "interfaces": [ - "java.lang.Cloneable" - ], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()", - "public com.yahoo.processing.request.Properties chain(com.yahoo.processing.request.Properties)", - "public com.yahoo.processing.request.Properties chained()", - "public final com.yahoo.processing.request.Properties getInstance(java.lang.Class)", - "public final java.util.Map listProperties()", - "public final java.util.Map listProperties(java.util.Map)", - "public final java.util.Map listProperties(com.yahoo.processing.request.CompoundName)", - "public final java.util.Map listProperties(java.lang.String)", - "public final java.util.Map listProperties(com.yahoo.processing.request.CompoundName, java.util.Map)", - "public final java.util.Map listProperties(java.lang.String, java.util.Map)", - "public java.util.Map listProperties(com.yahoo.processing.request.CompoundName, java.util.Map, com.yahoo.processing.request.Properties)", - "public final java.util.Map listProperties(java.lang.String, java.util.Map, com.yahoo.processing.request.Properties)", - "public java.lang.Object get(com.yahoo.processing.request.CompoundName, java.util.Map, com.yahoo.processing.request.Properties)", - "public final java.lang.Object get(java.lang.String, java.util.Map, com.yahoo.processing.request.Properties)", - "public final java.lang.Object get(com.yahoo.processing.request.CompoundName, java.util.Map)", - "public final java.lang.Object get(java.lang.String, java.util.Map)", - "public final java.lang.Object get(com.yahoo.processing.request.CompoundName)", - "public final java.lang.Object get(java.lang.String)", - "public final java.lang.Object get(com.yahoo.processing.request.CompoundName, java.lang.Object)", - "public final java.lang.Object get(java.lang.String, java.lang.Object)", - "public void set(com.yahoo.processing.request.CompoundName, java.lang.Object, java.util.Map)", - "public final void set(java.lang.String, java.lang.Object, java.util.Map)", - "public final void set(com.yahoo.processing.request.CompoundName, java.lang.Object)", - "public final void set(java.lang.String, java.lang.Object)", - "public void clearAll(com.yahoo.processing.request.CompoundName, java.util.Map)", - "public final void clearAll(java.lang.String, java.lang.Object, java.util.Map)", - "public final void clearAll(com.yahoo.processing.request.CompoundName)", - "public final void clearAll(java.lang.String)", - "public final boolean getBoolean(com.yahoo.processing.request.CompoundName)", - "public final boolean getBoolean(java.lang.String)", - "public final boolean getBoolean(com.yahoo.processing.request.CompoundName, boolean)", - "public final boolean getBoolean(java.lang.String, boolean)", - "protected final boolean asBoolean(java.lang.Object, boolean)", - "public final java.lang.String getString(com.yahoo.processing.request.CompoundName)", - "public final java.lang.String getString(java.lang.String)", - "public final java.lang.String getString(com.yahoo.processing.request.CompoundName, java.lang.String)", - "public final java.lang.String getString(java.lang.String, java.lang.String)", - "protected final java.lang.String asString(java.lang.Object, java.lang.String)", - "public final java.lang.Integer getInteger(com.yahoo.processing.request.CompoundName)", - "public final java.lang.Integer getInteger(java.lang.String)", - "public final java.lang.Integer getInteger(com.yahoo.processing.request.CompoundName, java.lang.Integer)", - "public final java.lang.Integer getInteger(java.lang.String, java.lang.Integer)", - "protected final java.lang.Integer asInteger(java.lang.Object, java.lang.Integer)", - "public final java.lang.Long getLong(com.yahoo.processing.request.CompoundName)", - "public final java.lang.Long getLong(java.lang.String)", - "public final java.lang.Long getLong(com.yahoo.processing.request.CompoundName, java.lang.Long)", - "public final java.lang.Long getLong(java.lang.String, java.lang.Long)", - "protected final java.lang.Long asLong(java.lang.Object, java.lang.Long)", - "public final java.lang.Double getDouble(com.yahoo.processing.request.CompoundName)", - "public final java.lang.Double getDouble(java.lang.String)", - "public final java.lang.Double getDouble(com.yahoo.processing.request.CompoundName, java.lang.Double)", - "public final java.lang.Double getDouble(java.lang.String, java.lang.Double)", - "protected final java.lang.Double asDouble(java.lang.Object, java.lang.Double)", - "public com.yahoo.processing.request.Properties clone()", - "public static java.util.Map cloneMap(java.util.Map)", - "public static java.lang.Object clone(java.lang.Object)", - "public bridge synthetic java.lang.Object clone()" - ], - "fields": [] - }, - "com.yahoo.processing.request.properties.PropertyMap": { - "superClass": "com.yahoo.processing.request.Properties", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()", - "public void set(com.yahoo.processing.request.CompoundName, java.lang.Object, java.util.Map)", - "protected boolean shouldSet(com.yahoo.processing.request.CompoundName, java.lang.Object)", - "public java.lang.Object get(com.yahoo.processing.request.CompoundName, java.util.Map, com.yahoo.processing.request.Properties)", - "public com.yahoo.processing.request.properties.PropertyMap clone()", - "public java.util.Map listProperties(com.yahoo.processing.request.CompoundName, java.util.Map, com.yahoo.processing.request.Properties)", - "public bridge synthetic com.yahoo.processing.request.Properties clone()", - "public bridge synthetic java.lang.Object clone()" - ], - "fields": [] - }, - "com.yahoo.processing.request.properties.PublicCloneable": { - "superClass": "java.lang.Object", - "interfaces": [ - "java.lang.Cloneable" - ], - "attributes": [ - "public", - "interface", - "abstract" - ], - "methods": [ - "public abstract java.lang.Object clone()" - ], - "fields": [] - }, - "com.yahoo.processing.response.AbstractData": { - "superClass": "com.yahoo.component.provider.ListenableFreezableClass", - "interfaces": [ - "com.yahoo.processing.response.Data" - ], - "attributes": [ - "public", - "abstract" - ], - "methods": [ - "public void <init>(com.yahoo.processing.Request)", - "public com.yahoo.processing.Request request()" - ], - "fields": [] - }, - "com.yahoo.processing.response.AbstractDataList$DrainOnGetFuture": { - "superClass": "com.google.common.util.concurrent.AbstractFuture", - "interfaces": [], - "attributes": [ - "public", - "final" - ], - "methods": [ - "public void <init>(com.yahoo.processing.response.DataList)", - "public boolean cancel(boolean)", - "public boolean isCancelled()", - "public com.yahoo.processing.response.DataList get()", - "public com.yahoo.processing.response.DataList get(long, java.util.concurrent.TimeUnit)", - "public bridge synthetic java.lang.Object get()", - "public bridge synthetic java.lang.Object get(long, java.util.concurrent.TimeUnit)" - ], - "fields": [] - }, - "com.yahoo.processing.response.AbstractDataList": { - "superClass": "com.yahoo.component.provider.ListenableFreezableClass", - "interfaces": [ - "com.yahoo.processing.response.DataList", - "com.yahoo.processing.response.Streamed", - "com.yahoo.processing.response.Ordered" - ], - "attributes": [ - "public", - "abstract" - ], - "methods": [ - "protected void <init>(com.yahoo.processing.Request)", - "protected void <init>(com.yahoo.processing.Request, com.yahoo.processing.response.IncomingData)", - "protected void <init>(com.yahoo.processing.Request, com.yahoo.processing.response.IncomingData, boolean, boolean)", - "public com.yahoo.processing.Request request()", - "public com.yahoo.processing.response.IncomingData incoming()", - "public com.google.common.util.concurrent.ListenableFuture complete()", - "public boolean isOrdered()", - "public boolean isStreamed()", - "public java.lang.String toString()" - ], - "fields": [] - }, - "com.yahoo.processing.response.ArrayDataList": { - "superClass": "com.yahoo.processing.response.AbstractDataList", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "protected void <init>(com.yahoo.processing.Request)", - "protected void <init>(com.yahoo.processing.Request, com.yahoo.processing.response.IncomingData)", - "protected void <init>(com.yahoo.processing.Request, com.yahoo.processing.response.IncomingData, boolean, boolean)", - "public static com.yahoo.processing.response.ArrayDataList create(com.yahoo.processing.Request)", - "public static com.yahoo.processing.response.ArrayDataList createAsync(com.yahoo.processing.Request)", - "public static com.yahoo.processing.response.ArrayDataList createAsyncUnordered(com.yahoo.processing.Request)", - "public static com.yahoo.processing.response.ArrayDataList createAsyncNonstreamed(com.yahoo.processing.Request)", - "public com.yahoo.processing.response.Data add(com.yahoo.processing.response.Data)", - "public com.yahoo.processing.response.Data get(int)", - "public java.util.List asList()", - "public void addDataListener(java.lang.Runnable)", - "public void freeze()" - ], - "fields": [] - }, - "com.yahoo.processing.response.Data": { - "superClass": "java.lang.Object", - "interfaces": [ - "com.yahoo.component.provider.ListenableFreezable" - ], - "attributes": [ - "public", - "interface", - "abstract" - ], - "methods": [ - "public abstract com.yahoo.processing.Request request()" - ], - "fields": [] - }, - "com.yahoo.processing.response.DataList": { - "superClass": "java.lang.Object", - "interfaces": [ - "com.yahoo.processing.response.Data" - ], - "attributes": [ - "public", - "interface", - "abstract" - ], - "methods": [ - "public abstract com.yahoo.processing.response.Data add(com.yahoo.processing.response.Data)", - "public abstract com.yahoo.processing.response.Data get(int)", - "public abstract java.util.List asList()", - "public abstract com.yahoo.processing.response.IncomingData incoming()", - "public abstract com.google.common.util.concurrent.ListenableFuture complete()", - "public abstract void addDataListener(java.lang.Runnable)", - "public void close()" - ], - "fields": [] - }, - "com.yahoo.processing.response.DefaultIncomingData": { - "superClass": "java.lang.Object", - "interfaces": [ - "com.yahoo.processing.response.IncomingData" - ], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>()", - "public void <init>(com.yahoo.processing.response.DataList)", - "public final void assignOwner(com.yahoo.processing.response.DataList)", - "public com.yahoo.processing.response.DataList getOwner()", - "public com.google.common.util.concurrent.ListenableFuture completed()", - "public synchronized boolean isComplete()", - "public synchronized void addLast(com.yahoo.processing.response.Data)", - "public synchronized void add(com.yahoo.processing.response.Data)", - "public synchronized void addLast(java.util.List)", - "public synchronized void add(java.util.List)", - "public synchronized void markComplete()", - "public synchronized java.util.List drain()", - "public void addNewDataListener(java.lang.Runnable, java.util.concurrent.Executor)", - "public java.lang.String toString()" - ], - "fields": [] - }, - "com.yahoo.processing.response.FutureResponse": { - "superClass": "com.google.common.util.concurrent.ForwardingFuture", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(java.util.concurrent.Callable, com.yahoo.processing.execution.Execution, com.yahoo.processing.Request)", - "public com.google.common.util.concurrent.ListenableFutureTask delegate()", - "public com.yahoo.processing.Response get()", - "public com.yahoo.processing.Response get(long, java.util.concurrent.TimeUnit)", - "public com.yahoo.processing.Request getRequest()", - "public bridge synthetic java.lang.Object get(long, java.util.concurrent.TimeUnit)", - "public bridge synthetic java.lang.Object get()", - "public bridge synthetic java.util.concurrent.Future delegate()", - "public bridge synthetic java.lang.Object delegate()" - ], - "fields": [] - }, - "com.yahoo.processing.response.IncomingData$NullIncomingData$ImmediateFuture": { - "superClass": "com.google.common.util.concurrent.AbstractFuture", - "interfaces": [], - "attributes": [ - "public" - ], - "methods": [ - "public void <init>(com.yahoo.processing.response.DataList)", - "public boolean cancel(boolean)", - "public boolean isCancelled()", - "public boolean isDone()", - "public com.yahoo.processing.response.DataList get()", - "public com.yahoo.processing.response.DataList get(long, java.util.concurrent.TimeUnit)", - "public bridge synthetic java.lang.Object get()", - "public bridge synthetic java.lang.Object get(long, java.util.concurrent.TimeUnit)" - ], - "fields": [] - }, - "com.yahoo.processing.response.IncomingData$NullIncomingData": { - "superClass": "java.lang.Object", - "interfaces": [ - "com.yahoo.processing.response.IncomingData" - ], - "attributes": [ - "public", - "final" - ], - "methods": [ - "public void <init>(com.yahoo.processing.response.DataList)", - "public com.google.common.util.concurrent.ListenableFuture completed()", - "public com.yahoo.processing.response.DataList getOwner()", - "public boolean isComplete()", - "public void addLast(com.yahoo.processing.response.Data)", - "public void add(com.yahoo.processing.response.Data)", - "public void addLast(java.util.List)", - "public void add(java.util.List)", - "public void markComplete()", - "public java.util.List drain()", - "public void addNewDataListener(java.lang.Runnable, java.util.concurrent.Executor)", - "public java.lang.String toString()" - ], - "fields": [] - }, - "com.yahoo.processing.response.IncomingData": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public", - "interface", - "abstract" - ], - "methods": [ - "public abstract com.yahoo.processing.response.DataList getOwner()", - "public abstract com.google.common.util.concurrent.ListenableFuture completed()", - "public abstract boolean isComplete()", - "public abstract void addLast(com.yahoo.processing.response.Data)", - "public abstract void add(com.yahoo.processing.response.Data)", - "public abstract void addLast(java.util.List)", - "public abstract void add(java.util.List)", - "public abstract void markComplete()", - "public abstract java.util.List drain()", - "public abstract void addNewDataListener(java.lang.Runnable, java.util.concurrent.Executor)" - ], - "fields": [] - }, - "com.yahoo.processing.response.Ordered": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public", - "interface", - "abstract" - ], - "methods": [ - "public abstract boolean isOrdered()" - ], - "fields": [] - }, - "com.yahoo.processing.response.Streamed": { - "superClass": "java.lang.Object", - "interfaces": [], - "attributes": [ - "public", - "interface", - "abstract" - ], - "methods": [ - "public abstract boolean isStreamed()" - ], - "fields": [] - } -}
\ No newline at end of file diff --git a/processing/pom.xml b/processing/pom.xml deleted file mode 100644 index 2e6be8a250a..00000000000 --- a/processing/pom.xml +++ /dev/null @@ -1,87 +0,0 @@ -<?xml version="1.0"?> -<!-- Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 - http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>com.yahoo.vespa</groupId> - <artifactId>parent</artifactId> - <version>7-SNAPSHOT</version> - <relativePath>../parent/pom.xml</relativePath> - </parent> - <artifactId>processing</artifactId> - <packaging>jar</packaging> - <version>7-SNAPSHOT</version> - <dependencies> - - <!-- COMPILE scope --> - <dependency> - <groupId>com.yahoo.vespa</groupId> - <artifactId>annotations</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>com.yahoo.vespa</groupId> - <artifactId>container-di</artifactId> - <version>${project.version}</version> - </dependency> - - <!-- PROVIDED scope --> - <dependency> - <groupId>com.yahoo.vespa</groupId> - <artifactId>provided-dependencies</artifactId> - <version>${project.version}</version> - <type>pom</type> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>com.yahoo.vespa</groupId> - <artifactId>component</artifactId> - <version>${project.version}</version> - <scope>provided</scope> - </dependency> - - - <!-- TEST scope --> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <scope>test</scope> - </dependency> - </dependencies> - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <compilerArgs> - <arg>-Xlint:all</arg> - <arg>-Xlint:-rawtypes</arg> - <arg>-Xlint:-serial</arg> - <arg>-Xlint:-options</arg> <!-- TODO: Remove when on a version above Java 8 --> - <arg>-Werror</arg> - </compilerArgs> - </configuration> - </plugin> - <plugin> - <groupId>com.yahoo.vespa</groupId> - <artifactId>abi-check-plugin</artifactId> - </plugin> - <plugin> - <groupId>com.yahoo.vespa</groupId> - <artifactId>config-class-plugin</artifactId> - <version>${project.version}</version> - <executions> - <execution> - <goals> - <goal>config-gen</goal> - </goals> - </execution> - </executions> - </plugin> - </plugins> - </build> -</project> diff --git a/processing/src/main/java/com/yahoo/component/chain/Chain.java b/processing/src/main/java/com/yahoo/component/chain/Chain.java deleted file mode 100644 index 1c628f3dfa4..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/Chain.java +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain; - -import com.google.common.collect.ImmutableList; -import com.yahoo.component.ComponentId; -import com.yahoo.component.chain.dependencies.ordering.ChainBuilder; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * An immutable ordered list of components - * - * @author Tony Vaagenes - */ -public class Chain<COMPONENT extends ChainedComponent> { - - final private List<COMPONENT> componentList; - private final ComponentId id; - - /** Create a chain directly. This will NOT order the chain by the ordering constraints. */ - public Chain(String id, List<COMPONENT> componentList) { - this(new ComponentId(id), componentList); - } - - /** Create a chain directly. This will NOT order the chain by the ordering constraints. */ - public Chain(ComponentId id, List<COMPONENT> componentList) { - this.id = id; - this.componentList = ImmutableList.copyOf(componentList); - } - - /** Create a chain directly. This will NOT order the chain by the ordering constraints. */ - public Chain(List<COMPONENT> componentList) { - this(new ComponentId("anonymous chain"), componentList); - } - - /** Create a chain directly. This will NOT order the chain by the ordering constraints. */ - @SafeVarargs - public Chain(COMPONENT... components) { - this("anonymous chain", components); - } - - /** Create a chain directly. This will NOT order the chain by the ordering constraints. */ - @SafeVarargs - public Chain(String id, COMPONENT... components) { - this(new ComponentId(id), components); - } - - /** Create a chain directly. This will NOT order the chain by the ordering constraints. */ - @SafeVarargs - @SuppressWarnings("varargs") - public Chain(ComponentId id, COMPONENT... components) { - this(id, Arrays.<COMPONENT>asList(components)); - } - - /** Create a chain by using a builder. This will order the chain by the ordering constraints. */ - public Chain(ComponentId id, Collection<COMPONENT> components, Collection<Phase> phases) { - this(id, buildChain( - emptyListIfNull(components), - emptyListIfNull(phases)).components()); - - } - - public ComponentId getId() { - return id; - } - - private static <T> Collection<T> emptyListIfNull(Collection<T> collection) { - return collection == null ? Collections.<T>emptyList() : collection; - } - - private static <T extends ChainedComponent> Chain<T> buildChain(Collection<T> components, Collection<Phase> phases) { - ChainBuilder<T> builder = new ChainBuilder<>(new ComponentId("temp")); - for (Phase phase : phases) { - builder.addPhase(phase); - } - - for (T component : components) { - builder.addComponent(component); - } - - return builder.orderNodes(); - } - - public List<COMPONENT> components() { - return componentList; - } - - public - @Override - String toString() { - StringBuilder b = new StringBuilder("chain '"); - b.append(getId().stringValue()); - b.append("' ["); - appendComponent(0, b); - appendComponent(1, b); - if (components().size() > 3) - b.append("... -> "); - if (components().size() > 2) - appendComponent(components().size() - 1, b); - b.append("]"); - return b.toString(); - } - - private void appendComponent(int i, StringBuilder b) { - if (i >= components().size()) return; - b.append(components().get(i).getId().stringValue()); - if (i < components().size() - 1) - b.append(" -> "); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Chain<?> chain = (Chain<?>) o; - - if (!componentList.equals(chain.componentList)) return false; - if (!id.equals(chain.id)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = componentList.hashCode(); - result = 31 * result + id.hashCode(); - return result; - } -} diff --git a/processing/src/main/java/com/yahoo/component/chain/ChainedComponent.java b/processing/src/main/java/com/yahoo/component/chain/ChainedComponent.java deleted file mode 100644 index 7e0eb8b72ec..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/ChainedComponent.java +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain; - -import com.yahoo.component.AbstractComponent; -import com.yahoo.component.ComponentId; -import com.yahoo.component.chain.dependencies.After; -import com.yahoo.component.chain.dependencies.Before; -import com.yahoo.component.chain.dependencies.Dependencies; -import com.yahoo.component.chain.dependencies.Provides; - -import java.lang.annotation.Annotation; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * Component with dependencies. - * - * @author Tony Vaagenes - */ -public abstract class ChainedComponent extends AbstractComponent { - - /** The immutable set of dependencies of this. NOTE: the default is only for unit testing. */ - private Dependencies dependencies = getDefaultAnnotatedDependencies(); - - public ChainedComponent(ComponentId id) { - super(id); - } - - protected ChainedComponent() {} - - /** - * Called by the container to assign the full set of dependencies to this class (configured and declared). - * This is called once before this is started. - * @param dependencies The configured dependencies, that this method will merge with annotated dependencies. - */ - public void initDependencies(Dependencies dependencies) { - this.dependencies = dependencies.union(getDefaultAnnotatedDependencies()); - } - - /** Returns the configured and declared dependencies of this chainedcomponent */ - public Dependencies getDependencies() { return dependencies; } - - /** This method is here only for legacy reasons, do not override. */ - protected Dependencies getDefaultAnnotatedDependencies() { - Dependencies dependencies = getAnnotatedDependencies(com.yahoo.yolean.chain.Provides.class, com.yahoo.yolean.chain.Before.class, com.yahoo.yolean.chain.After.class); - Dependencies legacyDependencies = getAnnotatedDependencies(Provides.class, Before.class, After.class); - - return dependencies.union(legacyDependencies); - } - - /** - * @param providesClass The annotation class representing 'provides'. - * @param beforeClass The annotation class representing 'before'. - * @param afterClass The annotation class representing 'after'. - * @return a new {@link Dependencies} created from the annotations given in this component's class. - */ - protected Dependencies getAnnotatedDependencies(Class<? extends Annotation> providesClass, - Class<? extends Annotation> beforeClass, - Class<? extends Annotation> afterClass) { - return new Dependencies( - allOf(getSymbols(this, providesClass), this.getClass().getSimpleName(), this.getClass().getName()), - getSymbols(this, beforeClass), - getSymbols(this, afterClass)); - } - - // TODO: move to vespajlib. - private static List<String> allOf(List<String> symbols, String... otherSymbols) { - List<String> result = new ArrayList<>(symbols); - result.addAll(Arrays.asList(otherSymbols)); - return result; - } - - - private static List<String> getSymbols(ChainedComponent component, Class<? extends Annotation> annotationClass) { - List<String> result = new ArrayList<>(); - - result.addAll(annotationSymbols(component, annotationClass)); - return result; - } - - private static Collection<String> annotationSymbols(ChainedComponent component, Class<? extends Annotation> annotationClass) { - - try { - Annotation annotation = component.getClass().getAnnotation(annotationClass); - if (annotation != null) { - Object values = annotationClass.getMethod("value").invoke(annotation); - return Arrays.asList((String[])values); - } - return Collections.emptyList(); - - } catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/ChainsConfigurer.java b/processing/src/main/java/com/yahoo/component/chain/ChainsConfigurer.java deleted file mode 100644 index 969c1c7d66a..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/ChainsConfigurer.java +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain; - -import com.yahoo.component.ComponentSpecification; -import com.yahoo.component.chain.model.ChainSpecification; -import com.yahoo.component.chain.model.ChainedComponentModel; -import com.yahoo.component.chain.model.ChainsModel; -import com.yahoo.component.provider.ComponentRegistry; -import com.yahoo.config.ConfigurationRuntimeException; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -/** - * Configures a registry of chains. - * - * @author bratseth - * @author gjoranv - */ -public class ChainsConfigurer { - - public static <COMPONENT extends ChainedComponent> void prepareChainRegistry( - ComponentRegistry<Chain<COMPONENT>> registry, - ChainsModel model, - ComponentRegistry<COMPONENT> allComponents) { - - initDependencies(model, allComponents); - instantiateChains(registry, model, allComponents); - } - - private static <COMPONENT extends ChainedComponent> void initDependencies( - ChainsModel model, - ComponentRegistry<COMPONENT> allComponents) { - - for (ChainedComponentModel componentModel : model.allComponents()) { - COMPONENT component = getComponentOrThrow(allComponents, componentModel.getComponentId().toSpecification()); - component.initDependencies(componentModel.dependencies); - } - } - - private static <COMPONENT extends ChainedComponent> COMPONENT getComponentOrThrow( - ComponentRegistry<COMPONENT> registry, - ComponentSpecification specification) { - - COMPONENT component = registry.getComponent(specification); - if (component == null) { - throw new ConfigurationRuntimeException("No such component '" + specification + "'"); - } - - return component; - } - - private static <COMPONENT extends ChainedComponent> void instantiateChains( - ComponentRegistry<Chain<COMPONENT>> chainRegistry, - ChainsModel model, - ComponentRegistry<COMPONENT> allComponents) { - - for (ChainSpecification chain : model.allChainsFlattened()) { - try { - Chain<COMPONENT> componentChain = new Chain<>(chain.componentId, - resolveComponents(chain.componentReferences, allComponents), - chain.phases()); - chainRegistry.register(chain.componentId, componentChain); - } catch (Exception e) { - throw new ConfigurationRuntimeException("Invalid chain '" + chain.componentId + "'", e); - } - } - } - - private static <T extends ChainedComponent> List<T> resolveComponents( - Set<ComponentSpecification> componentSpecifications, - ComponentRegistry<T> allComponents) { - - List<T> components = new ArrayList<>(componentSpecifications.size()); - for (ComponentSpecification componentSpec : componentSpecifications) { - T component = getComponentOrThrow(allComponents, componentSpec); - components.add(component); - } - return components; - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/Phase.java b/processing/src/main/java/com/yahoo/component/chain/Phase.java deleted file mode 100644 index 64584450c23..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/Phase.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain; - -import com.yahoo.component.chain.dependencies.Dependencies; - -import java.util.Set; -import java.util.TreeSet; - -/** - * Used for many to many constraints on searcher ordering. Immutable. - * - * @author Tony Vaagenes - */ -public class Phase { - - public final Dependencies dependencies; - - public Phase(String name, Set<String> before, Set<String> after) { - dependencies = new Dependencies(provides(name), before, after); - } - - public Phase(String name, Dependencies dependencies) { - this(name, dependencies.before(), dependencies.after()); - assert(dependencies.provides().isEmpty()); - } - - private Set<String> provides(String name) { - Set<String> provides = new TreeSet<>(); - provides.add(name); - return provides; - } - - public String getName() { - return dependencies.provides().iterator().next(); - } - - public Set<String> before() { - return dependencies.before(); - } - - public Set<String> after() { - return dependencies.after(); - } - - public Phase union(Phase phase) { - assert(getName().equals(phase.getName())); - - Dependencies union = dependencies.union(phase.dependencies); - return new Phase(getName(), union.before(), union.after()); - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/After.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/After.java deleted file mode 100644 index be10c82d2e1..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/After.java +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies; - -import java.lang.annotation.*; - -/** - * Components or phases providing names contained in this list must be - * placed earlier in the chain than the component that is annotated. - * <p> - * See {@link com.yahoo.component.chain.dependencies.ordering.ChainBuilder} - * for dependency handling information. - * - * @author Tony Vaagenes - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Inherited -public @interface After { - - String[] value() default {}; - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/Before.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/Before.java deleted file mode 100644 index 4542140c574..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/Before.java +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies; - -import java.lang.annotation.*; - -/** - * Components or phases providing names contained in this list must be - * placed later in the chain than the component that is annotated. - * <p> - * See {@link com.yahoo.component.chain.dependencies.ordering.ChainBuilder} - * for dependency handling information. - * - * @author Tony Vaagenes - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Inherited -public @interface Before { - - String[] value() default {}; - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/Dependencies.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/Dependencies.java deleted file mode 100644 index 2fd0dc9ea84..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/Dependencies.java +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies; - -import java.util.*; - -import com.google.common.collect.ImmutableSet; - -/** - * Constraints for ordering ChainedComponents in chains. Immutable. - * - * @author Tony Vaagenes - */ -public class Dependencies { - - private final Set<String> provides; - private final Set<String> before; - private final Set<String> after; - - /** - * Create from collections of strings, typically from config. - */ - public Dependencies(Collection<String> provides, Collection<String> before, Collection<String> after) { - this.provides = immutableSet(provides); - this.before = immutableSet(before); - this.after = immutableSet(after); - } - - public static Dependencies emptyDependencies() { - return new Dependencies(null, null, null); - } - - public Dependencies union(Dependencies dependencies) { - return new Dependencies( - union(provides, dependencies.provides), - union(before, dependencies.before), - union(after, dependencies.after)); - } - - private Set<String> immutableSet(Collection<String> set) { - if (set == null) return ImmutableSet.of(); - return ImmutableSet.copyOf(set); - } - - private Set<String> union(Set<String> s1, Set<String> s2) { - Set<String> result = new LinkedHashSet<>(s1); - result.addAll(s2); - return result; - } - - @Override - public String toString() { - return "Dependencies{" + - "provides=" + provides + - ", before=" + before + - ", after=" + after + - '}'; - } - - public Set<String> provides() { - return provides; - } - - public Set<String> before() { - return before; - } - - public Set<String> after() { - return after; - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/Provides.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/Provides.java deleted file mode 100644 index b014681c469..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/Provides.java +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies; - -import java.lang.annotation.*; - -/** - * Mark this component as providing some named functionality. - * Other components can then mark themselves as "before" and "after" the string provided here, - * to impose constraints on ordering. - * - * @author Tony Vaagenes - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Inherited -public @interface Provides { - - String[] value() default {}; - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilder.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilder.java deleted file mode 100644 index beafe7d2b98..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilder.java +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.yahoo.component.ComponentId; -import com.yahoo.component.chain.Chain; -import com.yahoo.component.chain.ChainedComponent; -import com.yahoo.component.chain.Phase; - - -/** - * Given a set of phases and a set of components, - * a ordered list of components satisfying the dependencies is given if possible. - * <p> - * The phase list implicitly defines the ordering: - * {@literal if i < j : p_i before p_j where i,j are valid indexes of the phrase list p.} - * <p> - * If multiple components provide the same name, ALL the components providing - * the same name must be placed earlier/later than an entity depending on - * that name. - * <p> - * A warning will be logged if multiple components of different types provides the - * same name. A component can not provide the same name as a phase. - * - * @author Tony Vaagenes - */ -public class ChainBuilder<T extends ChainedComponent> { - - private final ComponentId id; - private int numComponents = 0; - private int priority = 1; - - private Map<String, NameProvider> nameProviders = - new LinkedHashMap<>(); - - private Node allPhase; - - public ChainBuilder(ComponentId id) { - this.id = id; - allPhase = addPhase(new Phase("*", set("*"), Collections.<String>emptySet())); - } - - private Set<String> set(String... s) { - return new HashSet<>(Arrays.asList(s)); - } - - public PhaseNameProvider addPhase(Phase phase) { - NameProvider nameProvider = nameProviders.get(phase.getName()); - if (nameProvider instanceof ComponentNameProvider) { - throw new ConflictingNodeTypeException("Cannot add phase '" + phase.getName() + "' as it is already provided by " + nameProvider); - } - PhaseNameProvider phaseNameProvider; - if(nameProvider == null) { - phaseNameProvider = new PhaseNameProvider(phase.getName(), priority++); - } else { - phaseNameProvider = (PhaseNameProvider) nameProvider; - } - nameProviders.put(phase.getName(), phaseNameProvider); - for(String before : phase.before()) { - phaseNameProvider.before(getPhaseNameProvider(before)); - } - for(String after : phase.after()) { - getPhaseNameProvider(after).before(phaseNameProvider); - } - - return phaseNameProvider; - } - - public void addComponent(ChainedComponent component) { - ComponentNode<ChainedComponent> componentNode = new ComponentNode<>(component, priority++); - - ensureProvidesNotEmpty(component); - for (String name : component.getDependencies().provides()) { - NameProvider nameProvider = getNameProvider(name); - - nameProvider.addNode(componentNode); - } - - for (String before : component.getDependencies().before()) { - componentNode.before(getNameProvider(before)); - } - - for (String after : component.getDependencies().after()) { - getNameProvider(after).before(componentNode); - } - - ++numComponents; - } - - //destroys this dependency handler in the process - @SuppressWarnings("unchecked") - public Chain<T> orderNodes() { - List<T> chain = new ArrayList<>(); - OrderedReadyNodes readyNodes = getReadyNodes(); - - while (!readyNodes.isEmpty() || popAllPhase(readyNodes) ) { - Node candidate = readyNodes.pop(); - - candidate.removed(readyNodes); - - if ( candidate instanceof ComponentNode) - chain.add(((ComponentNode<T>)candidate).getComponent()); - } - - if ( chain.size() != numComponents) - throw new CycleDependenciesException(nameProviders); - - //prevent accidental reuse - nameProviders = null; - - return new Chain<>(id, chain); - } - - private void ensureProvidesNotEmpty(ChainedComponent component) { - if (component.getDependencies().provides().isEmpty()) { - throw new RuntimeException("The component " + component.getId() + " did not provide anything."); - } - } - - private Node getPhaseNameProvider(String name) { - NameProvider nameProvider = nameProviders.get(name); - if (nameProvider != null) - return nameProvider; - else { - nameProvider = new PhaseNameProvider(name, priority++); - nameProviders.put(name, nameProvider); - return nameProvider; - } - } - - private boolean popAllPhase(OrderedReadyNodes readyNodes) { - if (allPhase == null) { - return false; - } else { - Node phase = allPhase; - allPhase = null; - phase.removed(readyNodes); - return !readyNodes.isEmpty(); - } - } - - private NameProvider getNameProvider(String name) { - NameProvider nameProvider = nameProviders.get(name); - if (nameProvider != null) - return nameProvider; - else { - nameProvider = new ComponentNameProvider(name); - nameProviders.put(name, nameProvider); - return nameProvider; - } - } - - private OrderedReadyNodes getReadyNodes() { - OrderedReadyNodes readyNodes = new OrderedReadyNodes(); - for (Node node : nameProviders.values() ) { - if (node.ready()) - readyNodes.add(node); - } - return readyNodes; - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ComponentNameProvider.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ComponentNameProvider.java deleted file mode 100644 index b9e8f56d15c..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ComponentNameProvider.java +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.logging.Logger; - -import com.yahoo.component.chain.ChainedComponent; - -/** - * A set of components providing a given name. - * - * @author Tony Vaagenes - */ -class ComponentNameProvider extends NameProvider { - - @SuppressWarnings("rawtypes") - private Set<ComponentNode> nodes = new LinkedHashSet<>(); - private Logger logger = Logger.getLogger(getClass().getName()); - - ComponentNameProvider(String name) { - super(name, 0); - } - - protected void addNode(@SuppressWarnings("rawtypes") ComponentNode componentNode) { - if (nodes.add(componentNode)) - componentNode.notifyAfter(); - } - - @Override - protected void handleRemoved(OrderedReadyNodes readyNodes) { - for (Node node: nodes) { - /* - All providers must be run before dependencies are run. - Adding these dependencies just in time improves dot output - for the purpose of finding cycles manually. - */ - for (Node afterThis : nodesAfterThis) { - node.before(afterThis); - } - node.beforeRemoved(readyNodes); - } - } - - @Override - int classPriority() { - return 1; - } - - @Override - public String toString() { - StringBuilder b=new StringBuilder("components ["); - for (@SuppressWarnings("rawtypes") - Iterator<ComponentNode> i=nodes.iterator(); i.hasNext(); ) { - b.append(i.next().getComponent().getId()); - if (i.hasNext()) - b.append(", "); - } - b.append("]"); - return b.toString(); - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ComponentNode.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ComponentNode.java deleted file mode 100644 index 2bc81542d52..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ComponentNode.java +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - -import com.yahoo.component.chain.ChainedComponent; - -/** - * A node representing a given component. - * - * @see Node - * @author Tony Vaagenes - */ -class ComponentNode<T extends ChainedComponent> extends Node { - - private T component; - - public ComponentNode(T component, int priority) { - super(priority); - this.component = component; - } - - T getComponent() { - return component; - } - - @Override - protected String dotName() { - //TODO: config dependent name - return component.getClass().getSimpleName(); - } - - @Override - int classPriority() { - return 2; - } - -} - diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ConflictingNodeTypeException.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ConflictingNodeTypeException.java deleted file mode 100644 index edf4a119e5c..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/ConflictingNodeTypeException.java +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - -/** - * Thrown if a searcher provides the same name as a phase. - * - * @author Tony Vaagenes - */ -@SuppressWarnings("serial") -public class ConflictingNodeTypeException extends RuntimeException { - - public ConflictingNodeTypeException(String message) { - super(message); - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/CycleDependenciesException.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/CycleDependenciesException.java deleted file mode 100644 index 40a78030c41..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/CycleDependenciesException.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Signals that the dependency graph contains cycles. A DOT language - * representation of the cycle is available to help solve the problem (<a - * href="http://graphviz.org/">GraphViz</a>). - * - * @author Tony Vaagenes - */ -@SuppressWarnings("serial") -public class CycleDependenciesException extends RuntimeException { - - public Map<String, NameProvider> cycleNodes; - - CycleDependenciesException(Map<String, NameProvider> cycleNodes) { - super("The following set of dependencies lead to a cycle:\n" - + createDotString(cycleNodes)); - this.cycleNodes = cycleNodes; - } - - private static String createDotString(Map<String, NameProvider> cycleNodes) { - StringBuilder res = new StringBuilder(); - res.append("digraph dependencyGraph {\n"); - - Set<Node> used = new HashSet<>(); - for (Node node: cycleNodes.values()) { - if (!node.ready()) - node.dotDependenciesString(res, used); - - } - res.append("}"); - return res.toString(); - } - - - public String dotString() { - return createDotString(cycleNodes); - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/NameProvider.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/NameProvider.java deleted file mode 100644 index 773b6d07035..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/NameProvider.java +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - -/** - * A node containing nodes providing a given name. - * - * @author Tony Vaagenes - */ -abstract class NameProvider extends Node { - - final String name; - - public NameProvider(String name, int priority) { - super(priority); - this.name = name; - } - - protected abstract void addNode(ComponentNode<?> node); - - protected String name() { - return name; - } - - @Override - protected String dotName() { - return name; - } - -} - - diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/Node.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/Node.java deleted file mode 100644 index da652fde614..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/Node.java +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - -import java.util.HashSet; -import java.util.Set; - -/** - * A node in a dependency graph. - * - * Dependencies must declared as follows: - * a.before(b) , where a,b are nodes. - * - * The following dependencies are currently allowed: - * searcher.before(name) - * name.before(searcher) - * searcher1.before(searcher2) - * - * Where name designates a NameProvider( either a phase or a set of searchers). - * - * @author Tony Vaagenes -*/ -abstract class Node { - //How this node should be prioritized if its compared with a node of the same class, see class priority. - final int priority; - - private int numNodesBeforeThis = 0; - Set<Node> nodesAfterThis = new HashSet<>(); - - public Node(int priority) { - this.priority = priority; - } - - protected void before(Node node) { - if (nodesAfterThis.add(node)) { - node.notifyAfter(); - } - } - - void notifyAfter() { - ++numNodesBeforeThis; - } - - void removed(OrderedReadyNodes readyNodes) { - handleRemoved(readyNodes); - for (Node node: nodesAfterThis) { - node.beforeRemoved(readyNodes); - } - } - - void beforeRemoved(OrderedReadyNodes readyNodes) { - --numNodesBeforeThis; - - if (ready()) { - readyNodes.add(this); - } - } - - boolean ready() { - return numNodesBeforeThis == 0; - } - - protected void handleRemoved(OrderedReadyNodes readyNodes) {} - - void dotDependenciesString(StringBuilder s, Set<Node> used) { - if (used.contains(this)) - return; - used.add(this); - - for (Node afterNode : nodesAfterThis) { - String indent = " "; - s.append(indent); - s.append(dotName()).append(" -> ").append(afterNode.dotName()) - .append('\n'); - afterNode.dotDependenciesString(s, used); - } - } - - abstract protected String dotName(); - - /* - * Ensures that PhaseNameProviders < ComponentNameProviders < ComponentNodes - * The regular priority is only considered if the class priorities are equal. - */ - abstract int classPriority(); -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/OrderedReadyNodes.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/OrderedReadyNodes.java deleted file mode 100644 index d8fb0d7f584..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/OrderedReadyNodes.java +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - - -import java.util.Comparator; -import java.util.PriorityQueue; - -/** - * Ensures that Searchers are ordered deterministically. - * - * @author Tony Vaagenes - */ -class OrderedReadyNodes { - - private class PriorityComparator implements Comparator<Node> { - @Override - public int compare(Node lhs, Node rhs) { - int result = Integer.valueOf(lhs.classPriority()).compareTo(rhs.classPriority()); - - return result != 0 ? - result : - Integer.valueOf(lhs.priority).compareTo(rhs.priority); - } - } - - final private PriorityQueue<Node> nodes = new PriorityQueue<>(10, new PriorityComparator()); - - public void add(Node node) { - nodes.add(node); - } - - public Node pop() { - return nodes.poll(); - } - - public boolean isEmpty() { - return nodes.isEmpty(); - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/PhaseNameProvider.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/PhaseNameProvider.java deleted file mode 100644 index f99a9191150..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/ordering/PhaseNameProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - -/** - * A phase providing a given name. - * - * @author Tony Vaagenes - */ -class PhaseNameProvider extends NameProvider { - - public PhaseNameProvider(String name, int priority) { - super(name,priority); - } - - protected void addNode(ComponentNode<?> newNode) { - throw new ConflictingNodeTypeException("Both a phase and a searcher provides the name '" + name + "'"); - } - - @Override - public String toString() { - return getClass().getSimpleName() + "[name = " + name + "]"; - } - - - @Override - int classPriority() { - return 0; - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/dependencies/package-info.java b/processing/src/main/java/com/yahoo/component/chain/dependencies/package-info.java deleted file mode 100644 index acb8e4b011f..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/dependencies/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -@PublicApi -package com.yahoo.component.chain.dependencies; - -import com.yahoo.api.annotations.PublicApi; -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/processing/src/main/java/com/yahoo/component/chain/model/ChainSpecification.java b/processing/src/main/java/com/yahoo/component/chain/model/ChainSpecification.java deleted file mode 100644 index 53f5c5d1e06..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/model/ChainSpecification.java +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.model; - -import com.google.common.collect.ImmutableSet; -import com.yahoo.component.ComponentId; -import com.yahoo.component.ComponentSpecification; -import com.yahoo.component.chain.Phase; - -import java.util.*; - -/** - * Specifies how the components should be selected to create a chain. Immutable. - * - * @author Tony Vaagenes - */ -public class ChainSpecification { - - public static class Inheritance { - public final Set<ComponentSpecification> chainSpecifications; - public final Set<ComponentSpecification> excludedComponents; - - Inheritance flattened() { - return new Inheritance(Collections.<ComponentSpecification>emptySet(), excludedComponents); - } - - public Inheritance(Set<ComponentSpecification> inheritedChains, Set<ComponentSpecification> excludedComponents) { - this.chainSpecifications = immutableCopy(inheritedChains); - this.excludedComponents = immutableCopy(excludedComponents); - } - - public Inheritance addInherits(Collection<ComponentSpecification> inheritedChains) { - Set<ComponentSpecification> newChainSpecifications = - new LinkedHashSet<>(chainSpecifications); - newChainSpecifications.addAll(inheritedChains); - return new Inheritance(newChainSpecifications, excludedComponents); - } - } - - public final ComponentId componentId; - public final Inheritance inheritance; - final Map<String, Phase> phases; - public final Set<ComponentSpecification> componentReferences; - - public ChainSpecification(ComponentId componentId, Inheritance inheritance, - Collection<Phase> phases, - Set<ComponentSpecification> componentReferences) { - assertNotNull(componentId, inheritance, phases, componentReferences); - - if (componentsByName(componentReferences).size() != componentReferences.size()) - throw new RuntimeException("Two components with the same name are specified in '" + componentId + - "', but name must be unique inside a given chain."); - - this.componentId = componentId; - this.inheritance = inheritance; - this.phases = copyPhasesImmutable(phases); - this.componentReferences = ImmutableSet.copyOf( - filterByComponentSpecification(componentReferences, inheritance.excludedComponents)); - } - - public ChainSpecification addComponents(Collection<ComponentSpecification> componentSpecifications) { - Set<ComponentSpecification> newComponentReferences = new LinkedHashSet<>(componentReferences); - newComponentReferences.addAll(componentSpecifications); - - return new ChainSpecification(componentId, inheritance, phases(), newComponentReferences); - } - - public ChainSpecification addInherits(Collection<ComponentSpecification> inheritedChains) { - return new ChainSpecification(componentId, inheritance.addInherits(inheritedChains), phases(), componentReferences); - } - - public ChainSpecification setComponentId(ComponentId newComponentId) { - return new ChainSpecification(newComponentId, inheritance, phases(), componentReferences); - } - - public ChainSpecification flatten(Resolver<ChainSpecification> allChainSpecifications) { - Deque<ComponentId> path = new ArrayDeque<>(); - return flatten(allChainSpecifications, path); - } - - /** - * @param allChainSpecifications resolves ChainSpecifications from ComponentSpecifications - * as given in the inheritance fields. - * @param path tracks which chains are used in each recursive invocation of flatten, used for detecting cycles. - * @return ChainSpecification directly containing all the component references and phases of the inherited chains. - */ - private ChainSpecification flatten(Resolver<ChainSpecification> allChainSpecifications, - Deque<ComponentId> path) { - path.push(componentId); - - //if this turns out to be a bottleneck(which I seriously doubt), please add memoization - Map<String, ComponentSpecification> resultingComponents = componentsByName(componentReferences); - Map<String, Phase> resultingPhases = new LinkedHashMap<>(phases); - - - for (ComponentSpecification inheritedChainSpecification : inheritance.chainSpecifications) { - ChainSpecification inheritedChain = - resolveChain(path, allChainSpecifications, inheritedChainSpecification). - flatten(allChainSpecifications, path); - - mergeInto(resultingComponents, - filterByComponentSpecification( - filterByName(inheritedChain.componentReferences, names(componentReferences)), - inheritance.excludedComponents)); - mergeInto(resultingPhases, inheritedChain.phases); - } - - path.pop(); - return new ChainSpecification(componentId, inheritance.flattened(), resultingPhases.values(), - new LinkedHashSet<>(resultingComponents.values())); - } - - public Collection<Phase> phases() { - return phases.values(); - } - - private static <T> Set<T> immutableCopy(Set<T> set) { - if (set == null) return ImmutableSet.of(); - return ImmutableSet.copyOf(set); - } - - private static Map<String, Phase> copyPhasesImmutable(Collection<Phase> phases) { - Map<String, Phase> result = new LinkedHashMap<>(); - for (Phase phase : phases) { - Phase oldValue = result.put(phase.getName(), phase); - if (oldValue != null) - throw new RuntimeException("Two phases with the same name " + phase.getName() + " present in the same scope."); - } - return Collections.unmodifiableMap(result); - } - - private static void assertNotNull(Object... objects) { - for (Object o : objects) { - assert(o != null); - } - } - - static Map<String, ComponentSpecification> componentsByName(Set<ComponentSpecification> componentSpecifications) { - Map<String, ComponentSpecification> componentsByName = new LinkedHashMap<>(); - - for (ComponentSpecification component : componentSpecifications) - componentsByName.put(component.getName(), component); - - return componentsByName; - } - - private static void mergeInto(Map<String, ComponentSpecification> resultingComponents, - Set<ComponentSpecification> components) { - for (ComponentSpecification component : components) { - String name = component.getName(); - if (resultingComponents.containsKey(name)) { - resultingComponents.put(name, component.intersect(resultingComponents.get(name))); - } else { - resultingComponents.put(name, component); - } - } - } - - - private static void mergeInto(Map<String, Phase> resultingPhases, Map<String, Phase> phases) { - for (Phase phase : phases.values()) { - String name = phase.getName(); - if (resultingPhases.containsKey(name)) { - phase = phase.union(resultingPhases.get(name)); - } - resultingPhases.put(name, phase); - } - } - - private static Set<String> names(Set<ComponentSpecification> components) { - Set<String> names = new LinkedHashSet<>(); - for (ComponentSpecification component : components) { - names.add(component.getName()); - } - return names; - } - - private static Set<ComponentSpecification> filterByComponentSpecification(Set<ComponentSpecification> components, Set<ComponentSpecification> excludes) { - Set<ComponentSpecification> result = new LinkedHashSet<>(); - for (ComponentSpecification component : components) { - if (!matches(component, excludes)) - result.add(component); - } - - return result; - } - - private static Set<ComponentSpecification> filterByName(Set<ComponentSpecification> components, Set<String> names) { - Set<ComponentSpecification> result = new LinkedHashSet<>(); - for (ComponentSpecification component : components) { - if (!names.contains(component.getName())) - result.add(component); - } - return result; - } - - private static boolean matches(ComponentSpecification component, Set<ComponentSpecification> excludes) { - ComponentId id = component.toId().withoutNamespace(); - for (ComponentSpecification exclude : excludes) { - if (exclude.matches(id)) { - return true; - } - } - return false; - } - - private ChainSpecification resolveChain(Deque<ComponentId> path, - Resolver<ChainSpecification> allChainSpecifications, - ComponentSpecification chainSpecification) { - - ChainSpecification chain = allChainSpecifications.resolve(chainSpecification); - if (chain == null) { - throw new RuntimeException("Missing chain '" + chainSpecification + "'."); - } else if (path.contains(chain.componentId)) { - throw new RuntimeException("The chain " + chain.componentId + " inherits(possibly indirectly) from itself."); - } else { - return chain; - } - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/model/ChainedComponentModel.java b/processing/src/main/java/com/yahoo/component/chain/model/ChainedComponentModel.java deleted file mode 100644 index 196c0046c47..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/model/ChainedComponentModel.java +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.model; - -import com.yahoo.container.bundle.BundleInstantiationSpecification; -import com.yahoo.component.chain.dependencies.Dependencies; -import com.yahoo.osgi.provider.model.ComponentModel; - -/** - * Describes how a chained component should be created. Immutable. - * - * @author Arne Bergene Fossaa - * @author Tony Vaagenes - */ -public class ChainedComponentModel extends ComponentModel { - public final Dependencies dependencies; - - public ChainedComponentModel(BundleInstantiationSpecification bundleInstantiationSpec, Dependencies dependencies, - String configId) { - super(bundleInstantiationSpec, configId); - assert(dependencies != null); - - this.dependencies = dependencies; - } - - public ChainedComponentModel(BundleInstantiationSpecification bundleInstantiationSpec, Dependencies dependencies) { - this(bundleInstantiationSpec, dependencies, null); - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/model/ChainsModel.java b/processing/src/main/java/com/yahoo/component/chain/model/ChainsModel.java deleted file mode 100644 index 08cb6b7ccfd..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/model/ChainsModel.java +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.model; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; - -import com.yahoo.component.ComponentId; -import com.yahoo.component.ComponentSpecification; -import com.yahoo.component.provider.ComponentRegistry; - -/** - * A model of how the chains and components should be created. - * - * @author Tony Vaagenes - */ -public class ChainsModel { - - private final ComponentRegistry<ComponentAdaptor<ChainSpecification>> chainSpecifications = new ComponentRegistry<>(); - private final ComponentRegistry<ComponentAdaptor<ChainedComponentModel>> componentModels = new ComponentRegistry<>(); - - public void register(ChainSpecification chainSpecification) { - chainSpecifications.register(chainSpecification.componentId, - ComponentAdaptor.create(chainSpecification.componentId, chainSpecification)); - } - - public void register(ComponentId globalComponentId, ChainedComponentModel componentModel) { - assert (componentModel.getComponentId().withoutNamespace().equals( - globalComponentId.withoutNamespace())); - - componentModels.register(globalComponentId, ComponentAdaptor.create(globalComponentId, componentModel)); - } - - public Collection<ChainedComponentModel> allComponents() { - Collection<ChainedComponentModel> components = new ArrayList<>(); - for (ComponentAdaptor<ChainedComponentModel> component : componentModels.allComponents()) { - components.add(component.model); - } - return components; - } - - public Collection<ChainSpecification> allChainsFlattened() { - Resolver<ChainSpecification> resolver = new Resolver<ChainSpecification>() { - @Override - public ChainSpecification resolve(ComponentSpecification componentSpecification) { - ComponentAdaptor<ChainSpecification> spec = chainSpecifications.getComponent(componentSpecification); - return (spec==null) ? null : spec.model; - } - }; - - Collection<ChainSpecification> chains = new ArrayList<>(); - for (ComponentAdaptor<ChainSpecification> chain : chainSpecifications.allComponents()) { - chains.add(chain.model.flatten(resolver)); - } - return chains; - } - - public void validate() { - allChainsFlattened(); - for (ComponentAdaptor<ChainSpecification> chain : chainSpecifications.allComponents()) { - validate(chain.model); - } - } - - private void validate(ChainSpecification model) { - for (ComponentSpecification componentSpec : model.componentReferences) { - if (componentModels.getComponent(componentSpec) == null) { - throw new RuntimeException("No component matching the component specification " + componentSpec); - } - } - } - - // For testing - Map<ComponentId, ComponentAdaptor<ChainSpecification>> chainSpecifications() { - return chainSpecifications.allComponentsById(); - } - - // For testing - Map<ComponentId, ComponentAdaptor<ChainedComponentModel>> componentModels() { - return componentModels.allComponentsById(); - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/model/ChainsModelBuilder.java b/processing/src/main/java/com/yahoo/component/chain/model/ChainsModelBuilder.java deleted file mode 100644 index 5f9f2daa177..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/model/ChainsModelBuilder.java +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.model; - -import java.util.*; - -import com.yahoo.container.bundle.BundleInstantiationSpecification; -import com.yahoo.component.ComponentId; -import com.yahoo.component.ComponentSpecification; - -import com.yahoo.component.chain.dependencies.Dependencies; -import com.yahoo.component.chain.Phase; -import com.yahoo.container.core.ChainsConfig; - -/** - * Builds a chains model from config. - * - * @author Tony Vaagenes - */ -public class ChainsModelBuilder { - - public static ChainsModel buildFromConfig(ChainsConfig chainsConfig) { - ChainsModel model = createChainsModel(chainsConfig); - - for (ChainsConfig.Components component : chainsConfig.components()) { - ChainedComponentModel componentModel = createChainedComponentModel(component); - model.register(componentModel.getComponentId(), componentModel); - } - return model; - } - - private static ChainedComponentModel createChainedComponentModel(ChainsConfig.Components component) { - return new ChainedComponentModel( - new BundleInstantiationSpecification(new ComponentSpecification(component.id()), null, null), - createDependencies( - component.dependencies().provides(), - component.dependencies().before(), - component.dependencies().after()), - null); - } - - private static ChainsModel createChainsModel(ChainsConfig chainsConfig) { - ChainsModel model = new ChainsModel(); - for (ChainsConfig.Chains chainConfig : chainsConfig.chains()) { - model.register( - createChainSpecification(chainConfig)); - } - return model; - } - - private static ChainSpecification createChainSpecification(ChainsConfig.Chains config) { - return new ChainSpecification(new ComponentId(config.id()), - createInheritance(config.inherits(), config.excludes()), - createPhases(config.phases()), - createComponentSpecifications(config.components())); - } - - private static Collection<Phase> createPhases(List<ChainsConfig.Chains.Phases> phases) { - Collection<Phase> result = new ArrayList<>(); - for (ChainsConfig.Chains.Phases phase : phases) { - result.add( - new Phase(phase.id(), createDependencies(null, phase.before(), phase.after()))); - } - return result; - } - - private static Dependencies createDependencies(List<String> provides, - List<String> before, List<String> after) { - return new Dependencies(provides, before, after); - } - - private static Set<ComponentSpecification> createComponentSpecifications(List<String> stringSpecs) { - Set<ComponentSpecification> specifications = new LinkedHashSet<>(); - for (String stringSpec : stringSpecs) { - specifications.add(new ComponentSpecification(stringSpec)); - } - return specifications; - } - - private static ChainSpecification.Inheritance createInheritance(List<String> inherit, List<String> exclude) { - return new ChainSpecification.Inheritance( - createComponentSpecifications(inherit), - createComponentSpecifications(exclude)); - } -} diff --git a/processing/src/main/java/com/yahoo/component/chain/model/ComponentAdaptor.java b/processing/src/main/java/com/yahoo/component/chain/model/ComponentAdaptor.java deleted file mode 100644 index 2961768a7de..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/model/ComponentAdaptor.java +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.model; - -import com.yahoo.component.AbstractComponent; -import com.yahoo.component.ComponentId; - -/** - * For using non-component model classes with ComponentRegistry. - * - * @author Tony Vaagenes - */ -public final class ComponentAdaptor<T> extends AbstractComponent { - - public final T model; - - @SuppressWarnings("deprecation") - public ComponentAdaptor(ComponentId globalComponentId, T model) { - super(globalComponentId); - this.model = model; - } - - public static <T> ComponentAdaptor<T> create(ComponentId globalComponentId, T model) { - return new ComponentAdaptor<>(globalComponentId, model); - } - - // For testing - T model() { - return model; - } - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/model/Resolver.java b/processing/src/main/java/com/yahoo/component/chain/model/Resolver.java deleted file mode 100644 index 15acff0db0b..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/model/Resolver.java +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.model; - -import com.yahoo.component.ComponentSpecification; - -/** - * Maps component specifications to matching instances. - * - * @author Tony Vaagenes - */ -public interface Resolver<T> { - - T resolve(ComponentSpecification componentSpecification); - -} diff --git a/processing/src/main/java/com/yahoo/component/chain/model/package-info.java b/processing/src/main/java/com/yahoo/component/chain/model/package-info.java deleted file mode 100644 index 3d84de24df8..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/model/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -package com.yahoo.component.chain.model; - -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/processing/src/main/java/com/yahoo/component/chain/package-info.java b/processing/src/main/java/com/yahoo/component/chain/package-info.java deleted file mode 100644 index bfa18cf331c..00000000000 --- a/processing/src/main/java/com/yahoo/component/chain/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -@PublicApi -package com.yahoo.component.chain; - -import com.yahoo.api.annotations.PublicApi; -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/processing/src/main/java/com/yahoo/processing/IllegalInputException.java b/processing/src/main/java/com/yahoo/processing/IllegalInputException.java deleted file mode 100644 index 3f1605860ed..00000000000 --- a/processing/src/main/java/com/yahoo/processing/IllegalInputException.java +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing; - -/** - * Thrown on illegal input received from the requesting client. - * Use this instead of the superclass, IllegalArgumentException - * to signal illegal input to the client without causing logging and stack traces, - * - * @author bratseth - */ -public class IllegalInputException extends IllegalArgumentException { - - public IllegalInputException(String message) { - super(message); - } - - public IllegalInputException(Throwable cause) { - super(cause); - } - - public IllegalInputException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/Processor.java b/processing/src/main/java/com/yahoo/processing/Processor.java deleted file mode 100644 index 359244ff9c9..00000000000 --- a/processing/src/main/java/com/yahoo/processing/Processor.java +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing; - -import com.yahoo.component.chain.ChainedComponent; -import com.yahoo.processing.execution.Execution; - -/** - * Superclass of chainable components processing Requests to create Responses. - * <p> - * Processors typically changes the Request and/or the Response. It may also make multiple - * forward requests, in series or parallel, or manufacture the response content itself or by calling - * an external service. - * <p> - * Typical usage: - * <code> - * public class MyProcessor extends Processor { - * - * @Override - * public Response process(Request request, Execution execution) { - * // process the request here - * Response response = execution.process(request); // Pass along to get the Response - * // process (or fill in) Data/DataList items on the response here - * return response; - * } - * - * } - * </code> - * - * @author bratseth - */ -public abstract class Processor extends ChainedComponent { - - /** - * Performs a processing request and returns the response - * - * @return a Response instance - never null - containing the data produced by this processor - * and those it forwards the request to - */ - public abstract Response process(Request request, Execution execution); - - -} diff --git a/processing/src/main/java/com/yahoo/processing/Request.java b/processing/src/main/java/com/yahoo/processing/Request.java deleted file mode 100644 index d6607f136fb..00000000000 --- a/processing/src/main/java/com/yahoo/processing/Request.java +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing; - -import com.yahoo.component.provider.FreezableClass; -import com.yahoo.processing.request.CompoundName; -import com.yahoo.processing.request.ErrorMessage; -import com.yahoo.processing.request.Properties; -import com.yahoo.processing.request.properties.PropertyMap; - -import java.util.ArrayList; -import java.util.List; - -/** - * A generic processing request. - * The request contains a set of properties that are used to communicate information from the client making the - * processing request (e.g http parameters), and as a blackboard to pass information between processors. - * - * @author bratseth - */ -public class Request extends FreezableClass implements Cloneable { - - private Properties properties; - - /** - * The errors encountered while processing this request - */ - private List<ErrorMessage> errors = new ArrayList<>(0); - - /** - * The name of the chain of Processor instances which will be invoked when - * executing a request. - */ - public static final CompoundName CHAIN = new CompoundName("chain"); - - /** - * The name of the request property used in the processing framework to - * store the incoming JDisc request. - */ - public static final CompoundName JDISC_REQUEST = new CompoundName("jdisc.request"); - - /** - * Creates a request with no properties - */ - public Request() { - this(new PropertyMap()); - } - - /** - * Create a request with the given properties. - * This Request gains ownership of the given properties and may edit them in the future. - * - * @param properties the properties owner by this - */ - public Request(Properties properties) { - this.properties = properties; - } - - /** - * Returns the properties set on this request. - * Processors may add properties to send messages to downstream processors. - */ - public Properties properties() { - return properties; - } - - /** - * Returns the list of errors encountered while processing this request, never null. - * This is a live reference to the modifiable list of errors of this. - */ - public List<ErrorMessage> errors() { - return errors; - } - - /** - * Returns a clone of this request. - * <p> - * The properties are logically deeply cloned such that changes to properties in the clone are independent. - * <p> - * The errors of the original request <b>are not</b> cloned into the new instance: - * It will have an empty list of errors. - */ - @Override - public Request clone() { - Request clone = (Request) super.clone(); - clone.properties = properties.clone(); - clone.errors = new ArrayList<>(0); - return clone; - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/Response.java b/processing/src/main/java/com/yahoo/processing/Response.java deleted file mode 100644 index 485513cd0cb..00000000000 --- a/processing/src/main/java/com/yahoo/processing/Response.java +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing; - -import com.google.common.util.concurrent.AbstractFuture; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; -import com.yahoo.component.provider.ListenableFreezableClass; -import com.yahoo.concurrent.SystemTimer; -import com.yahoo.processing.execution.ResponseReceiver; -import com.yahoo.processing.request.CompoundName; -import com.yahoo.processing.request.ErrorMessage; -import com.yahoo.processing.response.ArrayDataList; -import com.yahoo.processing.response.Data; -import com.yahoo.processing.response.DataList; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * A Response to a Request. - * <p> - * A Response contains a list of Data items, which may (through Data implementations) contain payload data and/or - * further nested data lists. - * <p> - * Frameworks built on top of processing may subclass this to create a stricter definition of a response. - * Processors producing Responses should not create subclasses but should instead - * create additional instances/subclasses of Data. Such Processors should always create Response instances by calling - * execution.process(request), which will return an empty Response if there are no further processors in the chain. - * <p> - * Do not cache this as it may hold references to objects that should be garbage collected. - * - * @author bratseth - */ -public class Response extends ListenableFreezableClass { - - private final static CompoundName freezeListenerKey =new CompoundName("processing.freezeListener"); - - private final DataList<?> data; - - /** Creates a request containing an empty array data list */ - public Response(Request request) { - this(ArrayDataList.create(request)); - } - - /** Creates a response containing a list of data */ - public Response(DataList<?> data) { - this.data = data; - - Runnable freezeListener = null; - Request request = data.request(); - if (request != null) // subclasses of DataList may not ensure this - freezeListener = (Runnable)request.properties().get(freezeListenerKey); - if (freezeListener != null) { - if (freezeListener instanceof ResponseReceiver) - ((ResponseReceiver)freezeListener).setResponse(this); - data.addFreezeListener(freezeListener, MoreExecutors.directExecutor()); - } - } - - /** - * Convenience constructor which adds the given error message to the given request - */ - public Response(Request request, ErrorMessage errorMessage) { - this(ArrayDataList.create(request)); - request.errors().add(errorMessage); - } - - /** - * Processors which merges another request into this must call this method to notify the response. - * This does not modify the data of either response. - */ - public void mergeWith(Response other) { - } - - /** - * Returns the top level list of data items of this response - */ - public DataList data() { - return data; - } - - // ------ static utilities ---------------------------------------------------------------------------- - - /** - * Returns a future in which the given data list and all lists nested within it are completed. - * The only use of the returned future is to call a get() method on it to complete the given dataList and - * all dataLists nested below it recursively. - * <p> - * Lists are completed in prefix, depth-first order. DataLists added after the point when this method is called - * will not be completed. - * - * @param rootDataList the list to complete recursively - * @return the future in which all data in and below this list is complete, as the given root dataList for convenience - */ - public static <D extends Data> ListenableFuture<DataList<D>> recursiveComplete(DataList<D> rootDataList) { - List<ListenableFuture<DataList<D>>> futures = new ArrayList<>(); - collectCompletionFutures(rootDataList, futures); - return new CompleteAllOnGetFuture<D>(futures); - } - - @SuppressWarnings("unchecked") - private static <D extends Data> void collectCompletionFutures(DataList<D> dataList, List<ListenableFuture<DataList<D>>> futures) { - futures.add(dataList.complete()); - for (D data : dataList.asList()) { - if (data instanceof DataList) - collectCompletionFutures((DataList<D>) data, futures); - } - } - - /** - * A future which on get calls get on all its given futures and sets the value returned from the - * first given future as its result. - */ - private static class CompleteAllOnGetFuture<D extends Data> extends AbstractFuture<DataList<D>> { - - private final List<ListenableFuture<DataList<D>>> futures; - - public CompleteAllOnGetFuture(List<ListenableFuture<DataList<D>>> futures) { - this.futures = new ArrayList<>(futures); - } - - @Override - public DataList<D> get() throws InterruptedException, ExecutionException { - DataList<D> result = null; - for (ListenableFuture<DataList<D>> future : futures) { - if (result == null) - result = future.get(); - else - future.get(); - } - set(result); - return result; - } - - @Override - public DataList<D> get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - DataList<D> result = null; - long timeLeft = unit.toMillis(timeout); - long currentCallStart = SystemTimer.INSTANCE.milliTime(); - for (ListenableFuture<DataList<D>> future : futures) { - if (result == null) - result = future.get(timeLeft, TimeUnit.MILLISECONDS); - else - future.get(timeLeft, TimeUnit.MILLISECONDS); - long currentCallEnd = SystemTimer.INSTANCE.milliTime(); - timeLeft -= (currentCallEnd - currentCallStart); - if (timeLeft <= 0) break; - currentCallStart = currentCallEnd; - } - set(result); - return result; - } - - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/execution/AsyncExecution.java b/processing/src/main/java/com/yahoo/processing/execution/AsyncExecution.java deleted file mode 100644 index 2c40165f8e5..00000000000 --- a/processing/src/main/java/com/yahoo/processing/execution/AsyncExecution.java +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.execution; - -import com.yahoo.component.chain.Chain; -import com.yahoo.concurrent.ThreadFactoryFactory; -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.request.ErrorMessage; -import com.yahoo.processing.response.FutureResponse; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.*; - -/** - * <p>Provides asynchronous execution of processing chains. Usage:</p> - * - * <pre> - * Execution execution = new Execution(chain); - * AsyncExecution asyncExecution = new AsyncExecution(execution); - * Future<Response> future = asyncExecution.process(request) - * try { - * result = future.get(timeout, TimeUnit.milliseconds); - * } catch(TimeoutException e) { - * // Handle timeout - * } - * </pre> - * - * <p> - * The request is not thread safe. A clone() must be made for each parallel processing. - * </p> - * - * @author bratseth - * @see Execution - */ -public class AsyncExecution { - - private static final ThreadFactory threadFactory = ThreadFactoryFactory.getThreadFactory("processing"); - - private static final Executor executorMain = createExecutor(); - private static final Executor createExecutor() { - ThreadPoolExecutor executor = new ThreadPoolExecutor(100, - Integer.MAX_VALUE, 1L, TimeUnit.SECONDS, - new SynchronousQueue<Runnable>(false), threadFactory); - // Prestart needed, if not all threads will be created by the fist N tasks and hence they might also - // get the dreaded thread locals initialized even if they will never run. - // That counters what we we want to achieve with the Q that will prefer thread locality. - executor.prestartAllCoreThreads(); - return executor; - } - - /** - * The execution of this - */ - private final Execution execution; - - /** - * Create an async execution of a single processor - */ - public AsyncExecution(Processor processor, Execution parent) { - this(new Execution(processor, parent)); - } - - /** - * Create an async execution of a chain - */ - public AsyncExecution(Chain<? extends Processor> chain, Execution parent) { - this(new Execution(chain, parent)); - } - - /** - * Creates an async execution from an existing execution. This async - * execution will execute the chain from the given execution, starting - * from the next processor in that chain. This is handy to execute - * multiple executions to the rest of the chain in parallel. - * <p> - * The state of the given execution is read on construction of this and not - * used later - the argument execution can be reused for other purposes. - * - * @param execution the execution from which the state of this is created - */ - public AsyncExecution(Execution execution) { - this.execution = new Execution(execution); - } - - /** - * Performs an async processing. Note that the given request cannot be simultaneously - * used in multiple such processings - a clone must be created for each. - */ - public FutureResponse process(Request request) { - return getFutureResponse(new Callable<Response>() { - @Override - public Response call() { - return execution.process(request); - } - }, request); - } - - private static <T> Future<T> getFuture(final Callable<T> callable) { - FutureTask<T> future = new FutureTask<>(callable); - executorMain.execute(future); - return future; - } - - private FutureResponse getFutureResponse(Callable<Response> callable, Request request) { - FutureResponse future = new FutureResponse(callable, execution, request); - executorMain.execute(future.delegate()); - return future; - } - - /* - * Waits for all futures until the given timeout. If a FutureResult isn't - * done when the timeout expires, it will be cancelled, and it will return a - * response. All unfinished Futures will be cancelled. - * - * @return the list of responses in the same order as returned from the task collection - */ - // Note that this may also be achieved using guava Futures. Not sure if this should be deprecated because of it. - public static List<Response> waitForAll(Collection<FutureResponse> tasks, long timeout) { - - // Copy the list in case it is modified while we are waiting - List<FutureResponse> workingTasks = new ArrayList<>(tasks); - @SuppressWarnings({"rawtypes", "unchecked"}) - Future task = getFuture(new Callable() { - @Override - public List<Future> call() { - for (FutureResponse task : workingTasks) { - task.get(); - } - return null; - } - }); - - try { - task.get(timeout, TimeUnit.MILLISECONDS); - } catch (TimeoutException | InterruptedException | ExecutionException e) { - // Handle timeouts below - } - - List<Response> responses = new ArrayList<>(tasks.size()); - for (FutureResponse future : workingTasks) - responses.add(getTaskResponse(future)); - return responses; - } - - private static Response getTaskResponse(FutureResponse future) { - if (future.isDone() && !future.isCancelled()) { - return future.get(); // Since isDone() = true, this won't block. - } else { // Not done and no errors thrown - return new Response(future.getRequest(), new ErrorMessage("Timed out waiting for " + future)); - } - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/execution/Execution.java b/processing/src/main/java/com/yahoo/processing/execution/Execution.java deleted file mode 100644 index 98bc3485084..00000000000 --- a/processing/src/main/java/com/yahoo/processing/execution/Execution.java +++ /dev/null @@ -1,487 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.execution; - -import com.yahoo.collections.Pair; -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.execution.chain.ChainRegistry; -import com.yahoo.yolean.trace.TraceNode; -import com.yahoo.yolean.trace.TraceVisitor; - -import java.util.Iterator; - -/** - * An execution of a chain. This keeps tracks of the progress of the execution and is called by the - * processors (using {@link #process} to move the execution to the next one. - * - * @author bratseth - */ -public class Execution { - - /** - * The index of the searcher in the chain which should be executed on the next call - * An Execution instance contains the state of a chain execution by - * providing a class stack for a chain - when a processor is called - * (through this), it will increment the index of the processor to call next, - * each time a processor returns (regardless of how) it will do the opposite. - */ - private int processorIndex; - - private final Chain<? extends Processor> chain; - - private final Trace trace; - - private final Environment<? extends Processor> environment; - - /** - * Creates an execution of a single processor - * - * @param processor the processor to execute in this - * @param execution the parent execution of this - */ - public Execution(Processor processor, Execution execution) { - this(new Chain<>(processor), execution); - } - - /** Creates an execution of a single processor which is not in the context of an existing execution */ - public static Execution createRoot(Processor processor, int traceLevel, Environment<? extends Processor> environment) { - return createRoot(new Chain<>(processor), traceLevel, environment); - } - - /** - * Creates an execution which is not in the context of an existing execution - * - * @param chain the chain to execute - * @param traceLevel the level to emit trace at - * @param environment the execution environment to use - */ - public static Execution createRoot(Chain<? extends Processor> chain, int traceLevel, - Environment<? extends Processor> environment) { - return new Execution(chain, 0, Trace.createRoot(traceLevel), environment); - } - - /** - * Creates an execution of a chain - * - * @param chain the chain to execute in this, starting from the first processor - * @param execution the parent execution of this - */ - public Execution(Chain<? extends Processor> chain, Execution execution) { - this(chain, 0, execution.trace().createChild(), execution.environment().nested()); - } - - /** - * Creates an execution from another. This execution will start at the next processor of the - * given execution. The given execution can continue independently of this. - */ - public Execution(Execution startPoint) { - this(startPoint.chain, startPoint.processorIndex, startPoint.trace.createChild(), startPoint.environment().nested()); - } - - /** - * Creates a new execution by setting the internal state directly. - * - * @param chain the chain to execute - * @param startIndex the start index into that chain - * @param trace the context <b>of this</b>. If this is created from an existing execution/context, - * be sure to do <code> new Context<COMPONENT>(startPoint.context)</code> first! - * @param environment the static execution environment to use - */ - protected Execution(Chain<? extends Processor> chain, int startIndex, Trace trace, Environment<? extends Processor> environment) { - if (chain == null) throw new NullPointerException("Chain cannot be null"); - this.chain = chain; - this.processorIndex = startIndex; - this.trace = trace; - this.environment = environment; - } - - /** - * Calls process on the next processor in this chain. If there is no next, an empty response is returned. - */ - public Response process(Request request) { - Processor processor = next(); - if (processor == null) - return defaultResponse(request); - - Response response = null; - try { - nextProcessor(); - onInvoking(request, processor); - response = processor.process(request, this); - if (response == null) - throw new NullPointerException(processor + " returned null, not a Response object"); - return response; - } finally { - previousProcessor(); - onReturning(request, processor, response); - } - } - - /** - * Returns the index into the chain of processors which is currently next - */ - protected int nextIndex() { - return processorIndex; - } - - /** - * A hook called when a processor is to be invoked. Overriding methods must call super.onInvoking - */ - protected void onInvoking(Request request, Processor next) { - if (Trace.Level.Step.includes(trace.getTraceLevel()) || trace.getForceTimestamps()) { - int traceAt = trace.getForceTimestamps() ? 1 : trace.getTraceLevel(); - trace.trace("Invoke " + next, traceAt); - } - if (Trace.Level.Dependencies.includes(trace.getTraceLevel())) - trace.trace(next.getId() + " " + next.getDependencies().toString(), trace.getTraceLevel()); - } - - /** - * A hook called when a processor returns, either normally or by throwing. - * Overriding methods must call super.onReturning - * - * @param request the processing request - * @param processor the processor which returned - * @param response the response returned, or null if the processor returned by throwing - */ - protected void onReturning(Request request, Processor processor, Response response) { - if (Trace.Level.Step.includes(trace.getTraceLevel()) || trace.getForceTimestamps()) { - int traceAt = trace.getForceTimestamps() ? 1 : trace.getTraceLevel(); - trace.trace("Return " + processor, traceAt); - } - } - - /** Move this execution to the previous processor */ - protected void previousProcessor() { - processorIndex--; - } - - /** Move this execution to the next processor */ - protected void nextProcessor() { - processorIndex++; - } - - /** Returns the next searcher to be invoked in this chain, or null if we are at the last */ - protected Processor next() { - if (chain.components().size() <= processorIndex) return null; - return chain.components().get(processorIndex); - } - - /** Returns the chain this executes */ - public Chain<? extends Processor> chain() { - return chain; - } - - /** - * Creates the default response to return from this kind of execution when there are no further processors. - * If this is overridden, make sure to propagate any freezeListener from this to the returned response - * top-level DataList. - */ - protected Response defaultResponse(Request request) { - return new Response(request); - } - - public String toString() { - return "execution of chain '" + chain.getId() + "'"; - } - - public Trace trace() { - return trace; - } - - public Environment<? extends Processor> environment() { - return environment; - } - - /** - * Holds the static execution environment for the duration of an execution - */ - public static class Environment<COMPONENT extends Processor> { - - private final ChainRegistry<COMPONENT> chainRegistry; - - /** - * Creates an empty environment. Only useful for some limited testing - */ - public static <C extends Processor> Environment<C> createEmpty() { - return new Environment<>(new ChainRegistry<>()); - } - - /** - * Returns an environment for an execution spawned from the execution having this environment. - */ - public Environment<COMPONENT> nested() { - return this; // this is immutable, subclasses might want to do something else though - } - - /** - * Creates a new environment - */ - public Environment(ChainRegistry<COMPONENT> chainRegistry) { - this.chainRegistry = chainRegistry; - } - - /** - * Returns the processing chain registry of this execution environment. - * The registry may be empty, but never null. - */ - public ChainRegistry<COMPONENT> chainRegistry() { - return chainRegistry; - } - - } - - /** - * Tre trace of this execution. This is a facade into a node in the larger trace tree which captures - * the information about all executions caused by some request - * - * @author bratseth - */ - public static class Trace { - - /** - * The node in the trace tree capturing this execution - */ - private final TraceNode traceNode; - - /** - * The highest level of tracing this should record - */ - private int traceLevel; - - /** - * If true, do timing logic, even though trace level is low. - */ - private boolean forceTimestamps; - - /** - * Creates an empty root trace with a given level of tracing - */ - public static Trace createRoot(int traceLevel) { - return new Trace(traceLevel, new TraceNode(null, timestamp(traceLevel, false)), false); - } - - /** - * Creates a trace node below a parent - */ - public Trace createChild() { - TraceNode child = new TraceNode(null, timestamp(traceLevel, forceTimestamps)); - traceNode.add(child); - return new Trace(getTraceLevel(), child, forceTimestamps); - } - - /** - * Creates a new instance by assigning the internal state of this directly - */ - private Trace(int traceLevel, TraceNode traceNode, boolean forceTimestamps) { - this.traceLevel = traceLevel; - this.traceNode = traceNode; - this.forceTimestamps = forceTimestamps; - } - - /** - * Returns the maximum trace level this will record - */ - public int getTraceLevel() { - return traceLevel; - } - - /** - * Sets the maximum trace level this will record - */ - public void setTraceLevel(int traceLevel) { - this.traceLevel = traceLevel; - } - - public void setForceTimestamps(boolean forceTimestamps) { - this.forceTimestamps = forceTimestamps; - } - - public boolean getForceTimestamps() { - return forceTimestamps; - } - - /** - * Adds a trace message to this trace, if this trace has at most the given trace level - */ - public void trace(String message, int traceLevel) { - trace((Object)message, traceLevel); - } - public void trace(Object message, int traceLevel) { - if (this.traceLevel >= traceLevel) { - traceNode.add(new TraceNode(message, timestamp(traceLevel, forceTimestamps))); - } - } - - /** - * Adds a key-value which will be logged to the access log of this request. - * Multiple values may be set to the same key. A value cannot be removed once set, - * but it can be overwritten by adding another value for the same key. - */ - public void logValue(String key, String value) { - traceNode.add(new TraceNode(new LogValue(key, value), 0)); - } - - /** - * Returns the values that should be written to the access log set in the entire trace node tree - */ - public Iterator<LogValue> logValueIterator() { - return traceNode.root().descendants(LogValue.class).iterator(); - } - - /** - * Visits the entire trace tree - * - * @return the argument visitor for convenience - */ - public <VISITOR extends TraceVisitor> VISITOR accept(VISITOR visitor) { - return traceNode.root().accept(visitor); - } - - /** - * Adds a property key-value to this trace. - * Values are looked up by reverse depth-first search in the trace node tree. - * - * @param name the name of the property - * @param value the value of the property, or null to set this property to null - */ - public void setProperty(String name, Object value) { - traceNode.add(new TraceNode(new Pair<>(name, value), 0)); - } - - /** - * Returns a property set anywhere in the trace tree this points to. - * Note that even though this call is itself "thread robust", the object values returned - * may in some scenarios not be written behind a synchronization barrier, so when accessing - * objects which are not inherently thread safe, synchronization should be considered. - * <p> - * This method have a time complexity which is proportional to - * the number of trace nodes in the tree - * - * @return the value of this property, or null if none - */ - public Object getProperty(String name) { - return accept(new PropertyValueVisitor(name)).foundValue(); - } - - /** - * Returns the trace node peer of this - */ - public TraceNode traceNode() { - return traceNode; - } - - /** - * Returns a short string description of this - */ - @Override - public String toString() { - return "trace: " + traceNode; - } - - private static long timestamp(int traceLevel, boolean forceTimestamps) { - return (forceTimestamps || Level.Timestamp.includes(traceLevel)) ? System.currentTimeMillis() : 0; - } - - /** - * Visits all trace nodes to collect the last set value of a particular property in a trace tree - */ - private static class PropertyValueVisitor extends TraceVisitor { - - /** - * The name of the property to find - */ - private String name; - private Object foundValue = null; - - public PropertyValueVisitor(String name) { - this.name = name; - } - - @Override - public void visit(TraceNode node) { - if (node.payload() == null) return; - if (!(node.payload() instanceof Pair)) return; - - Pair property = (Pair) node.payload(); - if (!property.getFirst().equals(name)) return; - foundValue = property.getSecond(); - } - - public Object foundValue() { - return foundValue; - } - - } - - /** - * An immutable access log value added to the trace - */ - public static class LogValue { - - private final String key; - private final String value; - - public LogValue(String key, String value) { - this.key = key; - this.value = value; - } - - public String getKey() { - return key; - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return key + "=" + value; - } - - } - - /** - * Defines what information is added at which trace level - */ - public enum Level { - - /** - * Every processing step initiated is traced - */ - Step(4), - /** - * All trace messages are timestamped - */ - Timestamp(6), - /** - * The before/after dependencies of each processing step is traced on every invocation - */ - Dependencies(7); - - /** - * The smallest trace level at which this information will be traced - */ - private int value; - - Level(int value) { - this.value = value; - } - - public int value() { - return value; - } - - /** - * Returns whether this level includes the given level, i.e whether traceLevel is this.value() or more - */ - public boolean includes(int traceLevel) { - return traceLevel >= this.value(); - } - - } - } -} diff --git a/processing/src/main/java/com/yahoo/processing/execution/ExecutionWithResponse.java b/processing/src/main/java/com/yahoo/processing/execution/ExecutionWithResponse.java deleted file mode 100644 index a95771c1202..00000000000 --- a/processing/src/main/java/com/yahoo/processing/execution/ExecutionWithResponse.java +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.execution; - -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; - -/** - * An execution which has a response which is returned when this gets to the end of the chain. - * This is useful to run processing chains where a response exists up front, typically for on completion listeners. - * - * @author bratseth - */ -public class ExecutionWithResponse extends Execution { - - private Response response; - - /** - * Creates an execution which will return a given response at the end of the chain. - * - * @param chain the chain to execute in this - * @param response the response this will return from {@link #process} then the end of this chain is reached - * @param execution the the parent of this execution - */ - public ExecutionWithResponse(Chain<? extends Processor> chain, Response response, Execution execution) { - super(chain, execution); - this.response = response; - } - - @Override - protected Response defaultResponse(Request request) { - return response; - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/execution/ResponseReceiver.java b/processing/src/main/java/com/yahoo/processing/execution/ResponseReceiver.java deleted file mode 100644 index 053459166e6..00000000000 --- a/processing/src/main/java/com/yahoo/processing/execution/ResponseReceiver.java +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.execution; - -import com.yahoo.processing.Response; - -/** - * An interface for classes which can be given responses. - * Freeze listeners may implement this to be handed the response - * before they are run. There is probably no other sensible use for this. - * - * @author bratseth - */ -public interface ResponseReceiver { - - public void setResponse(Response response); - -} diff --git a/processing/src/main/java/com/yahoo/processing/execution/RunnableExecution.java b/processing/src/main/java/com/yahoo/processing/execution/RunnableExecution.java deleted file mode 100644 index e69cb8e48cd..00000000000 --- a/processing/src/main/java/com/yahoo/processing/execution/RunnableExecution.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.execution; - -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; - -/** - * An adaptor of an Execution to a runnable. Calling run on this causes process to be called on the - * given processor. - * - * @author bratseth - */ -public class RunnableExecution implements Runnable { - - private final Request request; - private final Execution execution; - private Response response = null; - private Throwable exception = null; - - public RunnableExecution(Request request, Execution execution) { - this.request = request; - this.execution = execution; - } - - /** - * Calls process on the execution of this. - * This will result in either response or exception being set on this. - * Calling this never throws an exception. - */ - public void run() { - try { - response = execution.process(request); - } catch (Exception e) { - exception = e; // TODO: Log - } - } - - /** - * Returns the response from executing this, or null if exception is set or run() has not been called yet - */ - public Response getResponse() { - return response; - } - - /** - * Returns the exception from executing this, or null if response is set or run() has not been called yet - */ - public Throwable getException() { - return exception; - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/execution/chain/ChainRegistry.java b/processing/src/main/java/com/yahoo/processing/execution/chain/ChainRegistry.java deleted file mode 100644 index dbf31de1b72..00000000000 --- a/processing/src/main/java/com/yahoo/processing/execution/chain/ChainRegistry.java +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.execution.chain; - -import com.yahoo.component.chain.Chain; -import com.yahoo.component.chain.ChainedComponent; -import com.yahoo.component.provider.ComponentRegistry; - -/** - * A registry of chains - * - * @author Tony Vaagenes - */ -public class ChainRegistry<T extends ChainedComponent> extends ComponentRegistry<Chain<T>> { -} diff --git a/processing/src/main/java/com/yahoo/processing/execution/chain/package-info.java b/processing/src/main/java/com/yahoo/processing/execution/chain/package-info.java deleted file mode 100644 index 6d82609bc76..00000000000 --- a/processing/src/main/java/com/yahoo/processing/execution/chain/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -@PublicApi package com.yahoo.processing.execution.chain; - -import com.yahoo.api.annotations.PublicApi; -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/processing/src/main/java/com/yahoo/processing/execution/package-info.java b/processing/src/main/java/com/yahoo/processing/execution/package-info.java deleted file mode 100644 index 6430aa32ae3..00000000000 --- a/processing/src/main/java/com/yahoo/processing/execution/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -@PublicApi package com.yahoo.processing.execution; - -import com.yahoo.api.annotations.PublicApi; -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/processing/src/main/java/com/yahoo/processing/package-info.java b/processing/src/main/java/com/yahoo/processing/package-info.java deleted file mode 100644 index b39272d881a..00000000000 --- a/processing/src/main/java/com/yahoo/processing/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -/** - * Java library for request-response data processing. - * - * This library defines request-response processing as an operation which - * accepts a Request and produces a Response containing Data by executing - * a Chain of processing components in a single worker thread using method - * calls for chaining, i.e a synchronous processing model. - * Data for the Response may optionally be produced asynchronously. - * - * The processing model can be implemented by subtyping in frameworks defining - * a processing model (with a richer, more specific API) for a particular domain. - */ -@ExportPackage -@PublicApi package com.yahoo.processing; - -// TODO: -// - Look through all instances where we pass executor and consider if we should allow the caller to decide the thread -// - Should data listener use a typed interface rather than runnable` - -import com.yahoo.api.annotations.PublicApi; -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/processing/src/main/java/com/yahoo/processing/request/CloneHelper.java b/processing/src/main/java/com/yahoo/processing/request/CloneHelper.java deleted file mode 100644 index 837ff3db295..00000000000 --- a/processing/src/main/java/com/yahoo/processing/request/CloneHelper.java +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request; - -import com.yahoo.collections.MethodCache; -import com.yahoo.component.provider.FreezableClass; -import com.yahoo.processing.request.properties.PublicCloneable; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.logging.Logger; -import java.util.LinkedList; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Map; -import java.util.HashMap; - -/** - * Helps to deep clone complex objects - * The following classes and their subclasses does have a fastpath - * - com.yahoo.component.provider.FreezableClass - * - com.yahoo.processing.request.properties.PublicCloneable BTW, this is the one you should implement too - * if you want the fastpath. - * - java.util.LinkedList - * - java.util.ArrayList - * The rest has the slow path with reflection, - * though using a fast thread safe method cache for speedup. - * - * @author bratseth - * @author baldersheim - */ -public class CloneHelper { - - private static Logger log = Logger.getLogger(CloneHelper.class.getName()); - private static final MethodCache cloneMethodCache = new MethodCache("clone"); - - /** - * Clones this object if it is clonable, and the clone is public. Returns null if not - */ - public final Object clone(Object object) { - if (object == null) return null; - if ( ! (object instanceof Cloneable)) return null; - if (object.getClass().isArray()) - return arrayClone(object); - else - return objectClone(object); - } - - private Object arrayClone(Object array) { - if (array instanceof Object[]) - return objectArrayClone((Object[]) array); - else if (array instanceof byte[]) - return Arrays.copyOf((byte[])array, ((byte[])array).length); - else if (array instanceof char[]) - return Arrays.copyOf((char[])array, ((char[])array).length); - else if (array instanceof short[]) - return Arrays.copyOf((short[])array, ((short[])array).length); - else if (array instanceof int[]) - return Arrays.copyOf((int[])array, ((int[])array).length); - else if (array instanceof long[]) - return Arrays.copyOf((long[])array, ((long[])array).length); - else if (array instanceof float[]) - return Arrays.copyOf((float[])array, ((float[])array).length); - else if (array instanceof double[]) - return Arrays.copyOf((double[])array, ((double[])array).length); - else if (array instanceof boolean[]) - return Arrays.copyOf((boolean[])array, ((boolean[])array).length); - else - return new IllegalArgumentException("Unexpected primitive array type " + array.getClass()); - } - - private Object objectArrayClone(Object[] object) { - Object[] arrayClone = Arrays.copyOf(object, object.length); - // deep clone - for (int i = 0; i < arrayClone.length; i++) { - Object elementClone = clone(arrayClone[i]); - if (elementClone != null) - arrayClone[i] = elementClone; - } - return arrayClone; - } - - protected Object objectClone(Object object) { - // Fastpath for our commonly used classes - if (object instanceof FreezableClass) - return ((FreezableClass)object).clone(); - else if (object instanceof PublicCloneable) - return ((PublicCloneable<?>)object).clone(); - else if (object instanceof LinkedList) - return ((LinkedList<?>) object).clone(); - else if (object instanceof ArrayList) - return ((ArrayList<?>) object).clone(); - - try { - Method cloneMethod = cloneMethodCache.get(object); - if (cloneMethod == null) { - log.warning("'" + object + "' of class " + object.getClass() + - " is Cloneable, but has no clone method - will use the same instance in all requests"); - return null; - } - return cloneMethod.invoke(object); - } catch (IllegalAccessException e) { - log.warning("'" + object + "' of class " + object.getClass() + - " is Cloneable, but clone method cannot be accessed - will use the same instance in all requests"); - return null; - } catch (InvocationTargetException e) { - throw new RuntimeException("Exception cloning '" + object + "'", e); - } - } - - /** - * Clones a map by deep cloning each value which is cloneable and shallow copying all other values. - */ - public Map<CompoundName, Object> cloneMap(Map<CompoundName, Object> map) { - Map<CompoundName, Object> cloneMap = new HashMap<>(map.size()); - for (Map.Entry<CompoundName, Object> entry : map.entrySet()) { - Object cloneValue = clone(entry.getValue()); - if (cloneValue == null) - cloneValue = entry.getValue(); // Shallow copy objects which does not support cloning - cloneMap.put(entry.getKey(), cloneValue); - } - return cloneMap; - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/request/CompoundName.java b/processing/src/main/java/com/yahoo/processing/request/CompoundName.java deleted file mode 100644 index 432c7473c2b..00000000000 --- a/processing/src/main/java/com/yahoo/processing/request/CompoundName.java +++ /dev/null @@ -1,288 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request; - -import com.google.common.collect.ImmutableList; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static com.yahoo.text.Lowercase.toLowerCase; - -/** - * An immutable compound name of the general form "a.bb.ccc", - * where there can be any number of such compounds, including one or zero. - * <p> - * Using CompoundName is generally substantially faster than using strings. - * - * @author bratseth - */ -public final class CompoundName { - - /** - * The string name of this compound. - */ - private final String name; - private final String lowerCasedName; - - private final ImmutableList<String> compounds; - - /** A hashcode which is always derived from the compounds (NEVER the string) */ - private final int hashCode; - - /** This name with the first component removed */ - private final CompoundName rest; - - /** The empty compound */ - public static final CompoundName empty = new CompoundName(""); - - /** - * Constructs this from a string which may contains dot-separated components - * - * @throws NullPointerException if name is null - */ - public CompoundName(String name) { - this(name, parse(name)); - } - - /** Constructs this from an array of name components which are assumed not to contain dots */ - public static CompoundName fromComponents(String ... components) { - return new CompoundName(Arrays.asList(components)); - } - - /** Constructs this from a list of compounds. */ - public CompoundName(List<String> compounds) { - this(toCompoundString(compounds), compounds); - } - - /** - * Constructs this from a name with already parsed compounds. - * Private to avoid creating names with inconsistencies. - * - * @param name the string representation of the compounds - * @param compounds the compounds of this name - */ - private CompoundName(String name, List<String> compounds) { - if (name == null) throw new NullPointerException("Name can not be null"); - - this.name = name; - this.lowerCasedName = toLowerCase(name); - if (compounds.size()==1 && compounds.get(0).isEmpty()) - this.compounds = ImmutableList.of(); - else - this.compounds = ImmutableList.copyOf(compounds); - this.hashCode = this.compounds.hashCode(); - - int size = this.compounds.size(); - rest = size > 1 ? new CompoundName(compounds.subList(1, size)) - : size == 1 ? empty : this; // size==0 -> this needed during construction of empty - } - - private static List<String> parse(String s) { - ArrayList<String> l = null; - - int p = 0; - final int m = s.length(); - for (int i = 0; i < m; i++) { - if (s.charAt(i) == '.') { - if (l == null) l = new ArrayList<>(8); - l.add(s.substring(p, i)); - p = i + 1; - } - } - if (p == 0) { - return ImmutableList.of(s); - } else if (p < m) { - l.add(s.substring(p, m)); - } else { - throw new IllegalArgumentException("'" + s + "' is not a legal compound name. Names can not end with a dot."); - } - return l; - } - - /** - * Returns a compound name which has the given compound string appended to it - * - * @param name if name is empty this returns <code>this</code> - */ - public CompoundName append(String name) { - if (name.isEmpty()) return this; - if (isEmpty()) return new CompoundName(name); - List<String> newCompounds = new ArrayList<>(compounds); - newCompounds.addAll(parse(name)); - return new CompoundName(concat(this.name, name), newCompounds); - } - - /** - * Returns a compound name which has the given compounds appended to it - * - * @param name if name is empty this returns <code>this</code> - */ - public CompoundName append(CompoundName name) { - if (name.isEmpty()) return this; - if (isEmpty()) return name; - List<String> newCompounds = new ArrayList<>(compounds); - newCompounds.addAll(name.compounds); - return new CompoundName(concat(this.name, name.name), newCompounds); - } - - private String concat(String name1, String name2) { - return name1 + "." + name2; - } - - /** - * Returns a compound name which has the given name components prepended to this name, - * in the given order, i.e new ComponentName("c").prepend("a","b") will yield "a.b.c". - * - * @param nameParts if name is empty this returns <code>this</code> - */ - public CompoundName prepend(String ... nameParts) { - if (nameParts.length == 0) return this; - if (isEmpty()) return fromComponents(nameParts); - - List<String> newCompounds = new ArrayList<>(nameParts.length + compounds.size()); - newCompounds.addAll(Arrays.asList(nameParts)); - newCompounds.addAll(this.compounds); - return new CompoundName(newCompounds); - } - - /** - * Returns the name after the last dot. If there are no dots, the full name is returned. - */ - public String last() { - if (compounds.isEmpty()) return ""; - return compounds.get(compounds.size() - 1); - } - - /** - * Returns the name before the first dot. If there are no dots the full name is returned. - */ - public String first() { - if (compounds.isEmpty()) return ""; - return compounds.get(0); - } - - /** - * Returns the first n components of this. - * - * @throws IllegalArgumentException if this does not have at least n components - */ - public CompoundName first(int n) { - if (compounds.size() < n) - throw new IllegalArgumentException("Asked for the first " + n + " components but '" + - this + "' only have " + compounds.size() + " components."); - return new CompoundName(compounds.subList(0, n)); - } - - /** - * Returns the name after the first dot, or "" if this name has no dots - */ - public CompoundName rest() { return rest; } - - /** - * Returns the name starting after the n first components (i.e dots). - * This may be the empty name. - * - * @throws IllegalArgumentException if this does not have at least that many components - */ - public CompoundName rest(int n) { - if (n == 0) return this; - if (compounds.size() < n) - throw new IllegalArgumentException("Asked for the rest after " + n + " components but '" + - this + "' only have " + compounds.size() + " components."); - if (n == 1) return rest(); - if (compounds.size() == n) return empty; - return rest.rest(n - 1); - } - - /** - * Returns the number of compound elements in this. Which is exactly the number of dots in the string plus one. - * The size of an empty compound is 0. - */ - public int size() { - return compounds.size(); - } - - /** - * Returns the compound element as the given index - */ - public String get(int i) { - return compounds.get(i); - } - - /** - * Returns a compound which have the name component at index i set to the given name. - * As an optimization, if the given name == the name component at this index, this is returned. - */ - public CompoundName set(int i, String name) { - if (get(i) == name) return this; - List<String> newCompounds = new ArrayList<>(compounds); - newCompounds.set(i, name); - return new CompoundName(newCompounds); - } - - /** - * Returns whether this name has more than one element - */ - public boolean isCompound() { - return compounds.size() > 1; - } - - public boolean isEmpty() { - return compounds.isEmpty(); - } - - /** - * Returns whether the given name is a prefix of this. - * Prefixes are taken on the component, not character level, so - * "a" is a prefix of "a.b", but not a prefix of "ax.b - */ - public boolean hasPrefix(CompoundName prefix) { - if (prefix.size() > this.size()) return false; - - int prefixLength = prefix.name.length(); - if (prefixLength == 0) - return true; - - if (name.length() > prefixLength && name.charAt(prefixLength) != '.') - return false; - - return name.startsWith(prefix.name); - } - - /** - * Returns an immutable list of the components of this - */ - public List<String> asList() { - return compounds; - } - - @Override - public int hashCode() { return hashCode; } - - @Override - public boolean equals(Object o) { - if (o == this) return true; - if ( ! (o instanceof CompoundName)) return false; - CompoundName other = (CompoundName)o; - return this.name.equals(other.name); - } - - /** - * Returns the string representation of this - all the name components in order separated by dots. - */ - @Override - public String toString() { return name; } - - public String getLowerCasedName() { - return lowerCasedName; - } - - private static String toCompoundString(List<String> compounds) { - StringBuilder b = new StringBuilder(); - for (String compound : compounds) - b.append(compound).append("."); - return b.length()==0 ? "" : b.substring(0, b.length()-1); - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/request/ErrorMessage.java b/processing/src/main/java/com/yahoo/processing/request/ErrorMessage.java deleted file mode 100644 index 0ced664bfdc..00000000000 --- a/processing/src/main/java/com/yahoo/processing/request/ErrorMessage.java +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request; - -/** - * An error encountered while processing a request. - * This can be subclassed to add error messages containing more information. - * <p> - * Error messages are immutable. - * - * @author bratseth - */ -public class ErrorMessage implements Cloneable { - - private final int code; - private final String message; - private final String detailedMessage; - private final Throwable cause; - - /** - * Creates an error - * - * @param message the textual message describing this condition tersely - */ - public ErrorMessage(String message) { - this(0, message, null, null); - } - - /** - * Creates an error - * - * @param message the textual message describing this condition tersely - * @param code an error code. If this is bound to HTTP request/responses and - * this error code is a HTTP status code, this code will be returned as the HTTP status - */ - public ErrorMessage(int code, String message) { - this(code, message, null, null); - } - - /** - * Creates an error - * - * @param message the textual message describing this condition tersely - * @param details a longer detail description of this condition - */ - public ErrorMessage(String message, String details) { - this(0, message, details, null); - } - - /** - * Creates an error - * - * @param message the textual message describing this condition tersely - * @param code an error code. If this is bound to HTTP request/responses and - * this error code is a HTTP status code, this code will be returned as the HTTP status - * @param details a longer detail description of this condition - */ - public ErrorMessage(int code, String message, String details) { - this(code, message, details, null); - } - - /** - * Creates an error - * - * @param message the textual message describing this condition tersely - * @param cause the cause of this error - */ - public ErrorMessage(String message, Throwable cause) { - this(0, message, null, cause); - } - - /** - * Creates an error - * - * @param code an error code. If this is bound to HTTP request/responses and - * this error code is a HTTP status code, this code will be returned as the HTTP status - * @param message the textual message describing this condition tersely - * @param cause the cause of this error - */ - public ErrorMessage(int code, String message, Throwable cause) { - this(code, message, null, cause); - } - - /** - * Creates an error - * - * @param message the textual message describing this condition tersely - * @param details a longer detail description of this condition - * @param cause the cause of this error - */ - public ErrorMessage(String message, String details, Throwable cause) { - this(0, message, details, cause); - } - - /** - * Creates an error - * - * @param code an error code. If this is bound to HTTP request/responses and - * this error code is a HTTP status code, this code will be returned as the HTTP status - * @param message the textual message describing this condition tersely - * @param details a longer detail description of this condition - * @param cause the cause of this error - */ - public ErrorMessage(int code, String message, String details, Throwable cause) { - if (message == null) throw new NullPointerException("Message cannot be null"); - this.code = code; - this.message = message; - this.detailedMessage = details; - this.cause = cause; - } - - /** - * Returns the code of this message, or 0 if no code is set - */ - public int getCode() { - return code; - } - - /** - * Returns the error message, never null - */ - public String getMessage() { - return message; - } - - /** - * Returns detailed information about this error, or null if there is no detailed message - */ - public String getDetailedMessage() { - return detailedMessage; - } - - /** - * Returns the throwable associated with this error, or null if none - */ - public Throwable getCause() { - return cause; - } - - /** - * Returns a formatted message containing the information in this - */ - @Override - public String toString() { - if (code == 0 && detailedMessage == null && cause == null) return message; // shortcut - StringBuilder b = new StringBuilder(); - if (code != 0) - b.append(code).append(": "); - b.append(message); - if (detailedMessage != null) - b.append(": ").append(detailedMessage); - if (cause != null) - append(cause, b); - return b.toString(); - } - - private void append(Throwable t, StringBuilder b) { - String lastMessage = null; - String message; - for (; t != null; t = t.getCause(), lastMessage = message) { - message = getMessage(t); - if (message == null) continue; - if (lastMessage != null && lastMessage.equals(message)) continue; - if (b.length() > 0) - b.append(": "); - b.append(message); - } - } - - /** - * Returns a useful message from *this* exception, or null if none - */ - private static String getMessage(Throwable t) { - String message = t.getMessage(); - if (t.getCause() == null) { - if (message == null) return t.getClass().getSimpleName(); - } else { - if (message == null) return null; - if (message.equals(t.getCause().getClass().getName() + ": " + t.getCause().getMessage())) return null; - } - return message; - } - - @Override - public int hashCode() { - return code * 7 + message.hashCode() + (detailedMessage == null ? 0 : 17 * detailedMessage.hashCode()); - } - - /** - * Two error messages are equal if they have the same code and message. - * The cause is ignored in the comparison. - */ - @Override - public boolean equals(Object o) { - if (!(o instanceof ErrorMessage)) return false; - - ErrorMessage other = (ErrorMessage) o; - - if (this.code != other.code) return false; - - if (!this.message.equals(other.message)) return false; - - if (this.detailedMessage == null) return other.detailedMessage == null; - if (other.detailedMessage == null) return false; - - return this.detailedMessage.equals(other.detailedMessage); - } - - @Override - public ErrorMessage clone() { - try { - return (ErrorMessage) super.clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException("Programming error"); - } - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/request/Properties.java b/processing/src/main/java/com/yahoo/processing/request/Properties.java deleted file mode 100644 index 9362de59203..00000000000 --- a/processing/src/main/java/com/yahoo/processing/request/Properties.java +++ /dev/null @@ -1,634 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request; - -import java.util.Map; -import java.util.HashMap; -import java.util.Collections; - -/** - * The properties of a request - * - * @author bratseth - */ -public class Properties implements Cloneable { - - private final static CloneHelper cloneHelper = new CloneHelper(); - private Properties chained = null; - - /** - * Sets the properties chained to this. - * - * @param chained the properties to chain to this, or null to make this the last in the chain - * @return the given chained object to allow setting up a chain by dotting in one statement - */ - public Properties chain(Properties chained) { - this.chained = chained; - return chained; - } - - /** - * Returns the properties chained to this, or null if this is the last in the chain - */ - public Properties chained() { - return chained; - } - - /** - * Returns the first instance of the given class in this chain, or null if none - */ - @SuppressWarnings("unchecked") - public final <T extends Properties> T getInstance(Class<T> propertyClass) { - if (propertyClass.isAssignableFrom(this.getClass())) return (T) this; - if (chained == null) return null; - return chained.getInstance(propertyClass); - } - - /** - * Lists all properties of this with no context, by delegating to listProperties("") - */ - public final Map<String, Object> listProperties() { - return listProperties(CompoundName.empty); - } - - /** - * Returns a snapshot of all properties of this - same as listProperties("",context) - */ - public final Map<String, Object> listProperties(Map<String, String> context) { - return listProperties(CompoundName.empty, context, this); - } - - /** - * Returns a snapshot of all properties by calling listProperties(path,null) - */ - public final Map<String, Object> listProperties(CompoundName path) { - return listProperties(path, null, this); - } - - /** - * Returns a snapshot of all properties by calling listProperties(path,null) - */ - public final Map<String, Object> listProperties(String path) { - return listProperties(new CompoundName(path), null, this); - } - - /** - * Returns a snapshot of all properties by calling listProperties(path,null) - */ - public final Map<String, Object> listProperties(CompoundName path, Map<String, String> context) { - return listProperties(path, context, this); - } - - /** - * Returns a snapshot of all properties by calling listProperties(path,null) - */ - public final Map<String, Object> listProperties(String path, Map<String, String> context) { - return listProperties(new CompoundName(path), context, this); - } - - /** - * Returns a snapshot of all properties of this having a given path prefix - * <p> - * Some sources of properties may not be list-able (e.g those using reflection) - * and will not be included in this snapshot. - * - * - * @param path the prefix (up to a ".") of the properties to return, or null or the empty string to return all properties - * @param context the context used to resolve the properties, or null if none - * @param substitution the properties which will be used to do string substitution in the values added to the map - */ - public Map<String, Object> listProperties(CompoundName path, Map<String, String> context, Properties substitution) { - if (path == null) - path = CompoundName.empty; - if (chained() == null) - return new HashMap<>(); - else - return chained().listProperties(path, context, substitution); - } - - /** - * Returns a snapshot of all properties of this having a given path prefix - * <p> - * Some sources of properties may not be list-able (e.g those using reflection) - * and will not be included in this snapshot. - * - * - * @param path the prefix (up to a ".") of the properties to return, or null or the empty string to return all properties - * @param context the context used to resolve the properties, or null if none - * @param substitution the properties which will be used to do string substitution in the values added to the map - */ - public final Map<String, Object> listProperties(String path, Map<String, String> context, Properties substitution) { - return listProperties(new CompoundName(path), context, substitution); - } - - /** - * Gets a named value which (if necessary) is resolved using a property context. - * - * @param name the name of the property to return - * @param context the variant resolution context, or null if none - * @param substitution the properties used to substitute in these properties, or null if none - */ - public Object get(CompoundName name, Map<String, String> context, Properties substitution) { - if (chained == null) return null; - return chained.get(name, context, substitution); - } - - /** - * Gets a named value which (if necessary) is resolved using a property context - * - * @param name the name of the property to return - * @param context the variant resolution context, or null if none - * @param substitution the properties used to substitute in these properties, or null if none - */ - public final Object get(String name, Map<String, String> context, Properties substitution) { - return get(new CompoundName(name), context, substitution); - } - - /** - * Gets a named value from the first chained instance which has one by calling get(name,context,this) - */ - public final Object get(CompoundName name, Map<String, String> context) { - return get(name, context, this); - } - - /** - * Gets a named value from the first chained instance which has one by calling get(name,context,this) - */ - public final Object get(String name, Map<String, String> context) { - return get(new CompoundName(name), context, this); - } - - /** - * Gets a named value from the first chained instance which has one by calling get(name,null,this) - */ - public final Object get(CompoundName name) { - return get(name, null, this); - } - - /** - * Gets a named value from the first chained instance which has one by calling get(name,null,this) - */ - public final Object get(String name) { - return get(new CompoundName(name), null, this); - } - - /** - * Gets a named value from the first chained instance which has one, - * or the default value if no value is set, or if the first value encountered is explicitly set to null. - * <p> - * This default implementation simply forwards to the chained instance, or returns the default if none - * - * - * @param name the name of the property to return - * @param defaultValue the default value returned if the value returned is null - */ - public final Object get(CompoundName name, Object defaultValue) { - Object value = get(name); - if (value == null) return defaultValue; - return value; - } - - /** - * Gets a named value from the first chained instance which has one, - * or the default value if no value is set, or if the first value encountered is explicitly set to null. - * <p> - * This default implementation simply forwards to the chained instance, or returns the default if none - * - * @param name the name of the property to return - * @param defaultValue the default value returned if the value returned is null - */ - public final Object get(String name, Object defaultValue) { - return get(new CompoundName(name), defaultValue); - } - - /** - * Sets a value to the first chained instance which accepts it. - * <p> - * This default implementation forwards to the chained instance or throws - * a RuntimeException if there is not chained instance. - * - * @param name the name of the property - * @param value the value to set. Setting a property to null clears it. - * @param context the context used to resolve where the values should be set, or null if none - * @throws RuntimeException if no instance in the chain accepted this name-value pair - */ - public void set(CompoundName name, Object value, Map<String, String> context) { - if (chained == null) throw new RuntimeException("Property '" + name + "->" + - value + "' was not accepted in this property chain"); - chained.set(name, value, context); - } - - /** - * Sets a value to the first chained instance which accepts it. - * <p> - * This default implementation forwards to the chained instance or throws - * a RuntimeException if there is not chained instance. - * - * @param name the name of the property - * @param value the value to set. Setting a property to null clears it. - * @param context the context used to resolve where the values should be set, or null if none - * @throws RuntimeException if no instance in the chain accepted this name-value pair - */ - public final void set(String name, Object value, Map<String, String> context) { - set(new CompoundName(name), value, context); - } - - /** - * Sets a value to the first chained instance which accepts it by calling set(name,value,null). - * - * @param name the name of the property - * @param value the value to set. Setting a property to null clears it. - * @throws RuntimeException if no instance in the chain accepted this name-value pair - */ - public final void set(CompoundName name, Object value) { - set(name, value, null); - } - - /** - * Sets a value to the first chained instance which accepts it by calling set(name,value,null). - * - * @param name the name of the property - * @param value the value to set. Setting a property to null clears it. - * @throws RuntimeException if no instance in the chain accepted this name-value pair - */ - public final void set(String name, Object value) { - set(new CompoundName(name), value, Collections.<String,String>emptyMap()); - } - - /** - * Sets all properties having this name as a compound prefix to null. - * I.e clearAll("a") will clear the value of "a" and "a.b" but not "ab". - * This default implementation forwards to the chained instance or throws - * a RuntimeException if there is not chained instance. - * - * @param name the compound prefix of the properties to clear - * @param context the context used to resolve where the values should be cleared, or null if none - * @throws RuntimeException if no instance in the chain accepted this name-value pair - */ - public void clearAll(CompoundName name, Map<String, String> context) { - if (chained == null) throw new RuntimeException("Property '" + name + - "' was not accepted in this property chain"); - chained.clearAll(name, context); - } - - /** - * Sets all properties having this name as a compound prefix to null. - * I.e clearAll("a") will clear the value of "a" and "a.b" but not "ab". - * - * @param name the compound prefix of the properties to clear - * @param context the context used to resolve where the values should be cleared, or null if none - * @throws RuntimeException if no instance in the chain accepted this name-value pair - */ - public final void clearAll(String name, Object value, Map<String, String> context) { - set(new CompoundName(name), value, context); - } - - /** - * Sets all properties having this name as a compound prefix to null. - * I.e clearAll("a") will clear the value of "a" and "a.b" but not "ab". - * - * @param name the compound prefix of the properties to clear - * @throws RuntimeException if no instance in the chain accepted this name-value pair - */ - public final void clearAll(CompoundName name) { - clearAll(name, null); - } - - /** - * Sets all properties having this name as a compound prefix to null. - * I.e clearAll("a") will clear the value of "a" and "a.b" but not "ab". - * - * @param name the compound prefix of the properties to clear - * @throws RuntimeException if no instance in the chain accepted this name-value pair - */ - public final void clearAll(String name) { - clearAll(new CompoundName(name), Collections.<String,String>emptyMap()); - } - - /** - * Gets a property as a boolean - if this value can reasonably be interpreted as a boolean, this will return - * the value. Returns false if this property is null. - */ - public final boolean getBoolean(CompoundName name) { - return getBoolean(name, false); - } - - /** - * Gets a property as a boolean - if this value can reasonably be interpreted as a boolean, this will return - * the value. Returns false if this property is null. - */ - public final boolean getBoolean(String name) { - return getBoolean(name, false); - } - - /** - * Gets a property as a boolean. - * This will return true only if the value is either the empty string, - * or any Object which has a toString which is case-insensitive equal to "true" - * - * @param defaultValue the value to return if this property is null - */ - public final boolean getBoolean(CompoundName key, boolean defaultValue) { - return asBoolean(get(key), defaultValue); - } - - /** - * Gets a property as a boolean. - * This will return true only if the value is either the empty string, - * or any Object which has a toString which is case-insensitive equal to "true" - * - * @param defaultValue the value to return if this property is null - */ - public final boolean getBoolean(String key, boolean defaultValue) { - return asBoolean(get(key), defaultValue); - } - - /** - * Converts a value to boolean - this will be true only if the value is either the empty string, - * or any Object which has a toString which is case-insensitive equal to "true" - */ - protected final boolean asBoolean(Object value, boolean defaultValue) { - if (value == null) return defaultValue; - - String s = value.toString(); - int sz = s.length(); - switch (sz) { - case 0: - return true; - case 4: - return ((s.charAt(0) | 0x20) == 't') && - ((s.charAt(1) | 0x20) == 'r') && - ((s.charAt(2) | 0x20) == 'u') && - ((s.charAt(3) | 0x20) == 'e'); - } - return false; - } - - /** - * Returns this property as a string - * - * @return this property as a string, or null if the property is null - */ - public final String getString(CompoundName key) { - return getString(key, null); - } - - /** - * Returns this property as a string - * - * @return this property as a string, or null if the property is null - */ - public final String getString(String key) { - return getString(key, null); - } - - /** - * Returns this property as a string - * - * @param key the property key - * @param defaultValue the value to return if this property is null - * @return this property as a string - */ - public final String getString(CompoundName key, String defaultValue) { - return asString(get(key), defaultValue); - } - - /** - * Returns this property as a string - * - * @param key the property key - * @param defaultValue the value to return if this property is null - * @return this property as a string - */ - public final String getString(String key, String defaultValue) { - return asString(get(key), defaultValue); - } - - protected final String asString(Object value, String defaultValue) { - if (value == null) return defaultValue; - return value.toString(); - } - - /** - * Returns a property as an Integer - * - * @return the integer value of the name, or null if the property is null - * @throws NumberFormatException if the given parameter exists but - * have a toString which is not parseable as a number - */ - public final Integer getInteger(CompoundName name) { - return getInteger(name, null); - } - - /** - * Returns a property as an Integer - * - * @return the integer value of the name, or null if the property is null - * @throws NumberFormatException if the given parameter exists but - * have a toString which is not parseable as a number - */ - public final Integer getInteger(String name) { - return getInteger(name, null); - } - - /** - * Returns a property as an Integer - * - * @param name the property name - * @param defaultValue the value to return if this property is null - * @return the integer value for the name - * @throws NumberFormatException if the given parameter does not exist - * or does not have a toString parseable as a number - */ - public final Integer getInteger(CompoundName name, Integer defaultValue) { - return asInteger(get(name), defaultValue); - } - - /** - * Returns a property as an Integer - * - * @param name the property name - * @param defaultValue the value to return if this property is null - * @return the integer value for the name - * @throws NumberFormatException if the given parameter does not exist - * or does not have a toString parseable as a number - */ - public final Integer getInteger(String name, Integer defaultValue) { - return asInteger(get(name), defaultValue); - } - - protected final Integer asInteger(Object value, Integer defaultValue) { - try { - if (value == null) - return defaultValue; - - if (value instanceof Number) - return ((Number)value).intValue(); - - String stringValue = value.toString(); - if (stringValue.isEmpty()) - return defaultValue; - - return Integer.valueOf(stringValue); - } catch (IllegalArgumentException e) { - throw new NumberFormatException("'" + value + "' is not a valid integer"); - } - } - - /** - * Returns a property as a Long - * - * @return the long value of the name, or null if the property is null - * @throws NumberFormatException if the given parameter exists but have a value which - * is not parseable as a number - */ - public final Long getLong(CompoundName name) { - return getLong(name, null); - } - - /** - * Returns a property as a Long - * - * @return the long value of the name, or null if the property is null - * @throws NumberFormatException if the given parameter exists but have a value which - * is not parseable as a number - */ - public final Long getLong(String name) { - return getLong(name, null); - } - - /** - * Returns a property as a Long - * - * @param name the property name - * @param defaultValue the value to return if this property is null - * @return the integer value for this name - * @throws NumberFormatException if the given parameter exists but have a value which - * is not parseable as a number - */ - public final Long getLong(CompoundName name, Long defaultValue) { - return asLong(get(name), defaultValue); - } - - /** - * Returns a property as a Long - * - * @param name the property name - * @param defaultValue the value to return if this property is null - * @return the integer value for this name - * @throws NumberFormatException if the given parameter exists but have a value which - * is not parseable as a number - */ - public final Long getLong(String name, Long defaultValue) { - return asLong(get(name), defaultValue); - } - - protected final Long asLong(Object value, Long defaultValue) { - try { - if (value == null) - return defaultValue; - - if (value instanceof Long) - return (Long) value; - - String stringValue = value.toString(); - if (stringValue.isEmpty()) - return defaultValue; - - return Long.valueOf(value.toString()); - } catch (IllegalArgumentException e) { - throw new NumberFormatException("Not a valid long"); - } - } - - /** - * Returns a property as a Double - * - * @return the double value of the name, or null if the property is null - * @throws NumberFormatException if the given parameter exists but have a value which - * is not parseable as a number - */ - public final Double getDouble(CompoundName name) { - return getDouble(name, null); - } - - /** - * Returns a property as a Double - * - * @return the double value of the name, or null if the property is null - * @throws NumberFormatException if the given parameter exists but have a value which - * is not parseable as a number - */ - public final Double getDouble(String name) { - return getDouble(name, null); - } - - /** - * Returns a property as a Double - * - * @param name the property name - * @param defaultValue the value to return if this property is null - * @return the integer value for this name - * @throws NumberFormatException if the given parameter exists but have a value which - * is not parseable as a number - */ - public final Double getDouble(CompoundName name, Double defaultValue) { - return asDouble(get(name), defaultValue); - } - - /** - * Returns a property as a Double - * - * @param name the property name - * @param defaultValue the value to return if this property is null - * @return the integer value for this name - * @throws NumberFormatException if the given parameter exists but have a value which - * is not parseable as a number - */ - public final Double getDouble(String name, Double defaultValue) { - return asDouble(get(name), defaultValue); - } - - protected final Double asDouble(Object value, Double defaultValue) { - try { - if (value == null) - return defaultValue; - - if (value instanceof Double) - return (Double) value; - - String stringValue = value.toString(); - if (stringValue.isEmpty()) - return defaultValue; - - return Double.valueOf(value.toString()); - } catch (IllegalArgumentException e) { - throw new NumberFormatException("Not a valid double"); - } - } - - /** - * Clones this instance and recursively all chained instance. - * Implementations should call this and clone their own state as appropriate - */ - public Properties clone() { - try { - Properties clone = (Properties) super.clone(); - if (chained != null) - clone.chained = this.chained.clone(); - return clone; - } catch (CloneNotSupportedException e) { - throw new RuntimeException("Will never happen"); - } - } - - /** Clones a map by deep cloning each value which is cloneable and shallow copying all other values. */ - public static Map<CompoundName, Object> cloneMap(Map<CompoundName, Object> map) { - return cloneHelper.cloneMap(map); - } - - /** Clones this object if it is clonable, and the clone is public. Returns null if not */ - public static Object clone(Object object) { - return cloneHelper.clone(object); - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/request/package-info.java b/processing/src/main/java/com/yahoo/processing/request/package-info.java deleted file mode 100644 index 96e82294075..00000000000 --- a/processing/src/main/java/com/yahoo/processing/request/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -@PublicApi package com.yahoo.processing.request; - -import com.yahoo.api.annotations.PublicApi; -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/processing/src/main/java/com/yahoo/processing/request/properties/PropertyMap.java b/processing/src/main/java/com/yahoo/processing/request/properties/PropertyMap.java deleted file mode 100644 index 54e5aae42cc..00000000000 --- a/processing/src/main/java/com/yahoo/processing/request/properties/PropertyMap.java +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request.properties; - -import com.yahoo.processing.request.CompoundName; -import com.yahoo.processing.request.Properties; - -import java.util.HashMap; -import java.util.Map; - -/** - * A HashMap backing of Properties. - * <p> - * When this is cloned it will deep copy not only the model object map, but also each - * clonable member inside the map. - * <p> - * Subclassing is supported, a hook can be implemented to provide conditional inclusion in the map. - * By default - all properties are accepted, so set is never propagated. - * <p> - * This class is not multithread safe. - * - * @author bratseth - */ -public class PropertyMap extends Properties { - - /** - * The properties of this - */ - private Map<CompoundName, Object> properties = new HashMap<>(); - - public void set(CompoundName name, Object value, Map<String, String> context) { - if (shouldSet(name, value)) - properties.put(name, value); - else - super.set(name, value, context); - } - - /** - * Return true if this value should be set in this map, false if the set should be propagated instead - * This default implementation always returns true. - */ - protected boolean shouldSet(CompoundName name, Object value) { - return true; - } - - public - @Override - Object get(CompoundName name, Map<String, String> context, - com.yahoo.processing.request.Properties substitution) { - if (!properties.containsKey(name)) return super.get(name, context, substitution); - return properties.get(name); - } - - public - @Override - PropertyMap clone() { - PropertyMap clone = (PropertyMap) super.clone(); - clone.properties = cloneMap(this.properties); - return clone; - } - - @Override - public Map<String, Object> listProperties(CompoundName path, Map<String, String> context, Properties substitution) { - Map<String, Object> map = super.listProperties(path, context, substitution); - - for (Map.Entry<CompoundName, Object> entry : properties.entrySet()) { - if ( ! entry.getKey().hasPrefix(path)) continue; - CompoundName propertyName = entry.getKey().rest(path.size()); - if (propertyName.isEmpty()) continue; - map.put(propertyName.toString(), entry.getValue()); - } - return map; - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/request/properties/PublicCloneable.java b/processing/src/main/java/com/yahoo/processing/request/properties/PublicCloneable.java deleted file mode 100644 index 785c3f08fa8..00000000000 --- a/processing/src/main/java/com/yahoo/processing/request/properties/PublicCloneable.java +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request.properties; - -/** - * This interface publicly exposes the clone method. - * Classes which are used in request properties may implement this to allow faster cloning of the request. - * - * @author bratseth - * @since 5.66 - */ -public interface PublicCloneable<T> extends Cloneable { - - public T clone(); - -} diff --git a/processing/src/main/java/com/yahoo/processing/request/properties/package-info.java b/processing/src/main/java/com/yahoo/processing/request/properties/package-info.java deleted file mode 100644 index bc0feb08411..00000000000 --- a/processing/src/main/java/com/yahoo/processing/request/properties/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -@PublicApi package com.yahoo.processing.request.properties; - -import com.yahoo.api.annotations.PublicApi; -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/processing/src/main/java/com/yahoo/processing/response/AbstractData.java b/processing/src/main/java/com/yahoo/processing/response/AbstractData.java deleted file mode 100644 index 341c6c800a5..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/AbstractData.java +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.response; - -import com.yahoo.component.provider.ListenableFreezableClass; -import com.yahoo.processing.Request; - -/** - * Convenience superclass for implementations of data. This contains no payload. - * - * @author bratseth - */ -public abstract class AbstractData extends ListenableFreezableClass implements Data { - - private Request request; - - /** - * Creates some data marked with the request that created it - */ - public AbstractData(Request request) { - this.request = request; - } - - /** - * Returns the request that created this data - */ - public Request request() { - return request; - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/response/AbstractDataList.java b/processing/src/main/java/com/yahoo/processing/response/AbstractDataList.java deleted file mode 100644 index 150d1e25d0a..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/AbstractDataList.java +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.response; - -import com.google.common.util.concurrent.AbstractFuture; -import com.google.common.util.concurrent.ExecutionList; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; -import com.yahoo.component.provider.ListenableFreezableClass; -import com.yahoo.processing.Request; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -/** - * A convenience superclass for dataList implementations which handles references to the request and to incoming data. - * - * @author bratseth - */ -public abstract class AbstractDataList<DATATYPE extends Data> extends ListenableFreezableClass implements DataList<DATATYPE>, Streamed, Ordered { - - private final boolean ordered; - private final boolean streamed; - - /** - * The request which caused this to be created - */ - private final Request request; - - /** - * The recipient of incoming data to this. Never null, but may be a null recipient. - */ - private final IncomingData<DATATYPE> incomingData; - - private final ListenableFuture<DataList<DATATYPE>> completedFuture; - - /** - * Creates a simple data list which does not allow late incoming data - * - * @param request the request which created this data list - */ - protected AbstractDataList(Request request) { - // Cannot call the constructor below because this must be given out below - this.request = request; - this.incomingData = new IncomingData.NullIncomingData<>(this); - this.completedFuture = new DrainOnGetFuture<>(this); - ordered = true; - streamed = true; - } - - /** - * Creates a simple data list which receives incoming data in the given instance - * - * @param request the request which created this data list, never null - * @param incomingData the recipient of incoming data to this list, never null - */ - protected AbstractDataList(Request request, IncomingData<DATATYPE> incomingData) { - this(request, incomingData, true, true); - } - - /** - * Creates a simple data list which receives incoming data in the given instance - * - * @param request the request which created this data list, never null - * @param incomingData the recipient of incoming data to this list, never null - */ - protected AbstractDataList(Request request, IncomingData<DATATYPE> incomingData, boolean ordered, boolean streamed) { - if (request == null) throw new NullPointerException("Request cannot be null"); - if (incomingData == null) throw new NullPointerException("incomingData cannot be null"); - - this.request = request; - this.incomingData = incomingData; - this.completedFuture = new DrainOnGetFuture<>(this); - this.ordered = ordered; - this.streamed = streamed; - } - - /** - * Returns the request which created this data - */ - public Request request() { - return request; - } - - /** - * Returns the holder of incoming data to this. - * This may be used to add, consume, wait for and be notified about incoming data. - * If this instance does not support late incoming data, the read methods of the return object behaves - * as expected and is synchronization free. The write methods throws an exception. - */ - public IncomingData<DATATYPE> incoming() { - return incomingData; - } - - public ListenableFuture<DataList<DATATYPE>> complete() { - return completedFuture; - } - - @Override - public boolean isOrdered() { return ordered; } - - @Override - public boolean isStreamed() { return streamed; } - - public String toString() { - return super.toString() + (complete().isDone() ? " [completed]" : " [incomplete, " + incoming() + "]"); - } - - public static final class DrainOnGetFuture<DATATYPE extends Data> extends AbstractFuture<DataList<DATATYPE>> { - - private final DataList<DATATYPE> owner; - - public DrainOnGetFuture(DataList<DATATYPE> owner) { - this.owner = owner; - } - - /** - * Returns false as this is not cancellable - */ - @Override - public boolean cancel(boolean b) { - return false; - } - - /** - * Returns false as this is not cancellable - */ - @Override - public boolean isCancelled() { - return false; - } - - /** - * Wait until all data is available. When this returns all data is available in the returned data list. - */ - @Override - public DataList<DATATYPE> get() throws InterruptedException, ExecutionException { - return drain(owner.incoming().completed().get()); - } - - /** - * Wait until all data is available. - * When and if this returns normally all data is available in the returned data list - */ - @Override - public DataList<DATATYPE> get(long timeout, TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException { - return drain(owner.incoming().completed().get(timeout, timeUnit)); - } - - private DataList<DATATYPE> drain(DataList<DATATYPE> dataList) { - for (DATATYPE item : dataList.incoming().drain()) - dataList.add(item); - set(dataList); // Signal completion to listeners - return dataList; - } - - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/response/ArrayDataList.java b/processing/src/main/java/com/yahoo/processing/response/ArrayDataList.java deleted file mode 100644 index 8987b8998af..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/ArrayDataList.java +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.response; - -import com.yahoo.collections.FreezableArrayList; -import com.yahoo.processing.Request; - -import java.util.List; - -/** - * A data list backed by an array. - * This implementation supports subclassing. - * - * @author bratseth - */ -public class ArrayDataList<DATATYPE extends Data> extends AbstractDataList<DATATYPE> { - - private final FreezableArrayList<DATATYPE> dataList = new FreezableArrayList<>(true); - - /** - * Creates a simple data list which does not allow late incoming data - * - * @param request the request which created this data list - */ - protected ArrayDataList(Request request) { - super(request); - } - - /** - * Creates a simple data list which receives incoming data in the given instance - * - * @param request the request which created this data list, never null - * @param incomingData the recipient of incoming data to this list, never null - */ - protected ArrayDataList(Request request, IncomingData<DATATYPE> incomingData) { - this(request, incomingData, true, true); - } - - /** - * Creates a simple data list which receives incoming data in the given instance - * - * @param request the request which created this data list, never null - * @param incomingData the recipient of incoming data to this list, never null - */ - protected ArrayDataList(Request request, IncomingData<DATATYPE> incomingData, boolean ordered, boolean streamed) { - super(request, incomingData, ordered, streamed); - } - - /** - * Creates a simple data list which does not allow late incoming data - * - * @param request the request which created this data list - */ - public static <DATATYPE extends Data> ArrayDataList<DATATYPE> create(Request request) { - return new ArrayDataList<>(request); - } - - /** - * Creates an instance of this which supports incoming data through the default mechanism (DefaultIncomingData) - */ - public static <DATATYPE extends Data> ArrayDataList<DATATYPE> createAsync(Request request) { - DefaultIncomingData<DATATYPE> incomingData = new DefaultIncomingData<>(); - ArrayDataList<DATATYPE> dataList = new ArrayDataList<>(request, incomingData); - incomingData.assignOwner(dataList); - return dataList; - } - - /** - * Creates an instance of this which supports incoming data through the default mechanism (DefaultIncomingData), - * and where this data can be rendered in any order. - */ - public static <DATATYPE extends Data> ArrayDataList<DATATYPE> createAsyncUnordered(Request request) { - DefaultIncomingData<DATATYPE> incomingData = new DefaultIncomingData<>(); - ArrayDataList<DATATYPE> dataList = new ArrayDataList<>(request, incomingData, false, true); - incomingData.assignOwner(dataList); - return dataList; - } - - /** - * Creates an instance of this which supports incoming data through the default mechanism (DefaultIncomingData) - * and where this data cannot be returned to clients until this is completed. - */ - public static <DATATYPE extends Data> ArrayDataList<DATATYPE> createAsyncNonstreamed(Request request) { - DefaultIncomingData<DATATYPE> incomingData = new DefaultIncomingData<>(); - ArrayDataList<DATATYPE> dataList = new ArrayDataList<>(request, incomingData, true, false); - incomingData.assignOwner(dataList); - return dataList; - } - - public DATATYPE add(DATATYPE data) { - dataList.add(data); - return data; - } - - /** - * Returns the data element at index - */ - public DATATYPE get(int index) { - return dataList.get(index); - } - - /** - * Returns a reference to the list backing this. The list may be modified freely, - * unless this is frozen. If frozen, the only permissible write operations are those that - * add new items to the end of the list. - */ - public List<DATATYPE> asList() { - return dataList; - } - - @Override - public void addDataListener(Runnable runnable) { - dataList.addListener(runnable); - } - - /** - * Irreversibly prevent further changes to the items of this. - * This allows the processing engine to start streaming the current content of this list back to the - * client (if applicable). - * <p> - * Adding new items to the end of this list is permitted even after freeze. - * If frozen, those items may be streamed back to the client immediately on add. - * <p> - * Calling this on a frozen list has no effect. - */ - public void freeze() { - super.freeze(); - dataList.freeze(); - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/response/Data.java b/processing/src/main/java/com/yahoo/processing/response/Data.java deleted file mode 100644 index ff48f1e86b6..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/Data.java +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.response; - -import com.yahoo.component.provider.ListenableFreezable; -import com.yahoo.processing.Request; - -/** - * A data item created due to a processing request. - * <p> - * If a data item is <i>frozen</i> it is illegal to make further changes to its payload or referenced request. - * - * @author bratseth - */ -// TODO: Have DataList implement this instead, probably (should be a safe change in practise) -public interface Data extends ListenableFreezable { - - /** Returns the request that created this data */ - Request request(); - -} diff --git a/processing/src/main/java/com/yahoo/processing/response/DataList.java b/processing/src/main/java/com/yahoo/processing/response/DataList.java deleted file mode 100644 index ff67dd82aa7..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/DataList.java +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.response; - -import com.google.common.util.concurrent.ExecutionList; -import com.google.common.util.concurrent.ListenableFuture; - -import java.util.List; -import java.util.concurrent.Executor; - -/** - * A list of data items created due to a processing request. - * This list is itself a data item, allowing data items to be organized into a composite tree. - * <p> - * A data list can be frozen even though its child data items are not. - * When a datalist is frozen the only permissible write operation is to add new items - * to the end of the list. - * <p> - * Content in a frozen list may be returned to the requesting client immediately by the underlying engine, - * even if the Response owning the list is not returned yet. - * - * @author bratseth - */ -public interface DataList<DATATYPE extends Data> extends Data { - - /** - * Adds a child data item to this. - * - * @param data the data to add to this - * @return the input data instance, for chaining - */ - DATATYPE add(DATATYPE data); - - DATATYPE get(int index); - - /** - * Returns the content of this as a List. - * The returned list is either a read-only snapshot or an editable reference to the content of this. - * If the returned list is editable and this is frozen, the only allowed operation is to add new items - * to the end of the list. - */ - List<DATATYPE> asList(); - - /** - * Returns the buffer of incoming/future data to this list. - * This can be used to provide data to this list from other threads, after its creation, - * and to consume, wait for, or be notified upon the arrival of such data. - * <p> - * Some list instances do not support late incoming data, - * such lists responds to <i>read</i> calls to IncomingData as expected and without - * incurring any synchronization, and throws an exception on <i>write</i> calls. - */ - IncomingData<DATATYPE> incoming(); - - /** - * Returns a future in which all incoming data in this has become available. - * This has two uses: - * <ul> - * <li>Calling {@link #get} on this future will block (if necessary) until all incoming data has arrived, - * transfer that data from the incoming buffer into this list and invoke any listeners on this event - * on the calling thread. - * <li>Adding a listener on this future will cause it to be called when completion().get() is called, <i>after</i> - * the incoming data has been moved to this thread and <i>before</i> the get() call returns. - * </ul> - * <p> - * Note that if no thread calls completed().get(), this future will never occur. - * <p> - * Any data list consumer who wishes to make sure it sees the complete data for this list - * <i>must</i> call <code>dataList.complete().get()</code> before consuming this list. - * If a guaranteed non-blocking call to this method is desired, register a listener on the future where all - * data is available for draining (that is, on <code>dataList.incoming().completed()</code>) - * and resume by calling this method from the listener. - * <p> - * Making this call on a list which does not support future data always returns immediately and - * causes no memory synchronization cost. - */ - ListenableFuture<DataList<DATATYPE>> complete(); - - /** - * Adds a listener which is invoked every time data is added to this list. - * The listener is always invoked on the same thread which is adding the data, - * and hence it can modify this list freely without synchronization. - */ - void addDataListener(Runnable runnable); - - /** - * Notify this list that is will never be accessed again, neither for read nor write. - * Implementations can override this as an optimization to release any data held in the list - * for garbage collection. - * - * This default implementation does nothing. - */ - default void close() {}; - -} diff --git a/processing/src/main/java/com/yahoo/processing/response/DefaultIncomingData.java b/processing/src/main/java/com/yahoo/processing/response/DefaultIncomingData.java deleted file mode 100644 index c436f92f78b..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/DefaultIncomingData.java +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.response; - -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; -import com.yahoo.collections.Tuple2; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.Executor; - -/** - * The default incoming data implementation - * - * @author bratseth - */ -public class DefaultIncomingData<DATATYPE extends Data> implements IncomingData<DATATYPE> { - - private DataList<DATATYPE> owner = null; - - private final SettableFuture<DataList<DATATYPE>> completionFuture; - - private final List<DATATYPE> dataList = new ArrayList<>(); - - private List<Tuple2<Runnable,Executor>> newDataListeners = null; - - /** Whether this is completed, such that no more data can be added */ - private boolean complete = false; - - /** Creates an instance which must be assigned an owner after creation */ - public DefaultIncomingData() { - this(null); - } - - public DefaultIncomingData(DataList<DATATYPE> owner) { - assignOwner(owner); - completionFuture = SettableFuture.create(); - } - - /** Assigns the owner of this. Throws an exception if the owner is already set. */ - public final void assignOwner(DataList<DATATYPE> owner) { - if (this.owner != null) throw new NullPointerException("Owner of " + this + " was already assigned"); - this.owner = owner; - } - - @Override - public DataList<DATATYPE> getOwner() { - return owner; - } - - @Override - public ListenableFuture<DataList<DATATYPE>> completed() { - return completionFuture; - } - - /** Returns whether the data in this is complete */ - @Override - public synchronized boolean isComplete() { - return complete; - } - - /** Adds new data and marks this as completed */ - @Override - public synchronized void addLast(DATATYPE data) { - addLast(Collections.singletonList(data)); - } - - /** Adds new data without completing this */ - @Override - public synchronized void add(DATATYPE data) { - add(Collections.singletonList(data)); - } - - /** Adds new data and marks this as completed */ - @Override - public synchronized void addLast(List<DATATYPE> data) { - add(data); - markComplete(); - } - - /** Adds new data without completing this */ - @Override - public synchronized void add(List<DATATYPE> data) { - if (complete) throw new IllegalStateException("Attempted to add data to completed " + this); - - dataList.addAll(data); - notifyDataListeners(); - } - - /** Marks this as completed and notify any listeners */ - @Override - public synchronized void markComplete() { - complete = true; - completionFuture.set(owner); - } - - /** - * Gets and removes all the data currently available in this. - * The returned list is a modifiable fresh instance owned by the caller. - */ - public synchronized List<DATATYPE> drain() { - List<DATATYPE> dataListCopy = new ArrayList<>(dataList); - dataList.clear(); - return dataListCopy; - } - - @Override - public void addNewDataListener(Runnable listener, Executor executor) { - synchronized (this) { - if (newDataListeners == null) - newDataListeners = new ArrayList<>(); - newDataListeners.add(new Tuple2<>(listener, executor)); - if (dataList.isEmpty()) return; - } - notifyDataListeners(); - } - - private void notifyDataListeners() { - if (newDataListeners == null) return; - for (Tuple2<Runnable, Executor> listener : newDataListeners) { - listener.second.execute(listener.first); - } - } - - @Override - public String toString() { - return "incoming: " + (complete ? "complete" : "incomplete") + ", data " + dataList; - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/response/FutureResponse.java b/processing/src/main/java/com/yahoo/processing/response/FutureResponse.java deleted file mode 100644 index 21877dfc8c3..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/FutureResponse.java +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.response; - -import com.google.common.util.concurrent.ForwardingFuture; -import com.google.common.util.concurrent.ListenableFutureTask; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.execution.Execution; -import com.yahoo.processing.request.ErrorMessage; - -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * A processing response which will arrive in the future. - * - * @author bratseth - */ -public class FutureResponse extends ForwardingFuture<Response> { - - private final Request request; - - /** - * Only used for generating messages - */ - private final Execution execution; - - private final static Logger log = Logger.getLogger(FutureResponse.class.getName()); - - private final ListenableFutureTask<Response> futureTask; - - public FutureResponse(final Callable<Response> callable, Execution execution, final Request request) { - this.futureTask = ListenableFutureTask.create(callable); - this.request = request; - this.execution = execution; - } - - @Override - public ListenableFutureTask<Response> delegate() { - return futureTask; - } - - public - @Override - Response get() { - try { - return super.get(); - } catch (InterruptedException e) { - return new Response(request, new ErrorMessage("'" + execution + "' was interrupted", e)); - } catch (ExecutionException e) { - log.log(Level.WARNING, "Exception on executing " + execution + " for " + request, e); - return new Response(request, new ErrorMessage("Error in '" + execution + "'", e)); - } - } - - public - @Override - Response get(long timeout, TimeUnit timeunit) { - try { - return super.get(timeout, timeunit); - } catch (InterruptedException e) { - return new Response(request, new ErrorMessage("'" + execution + "' was interrupted", e)); - } catch (ExecutionException e) { - log.log(Level.WARNING, "Exception on executing " + execution + " for " + request, e); - return new Response(request, new ErrorMessage("Error in '" + execution + "'", e)); - } catch (TimeoutException e) { - return new Response(request, new ErrorMessage("Error executing '" + execution + "': " + " Chain timed out.")); - } - } - - /** - * Returns the query used in this execution, never null - */ - public Request getRequest() { - return request; - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/response/IncomingData.java b/processing/src/main/java/com/yahoo/processing/response/IncomingData.java deleted file mode 100644 index b8cdf8683bc..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/IncomingData.java +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.response; - -import com.google.common.util.concurrent.AbstractFuture; -import com.google.common.util.concurrent.ListenableFuture; - -import java.util.Collections; -import java.util.List; -import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; - -/** - * A data list own once instance of this which can be used to provide data asynchronously to the list, - * and consume, wait for or be notified upon the arrival of such data. - * - * @author bratseth - */ -public interface IncomingData<DATATYPE extends Data> { - - /** - * Returns the owner (target DataList) of this. - * Note that accessing the owner from the thread producing incoming data - * is generally *not* thread safe. - */ - DataList<DATATYPE> getOwner(); - - /** - * Returns a future in which all the incoming data that will be produced in this is available. - * Listeners on this are invoked on the thread producing the incoming data (or a thread spawned from it), - * which in general is separate from the thread using the data list. Hence, listeners on this even cannot - * in general assume that they may modify the data list or the request. - * <p> - * The data is not {@link #drain drained} into the owner of this by this method. That must be done - * by the thread using the data list. - * <p> - * This return the list owning this for convenience. - */ - ListenableFuture<DataList<DATATYPE>> completed(); - - /** - * Returns whether this is complete - */ - boolean isComplete(); - - /** - * Add new data and mark this as completed - * - * @throws IllegalStateException if this is already complete or does not allow writes - */ - void addLast(DATATYPE data); - - /** - * Add new data without completing this - * - * @throws IllegalStateException if this is already complete or does not allow writes - */ - void add(DATATYPE data); - - /** - * Add new data and mark this as completed - * - * @throws IllegalStateException if this is already complete or does not allow writes - */ - void addLast(List<DATATYPE> data); - - /** - * Add new data without completing this. - * - * @throws IllegalStateException if this is already complete or does not allow writes - */ - void add(List<DATATYPE> data); - - /** - * Mark this as completed and notify any listeners. If this is already complete this method does nothing. - */ - void markComplete(); - - /** - * Get and remove all the data currently available in this - */ - List<DATATYPE> drain(); - - /** - * Add a listener which will be invoked every time new data is added to this. - * This listener may be invoked at any time in any thread, any thread synchronization is left - * to the listener itself - */ - void addNewDataListener(Runnable listener, Executor executor); - - /** - * Creates a null implementation of this which is empty and complete at creation: - * <ul> - * <li>Provides immediate return without incurring any memory synchronization for - * any read method. - * <li>Throws an exception on any write method - * </ul> - * <p> - * This allows consumers to check for completion the same way whether or not the data list in question - * supports asynchronous addition of data, and without incurring unnecessary costs. - */ - final class NullIncomingData<DATATYPE extends Data> implements IncomingData<DATATYPE> { - - private DataList<DATATYPE> owner; - private final ImmediateFuture<DATATYPE> completionFuture; - - public NullIncomingData(DataList<DATATYPE> owner) { - this.owner = owner; - completionFuture = new ImmediateFuture<>(owner); - } - - public ListenableFuture<DataList<DATATYPE>> completed() { - return completionFuture; - } - - @Override - public DataList<DATATYPE> getOwner() { - return owner; - } - - /** - * Returns true - */ - @Override - public boolean isComplete() { - return true; - } - - /** - * @throws IllegalStateException as this is read only - */ - public void addLast(DATATYPE data) { - throw new IllegalStateException(owner + " does not support adding data asynchronously"); - } - - /** - * @throws IllegalStateException as this is read only - */ - public void add(DATATYPE data) { - throw new IllegalStateException(owner + " does not support adding data asynchronously"); - } - - /** - * @throws IllegalStateException as this is read only - */ - public void addLast(List<DATATYPE> data) { - throw new IllegalStateException(owner + " does not support adding data asynchronously"); - } - - /** - * @throws IllegalStateException as this is read only - */ - public void add(List<DATATYPE> data) { - throw new IllegalStateException(owner + " does not support adding data asynchronously"); - } - - /** - * Do nothing as this is already complete - */ - public void markComplete() { - } - - public List<DATATYPE> drain() { - return Collections.emptyList(); - } - - /** - * Adds a new data listener to this - this is a no-op - * as new data can never be added to this implementation. - */ - public void addNewDataListener(Runnable listener, Executor executor) { } - - public String toString() { - return "(no incoming)"; - } - - /** - * A future which is always done and incurs no synchronization. - * This is semantically the same as Futures.immediateFuture but contrary to it, - * this never causes any memory synchronization when accessed. - */ - public static class ImmediateFuture<DATATYPE extends Data> extends AbstractFuture<DataList<DATATYPE>> { - - private DataList<DATATYPE> owner; - - public ImmediateFuture(DataList<DATATYPE> owner) { - this.owner = owner; // keep here to avoid memory synchronization for access - set(owner); // Signal completion (for future listeners) - } - - @Override - public boolean cancel(boolean b) { - return false; - } - - @Override - public boolean isCancelled() { - return false; - } - - @Override - public boolean isDone() { - return true; - } - - @Override - public DataList<DATATYPE> get() { - return owner; - } - - @Override - public DataList<DATATYPE> get(long l, TimeUnit timeUnit) { - return owner; - } - - } - - } - -} diff --git a/processing/src/main/java/com/yahoo/processing/response/Ordered.java b/processing/src/main/java/com/yahoo/processing/response/Ordered.java deleted file mode 100644 index dc969f7acef..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/Ordered.java +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.response; - -/** - * This is an <i>optional marker interface</i>. - * DataLists may implement this to return false to indicate that the order of the elements of - * the list is insignificant. The usage of this is to allow the content of a list to be rendered in the order - * in which it completes rather than in the order in which it is added to the list. - * - * @author bratseth - * @since 5.1.19 - */ -public interface Ordered { - - /** Returns false if the data in this list can be returned in any order. Default: true, meaning the order matters */ - public boolean isOrdered(); - -} diff --git a/processing/src/main/java/com/yahoo/processing/response/Streamed.java b/processing/src/main/java/com/yahoo/processing/response/Streamed.java deleted file mode 100644 index 2aae03104be..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/Streamed.java +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.response; - -/** - * This is an <i>optional marker interface</i>. - * DataLists may implement this to return false to indicate that no data from the list should be returned to clients - * until it is completed. This is useful in cases where some decision making which may impact the content of the list - * must be deferred until the list is complete. - * - * @author bratseth - * @since 5.1.19 - */ -public interface Streamed { - - /** - * Returns false if the data in this list can not be returned until it is completed. - * Default: true, meaning eager streaming of the data is permissible. - */ - public boolean isStreamed(); - -} diff --git a/processing/src/main/java/com/yahoo/processing/response/package-info.java b/processing/src/main/java/com/yahoo/processing/response/package-info.java deleted file mode 100644 index 204b0e04393..00000000000 --- a/processing/src/main/java/com/yahoo/processing/response/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -@ExportPackage -@PublicApi package com.yahoo.processing.response; - -import com.yahoo.api.annotations.PublicApi; -import com.yahoo.osgi.annotation.ExportPackage; diff --git a/processing/src/main/java/com/yahoo/processing/test/ProcessorLibrary.java b/processing/src/main/java/com/yahoo/processing/test/ProcessorLibrary.java deleted file mode 100644 index 5f6201c6f2d..00000000000 --- a/processing/src/main/java/com/yahoo/processing/test/ProcessorLibrary.java +++ /dev/null @@ -1,556 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.test; - -import com.google.common.util.concurrent.MoreExecutors; -import com.google.common.util.concurrent.SettableFuture; -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.execution.AsyncExecution; -import com.yahoo.processing.execution.Execution; -import com.yahoo.processing.execution.ExecutionWithResponse; -import com.yahoo.processing.execution.RunnableExecution; -import com.yahoo.processing.request.ErrorMessage; -import com.yahoo.processing.response.*; - -import java.util.*; -import java.util.concurrent.ExecutionException; - -/** - * A collection of processors for test purposes. - * - * @author bratseth - */ -public class ProcessorLibrary { - - private ProcessorLibrary() { - } - - // ---------------------------------------- Data types - - public static class StringData extends AbstractData { - - private String string; - - public StringData(Request request, String string) { - super(request); - this.string = string; - } - - public void setString(String string) { - this.string = string; - } - - @Override - public String toString() { - return string; - } - - } - - public static class MapData extends AbstractData { - - private Map map = new LinkedHashMap(); - - public MapData(Request request) { - super(request); - } - - public Map map() { return map; } - - @Override - public String toString() { - return "map data: " + map; - } - - } - - // ---------------------------------------- DataLists - - public static class UnorderedArrayDataList extends ArrayDataList implements Ordered { - - public UnorderedArrayDataList(Request request) { - super(request); - } - - @Override - public boolean isOrdered() {return false; } - - } - - // ---------------------------------------- Processors - - /** - * Makes some modifications to the request, passes it on and finally removes one data item from the response - */ - public static class CombineData extends Processor { - - public Response process(Request request, Execution execution) { - request.properties().set("appendage", request.properties().getInteger("appendage") + 1); - Response response = execution.process(request); - - // Modify the response - StringData first = (StringData) response.data().get(0); - StringData third = (StringData) response.data().get(2); - first.setString(first.toString() + ", " + third.toString()); - response.data().asList().remove(2); - return response; - } - - } - - /** - * Sends the request multiple times to get at least 6 pieces of data - */ - public static class Get6DataItems extends Processor { - - @SuppressWarnings("unchecked") - public Response process(Request request, Execution execution) { - Response response = execution.process(request); - while (response.data().asList().size() < 6) { - request.properties().set("appendage", request.properties().getInteger("appendage") + 1); - Response additional = execution.process(request); - response.mergeWith(additional); - response.data().asList().addAll(additional.data().asList()); - } - return response; - } - - } - - /** - * Produces 3 pieces of string data - */ - public static class DataSource extends Processor { - - @SuppressWarnings("unchecked") - public Response process(Request request, Execution execution) { - Response response = execution.process(request); - response.data().add(new StringData(request, "first." + request.properties().get("appendage"))); - response.data().add(new StringData(request, "second." + request.properties().get("appendage"))); - response.data().add(new StringData(request, "third." + request.properties().get("appendage"))); - return response; - } - - } - - public static class Federator extends Processor { - - private final List<Chain<? extends Processor>> chains; - - private final boolean ordered; - - /** - * Federates over the given chains. Returns an ordered response. - */ - @SafeVarargs - public Federator(Chain<? extends Processor>... chains) { - this(true, chains); - } - - /** - * Federates over the given chains - * - * @param ordered true if the returned list should be ordered (default), false if it should be permissible - * to render the datalist from each federated source in the order it completes. - */ - @SafeVarargs - @SuppressWarnings("varargs") - public Federator(boolean ordered, Chain<? extends Processor>... chains) { - this.chains = Arrays.asList(chains); - this.ordered = ordered; - } - - @SuppressWarnings("unchecked") - @Override - public Response process(Request request, Execution execution) { - Response response = ordered ? new Response(request) : new Response(new UnorderedArrayDataList(request)); - - List<FutureResponse> futureResponses = new ArrayList<>(chains.size()); - for (Chain<? extends Processor> chain : chains) { - - futureResponses.add(new AsyncExecution(chain, execution).process(request.clone())); - } - AsyncExecution.waitForAll(futureResponses, 1000); - for (FutureResponse futureResponse : futureResponses) { - Response federatedResponse = futureResponse.get(); - response.data().add(federatedResponse.data()); - response.mergeWith(federatedResponse); - } - return response; - } - } - - /** - * A federator which supports returning frozen data from each chain before the response is returned. - */ - public static class EagerReturnFederator extends Processor { - - private final List<Chain<? extends Processor>> chains; - - private final boolean ordered; - - /** - * Federates over the given chains. Returns an ordered response. - */ - @SafeVarargs - public EagerReturnFederator(Chain<? extends Processor>... chains) { - this(true, chains); - } - - /** - * Federates over the given chains - * - * @param ordered true if the returned list should be ordered (default), false if it should be permissible - * to render the datalist from each federated source in the order it completes. - */ - @SafeVarargs - @SuppressWarnings("varargs") - public EagerReturnFederator(boolean ordered, Chain<? extends Processor>... chains) { - this.chains = Arrays.asList(chains); - this.ordered = ordered; - } - - @SuppressWarnings("unchecked") - @Override - public Response process(Request request, Execution execution) { - List<FutureResponse> futureResponses = new ArrayList<>(chains.size()); - for (Chain<? extends Processor> chain : chains) { - futureResponses.add(new AsyncExecution(chain, execution).process(request.clone())); - } - AsyncExecution.waitForAll(futureResponses, 1000); - Response response = ordered ? new Response(request) : new Response(new UnorderedArrayDataList(request)); - for (FutureResponse futureResponse : futureResponses) { - Response federatedResponse = futureResponse.get(); - response.data().add(federatedResponse.data()); - response.mergeWith(federatedResponse); - } - return response; - } - } - - /** - * Adds a data element containing the (recursive) count of concrete (non-list) data elements in the response - */ - public static class DataCounter extends Processor { - - private String prefix = ""; - - public DataCounter() { - } - - /** - * The prefix "[name] " is prepended to the string data - */ - public DataCounter(String name) { - prefix = "[" + name + "] "; - } - - @SuppressWarnings("unchecked") - @Override - public Response process(Request request, Execution execution) { - Response response = execution.process(request); - int dataCount = countData(response.data()); - response.data().add(new StringData(request, prefix + "Data count: " + dataCount)); - return response; - } - - private int countData(DataList<? extends Data> dataList) { - int count = 0; - for (Data data : dataList.asList()) { - if (data instanceof DataList) - count += countData((DataList<?>) data); - else - count++; - } - return count; - } - } - - // TODO: Replace by below? - public static class FutureDataSource extends Processor { - - /** The list of incoming data this has created */ - public final List<IncomingData> incomingData = new ArrayList<>(); - - @Override - public Response process(Request request, Execution execution) { - ArrayDataList dataList = ArrayDataList.createAsync(request); - incomingData.add(dataList.incoming()); - return new Response(dataList); - } - - } - - /** Allows waiting for that request to happen. */ - public static class ListenableFutureDataSource extends Processor { - - private final boolean ordered, streamed; - - /** The incoming data this has created */ - public final SettableFuture<IncomingData> incomingData = SettableFuture.create(); - - /** Create an instance which returns ordered, streamable data */ - public ListenableFutureDataSource() { this(true, true); } - - public ListenableFutureDataSource(boolean ordered, boolean streamed) { - this.ordered = ordered; - this.streamed = streamed; - } - - @Override - public Response process(Request request, Execution execution) { - ArrayDataList dataList; - if (! ordered) - dataList = ArrayDataList.createAsyncUnordered(request); - else if (! streamed) - dataList = ArrayDataList.createAsyncNonstreamed(request); - else - dataList = ArrayDataList.createAsync(request); - incomingData.set(dataList.incoming()); - return new Response(dataList); - } - - } - - /** Allows waiting for that request to happen. */ - public static class RequestCounter extends Processor { - - /** The incoming data this has created */ - public final SettableFuture<IncomingData> incomingData = SettableFuture.create(); - - @Override - public Response process(Request request, Execution execution) { - ArrayDataList dataList = ArrayDataList.createAsync(request); - incomingData.set(dataList.incoming()); - return new Response(dataList); - } - - } - - /** - * Multiples the amount of data returned by parallelism by performing parallel executions of the rest of the chain - */ - public static class BlockingSplitter extends Processor { - - private final int parallelism; - - public BlockingSplitter(int parallelism) { - this.parallelism = parallelism; - } - - @SuppressWarnings("unchecked") - @Override - public Response process(Request request, Execution execution) { - try { - // start executions in other threads - List<FutureResponse> futures = new ArrayList<>(parallelism - 1); - for (int i = 1; i < parallelism; i++) { - futures.add(new AsyncExecution(execution).process(request.clone())); - } - - // complete this execution - Response response = execution.process(request); - - // wait for other executions and merge the responses - for (Response additionalResponse : AsyncExecution.waitForAll(futures, 1000)) { - additionalResponse.data().complete().get(); // block until we have all the data elements - for (Object item : additionalResponse.data().asList()) - response.data().add((Data) item); - response.mergeWith(additionalResponse); - } - return response; - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } - } - - } - - /** - * Registers an async processing of the chain given in the constructor on completion of the data in the response - */ - public static class AsyncDataProcessingInitiator extends Processor { - - private final Chain<Processor> asyncChain; - - public AsyncDataProcessingInitiator(Chain<Processor> asyncChain) { - this.asyncChain = asyncChain; - } - - @Override - public Response process(Request request, Execution execution) { - Response response = execution.process(request); - // TODO: Consider for to best provide helpers for this - response.data().complete().addListener(new RunnableExecution(request, - new ExecutionWithResponse(asyncChain, response, execution)), - MoreExecutors.directExecutor()); - return response; - } - - } - - /** - * Registers a chain to be invoked each time new data becomes available in the first child list - */ - public static class StreamProcessingInitiator extends Processor { - - private final Chain<Processor> streamChain; - - public StreamProcessingInitiator(Chain<Processor> streamChain) { - this.streamChain = streamChain; - } - - @Override - public Response process(Request request, Execution execution) { - Response response = execution.process(request); - // TODO: Consider for to best provide helpers for this - response.data().addDataListener(new RunnableExecution(request, - new ExecutionWithResponse(streamChain, response, execution))); - return response; - } - - } - - /** - * A processor which on invocation prints the string given on construction - */ - public static class Echo extends Processor { - - private String s; - - public Echo(String s) { - this.s = s; - } - - @Override - public Response process(Request request, Execution execution) { - System.out.println(s); - return execution.process(request); - } - - } - - /** - * A processor which adds a StringData item containing the string given in the constructor to every response - */ - public static class StringDataAdder extends Processor { - - private String string; - - public StringDataAdder(String string) { - this.string = string; - } - - @SuppressWarnings("unchecked") - @Override - public Response process(Request request, Execution execution) { - Response response = execution.process(request); - response.data().add(new StringData(request, string)); - return response; - } - - } - - /** - * A processor which adds an ErrorMessage to the request of the top level - * data of each returned response. - */ - public static class ErrorAdder extends Processor { - - private ErrorMessage errorMessage; - - public ErrorAdder(ErrorMessage errorMessage) { - this.errorMessage = errorMessage; - } - - @Override - public Response process(Request request, Execution execution) { - Response response = execution.process(request); - response.data().request().errors().add(errorMessage); - return response; - } - - } - - /** - * A processor which adds a List of StringData items containing the strings given in the constructor to every response - */ - public static class StringDataListAdder extends Processor { - - private String[] strings; - - public StringDataListAdder(String... strings) { - this.strings = strings; - } - - @SuppressWarnings("unchecked") - @Override - public Response process(Request request, Execution execution) { - Response response = execution.process(request); - DataList<StringData> list = ArrayDataList.create(request); - for (String string : strings) - list.add(new StringData(request, string)); - response.data().add(list); - return response; - } - - } - - /** - * Adds a the given trace message at the given trace level - */ - public static class Trace extends Processor { - - private String traceMessage; - private int traceLevel; - - public Trace(String traceMessage, int traceLevel) { - this.traceMessage = traceMessage; - this.traceLevel = traceLevel; - } - - @Override - public Response process(Request request, Execution execution) { - execution.trace().trace(traceMessage, traceLevel); - return execution.process(request); - } - - } - - public static final class StatusSetter extends Processor { - - private final int status; - - public StatusSetter(int status) { - this.status = status; - } - - @Override - public com.yahoo.processing.Response process(com.yahoo.processing.Request request, Execution execution) { - request.errors().add(new ErrorMessage(status, "")); - return execution.process(request); - } - - } - - /** - * Adds (key, value) to the log value trace. - */ - public static class LogValueAdder extends Processor { - private final String key; - private final String value; - - public LogValueAdder(String key, String value) { - this.key = key; - this.value = value; - } - - @Override - public Response process(Request request, Execution execution) { - execution.trace().logValue(key, value); - return execution.process(request); - } - } -} diff --git a/processing/src/main/java/com/yahoo/processing/test/Responses.java b/processing/src/main/java/com/yahoo/processing/test/Responses.java deleted file mode 100644 index cabce8fc109..00000000000 --- a/processing/src/main/java/com/yahoo/processing/test/Responses.java +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.test; - -import com.yahoo.processing.response.Data; -import com.yahoo.processing.response.DataList; - -/** - * Static utilities - * - * @author bratseth - * @since 5.1.13 - */ -public class Responses { - - /** - * Returns a data item as a recursively indented string - */ - public static String recursiveToString(Data data) { - StringBuilder b = new StringBuilder(); - asString(data, b, ""); - return b.toString(); - } - - private static void asString(Data data, StringBuilder b, String indent) { - b.append(indent).append(data).append("\n"); - if (!(data instanceof DataList)) return; - for (Data childData : ((DataList<? extends Data>) data).asList()) { - asString(childData, b, indent.concat(" ")); - } - } - -} diff --git a/processing/src/main/resources/configdefinitions/container.core.chains.def b/processing/src/main/resources/configdefinitions/container.core.chains.def deleted file mode 100644 index 8520a8d6332..00000000000 --- a/processing/src/main/resources/configdefinitions/container.core.chains.def +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -# Chains configuration -namespace=container.core - -components[].id string - -# Configured functionality provided by this - comes in addition to those set in the code -components[].dependencies.provides[] string - -# Configured "before" dependencies provided by this - comes in addition to those set in the code -components[].dependencies.before[] string - -# Configured "after" dependencies provided by this - comes in addition to those set in the code -components[].dependencies.after[] string - -# The id of this chain. The id has the form name(:version)? -# where the version has the form 1(.2(.3(.identifier)?)?)?. -# The default chain must be called "default". -chains[].id string - -#The type of this chain -chains[].type enum {DOCPROC, SEARCH} default=SEARCH - -# The id of a component to include in this chain. -# The id has the form fullclassname(:version)? -# where the version has the form 1(.2(.3(.identifier)?)?)?. -chains[].components[] string - -# The optional list of chain ids this inherits. -# The ids has the form name(:version)? -# where the version has the form 1(.2(.3(.identifier)?)?)?. -# If the version is not specified the newest version is used. -chains[].inherits[] string - -# The optional list of component ids to exclude from this chain even if they exists in inherited chains -# If versions are specified in these ids, they are ignored. -chains[].excludes[] string - -# The phases for a chain -chains[].phases[].id string -chains[].phases[].before[] string -chains[].phases[].after[] string diff --git a/processing/src/test/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilderTest.java b/processing/src/test/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilderTest.java deleted file mode 100644 index 07ac302f1f3..00000000000 --- a/processing/src/test/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilderTest.java +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - -import com.yahoo.component.ComponentId; -import com.yahoo.component.chain.Chain; -import com.yahoo.component.chain.ChainedComponent; -import com.yahoo.component.chain.Phase; -import com.yahoo.component.chain.dependencies.After; -import com.yahoo.component.chain.dependencies.Before; -import com.yahoo.component.chain.dependencies.Provides; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * @author Tony Vaagenes - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -public class ChainBuilderTest { - - private void addAtoG(ChainBuilder chainBuilder) throws ReflectiveOperationException { - List<Class<? extends ChainedComponent>> componentTypes = new ArrayList<>(); - - componentTypes.add(A.class); - componentTypes.add(B.class); - componentTypes.add(C.class); - componentTypes.add(D.class); - componentTypes.add(E.class); - componentTypes.add(F.class); - componentTypes.add(G.class); - - permute(componentTypes); - - for (Class<? extends ChainedComponent> searcherClass : componentTypes) { - chainBuilder.addComponent(searcherClass.getDeclaredConstructor().newInstance()); - } - } - - - private void permute(List<Class<? extends ChainedComponent>> searcherTypes) { - for (int i=0; i<searcherTypes.size(); ++i) { - int j = (int) (Math.random() * searcherTypes.size()); - Class<? extends ChainedComponent> tmp = searcherTypes.get(i); - searcherTypes.set(i,searcherTypes.get(j)); - searcherTypes.set(j, tmp); - } - } - - @Test - public void testRegular() throws Exception { - ChainBuilder chainBuilder = createDependencyHandler(); - - addAtoG(chainBuilder); - - Chain<ChainedComponent> res = chainBuilder.orderNodes(); - - Iterator<ChainedComponent> i = res.components().iterator(); - for (char j=0; j< 'G' - 'A'; ++j) { - assertEquals(String.valueOf((char)('A' + j)), name(i.next())); - } - } - - @Test - public void testCycle() throws Exception { - - ChainBuilder chainBuilder = createDependencyHandler(); - - addAtoG(chainBuilder); - chainBuilder.addComponent(new H()); - - boolean cycle = false; - try { - chainBuilder.orderNodes(); - } catch (CycleDependenciesException e) { - cycle = true; - } - assertTrue(cycle); - } - - - @Test - public void testPhaseAndSearcher() { - ChainBuilder depHandler = newChainBuilder(); - depHandler.addPhase(new Phase("phase1", set("phase2"), Collections.<String>emptySet())); - depHandler.addPhase(new Phase("phase2", set("phase3"), set("phase1"))); - depHandler.addPhase(new Phase("phase3", Collections.<String>emptySet(), set("phase2", "phase1"))); - ChainedComponent first = new First(); - ChainedComponent second = new Second(); - - depHandler.addComponent(first); - depHandler.addComponent(second); - assertEquals(depHandler.orderNodes().components(), Arrays.asList(first, second)); - - } - - @Test - public void testInputOrderPreservedWhenProvidesOverlap() { - ChainBuilder chainBuilder = newChainBuilder(); - - A a1 = new A(); - C c = new C(); - A a2 = new A(); - - chainBuilder.addComponent(a1); - chainBuilder.addComponent(c); - chainBuilder.addComponent(a2); - - assertEquals(Arrays.asList(a1, c, a2), chainBuilder.orderNodes().components()); - } - - private ChainBuilder newChainBuilder() { - return new ChainBuilder(new ComponentId("test")); - } - - private Set<String> set(String... strings) { - return new HashSet<>(Arrays.asList(strings)); - } - - @Before("phase1") - static class First extends NoopComponent { - - } - - @After("phase3") - static class Second extends NoopComponent { - - } - - @Test - public void testAfterAll1() throws Exception { - ChainBuilder chainBuilder = createDependencyHandler(); - ChainedComponent afterAll1 = new AfterAll(); - chainBuilder.addComponent(afterAll1); - addAtoG(chainBuilder); - - List<ChainedComponent> resolution= chainBuilder.orderNodes().components(); - assertEquals(afterAll1,resolution.get(resolution.size()-1)); - } - - @Test - public void testAfterAll2() throws Exception { - ChainBuilder chainBuilder = createDependencyHandler(); - addAtoG(chainBuilder); - ChainedComponent afterAll1 = new AfterAll(); - chainBuilder.addComponent(afterAll1); - - List<ChainedComponent> resolution = chainBuilder.orderNodes().components(); - assertEquals(afterAll1,resolution.get(resolution.size()-1)); - } - - @Test - public void testAfterImplicitProvides() - throws InstantiationException, IllegalAccessException { - ChainBuilder chainBuilder = createDependencyHandler(); - ChainedComponent afterProvidesNothing=new AfterProvidesNothing(); - ChainedComponent providesNothing=new ProvidesNothing(); - chainBuilder.addComponent(afterProvidesNothing); - chainBuilder.addComponent(providesNothing); - List<ChainedComponent> resolution = chainBuilder.orderNodes().components(); - assertEquals(providesNothing,resolution.get(0)); - assertEquals(afterProvidesNothing,resolution.get(1)); - } - - private ChainBuilder createDependencyHandler() { - ChainBuilder chainBuilder = newChainBuilder(); - chainBuilder.addPhase(new Phase("phase1", Collections.<String>emptySet(), Collections.<String>emptySet())); - chainBuilder.addPhase(new Phase("phase2", Collections.<String>emptySet(), Collections.<String>emptySet())); - chainBuilder.addPhase(new Phase("phase3", Collections.<String>emptySet(), Collections.<String>emptySet())); - return chainBuilder; - } - - private String name(ChainedComponent searcher) { - return searcher.getClass().getSimpleName(); - } - - @Provides("A") - static class A extends NoopComponent { - } - - @Provides("B") - @After("A") - @Before({"D", "phase1"}) - static class B extends NoopComponent { - } - - @Provides("C") - @After("phase1") - static class C extends NoopComponent { - } - - @Provides("D") - @After({"C","A"}) - static class D extends NoopComponent { - } - - @Provides("E") - @After({"B","D"}) - @Before("phase2") - static class E extends NoopComponent { - } - - @Provides("F") - @After("phase2") - static class F extends NoopComponent { - } - - @Provides("G") - @After("F") - static class G extends NoopComponent { - } - - @Provides("H") - @Before("A") - @After("F") - static class H extends NoopComponent { - } - - @Provides("AfterAll") - @After("*") - static class AfterAll extends NoopComponent { - } - - static class ProvidesNothing extends NoopComponent { - } - - @After("ProvidesNothing") - static class AfterProvidesNothing extends NoopComponent { - } - - static class NoopComponent extends ChainedComponent { - } - -} diff --git a/processing/src/test/java/com/yahoo/component/chain/dependencies/ordering/OrderedReadyNodesTest.java b/processing/src/test/java/com/yahoo/component/chain/dependencies/ordering/OrderedReadyNodesTest.java deleted file mode 100644 index 77729a99012..00000000000 --- a/processing/src/test/java/com/yahoo/component/chain/dependencies/ordering/OrderedReadyNodesTest.java +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.dependencies.ordering; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; - -import com.yahoo.component.chain.ChainedComponent; -import com.yahoo.component.chain.dependencies.Dependencies; -import org.junit.Before; -import org.junit.Test; - -import com.yahoo.component.ComponentId; - - - -/** - * Test for OrderedReadyNodes. - * - * @author Tony Vaagenes - */ -@SuppressWarnings("rawtypes") -public class OrderedReadyNodesTest { - - class ComponentA extends ChainedComponent { - public ComponentA(ComponentId id) { - super(id); - } - - @Override - public Dependencies getDependencies() { - return new Dependencies(Arrays.asList(getId().getName()), null, null); - } - } - - class ComponentB extends ComponentA { - public ComponentB(ComponentId id) { - super(id); - } - } - - private OrderedReadyNodes readyNodes; - - @Before - public void setup() { - readyNodes = new OrderedReadyNodes(); - } - - @Test - public void require_NameProviders_before_SearcherNodes() { - NameProvider nameProvider = createDummyNameProvider(100); - ComponentNode componentNode = new ComponentNode<>(createFakeComponentA("a"), 1); - - addNodes(nameProvider, componentNode); - - assertEquals(nameProvider, pop()); - assertEquals(componentNode, pop()); - } - - private NameProvider createDummyNameProvider(int priority) { - return new NameProvider("anonymous", priority) { - @Override - protected void addNode(ComponentNode node) { - throw new UnsupportedOperationException(); - } - - @Override - int classPriority() { - return 0; - } - }; - } - - @Test - public void require_SearcherNodes_ordered_by_insertion_order() { - int priority = 0; - ComponentNode a = new ComponentNode<>(createFakeComponentB("1"), priority++); - ComponentNode b = new ComponentNode<>(createFakeComponentA("2"), priority++); - ComponentNode c = new ComponentNode<>(createFakeComponentA("03"), priority++); - - addNodes(a, b, c); - - assertEquals(a, pop()); - assertEquals(b, pop()); - assertEquals(c, pop()); - } - - ChainedComponent createFakeComponentA(String id) { - return new ComponentA(ComponentId.fromString(id)); - } - - ChainedComponent createFakeComponentB(String id) { - return new ComponentB(ComponentId.fromString(id)); - } - - - private void addNodes(Node... nodes) { - for (Node node : nodes) { - readyNodes.add(node); - } - } - - private Node pop() { - return readyNodes.pop(); - } - -} diff --git a/processing/src/test/java/com/yahoo/component/chain/model/ChainsModelBuilderTest.java b/processing/src/test/java/com/yahoo/component/chain/model/ChainsModelBuilderTest.java deleted file mode 100644 index 7cef03bbb06..00000000000 --- a/processing/src/test/java/com/yahoo/component/chain/model/ChainsModelBuilderTest.java +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.component.chain.model; - -import com.yahoo.component.ComponentId; -import com.yahoo.component.ComponentSpecification; -import com.yahoo.container.core.ChainsConfig; -import org.junit.Test; - -import java.util.Map; -import java.util.Set; - -import static com.yahoo.container.core.ChainsConfig.Components; -import static com.yahoo.container.core.ChainsConfig.Chains; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * @author gjoranv - */ -public class ChainsModelBuilderTest { - - @Test - public void components_are_added_to_componentModels() throws Exception { - ChainsModel model = chainsModel(); - assertEquals(2, model.allComponents().size()); - assertTrue(model.componentModels().containsKey(new ComponentId("componentA"))); - } - - @Test - public void components_are_added_to_chainSpecification() throws Exception { - ChainsModel model = chainsModel(); - ChainSpecification chainSpec = model.chainSpecifications().get(new ComponentId("chain1")).model(); - assertTrue(getComponentsByName(chainSpec.componentReferences).containsKey("componentA")); - } - - @Test - public void inherited_chains_are_added_to_chainSpecification() throws Exception { - ChainsModel model = chainsModel(); - ChainSpecification inheritsChain1 = model.chainSpecifications().get(new ComponentId("inheritsChain1")).model(); - assertEquals(2, model.allChainsFlattened().size()); - assertTrue(getComponentsByName(inheritsChain1.inheritance.chainSpecifications).containsKey("chain1")); - assertTrue(getComponentsByName(inheritsChain1.inheritance.excludedComponents).containsKey("componentA")); - } - - private ChainsModel chainsModel() { - ChainsConfig.Builder builder = new ChainsConfig.Builder() - .components(new Components.Builder() - .id("componentA")) - .components(new Components.Builder() - .id("componentB")) - .chains(new Chains.Builder() - .id("chain1") - .components("componentA") - .components("componentB")) - .chains(new Chains.Builder() - .id("inheritsChain1") - .inherits("chain1") - .excludes("componentA")); - ChainsConfig config = new ChainsConfig(builder); - - ChainsModel model = ChainsModelBuilder.buildFromConfig(config); - model.validate(); - return model; - } - - private static Map<String, ComponentSpecification> - getComponentsByName(Set<ComponentSpecification> componentSpecifications) { - return ChainSpecification.componentsByName(componentSpecifications); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/ResponseTestCase.java b/processing/src/test/java/com/yahoo/processing/ResponseTestCase.java deleted file mode 100644 index 02c6049de49..00000000000 --- a/processing/src/test/java/com/yahoo/processing/ResponseTestCase.java +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing; - -import com.yahoo.processing.response.ArrayDataList; -import com.yahoo.processing.response.DataList; -import com.yahoo.processing.test.ProcessorLibrary; -import com.yahoo.processing.test.Responses; -import org.junit.Test; - -import java.util.concurrent.ExecutionException; - -import static org.junit.Assert.*; - -/** - * @author bratseth - */ -@SuppressWarnings("unchecked") -public class ResponseTestCase { - - /** - * Create a nested async tree of data elements, complete it recursively and check completion order. - * Check the recursive toString printing along the way. - * List variable names ends by numbers specifying the index of the list at each level. - */ - @SuppressWarnings("unchecked") - @Test - public void testRecursiveCompletionAndToString() throws InterruptedException, ExecutionException { - // create lists - Request request = new Request(); - DataList list1 = ArrayDataList.create(request); - DataList list11 = ArrayDataList.create(request); - DataList list12 = ArrayDataList.createAsync(request); - DataList list13 = ArrayDataList.createAsync(request); - DataList list14 = ArrayDataList.create(request); - DataList list121 = ArrayDataList.createAsync(request); - DataList list122 = ArrayDataList.create(request); - DataList list123 = ArrayDataList.createAsync(request); - DataList list1231 = ArrayDataList.createAsync(request); - DataList list1232 = ArrayDataList.create(request); - // wire tree - list1.add(list11); - list1.add(list12); - list1.add(list13); - list1.add(list14); - list12.add(list121); - list12.add(list122); - list12.add(list123); - list123.add(list1231); - list123.add(list1232); - // add sync data elements - list1.add(new ProcessorLibrary.StringData(request,"list1")); - list12.add(new ProcessorLibrary.StringData(request,"list12")); - list14.add(new ProcessorLibrary.StringData(request,"list14")); - list122.add(new ProcessorLibrary.StringData(request,"list122")); - list1231.add(new ProcessorLibrary.StringData(request,"list1231")); - - assertEqualsIgnoreObjectNumbers("Uncompleted tree, no incoming",uncompletedTreeUncompletedIncoming,Responses.recursiveToString(list1)); - - // provide all async incoming data - list12.incoming().markComplete(); - list121.incoming().addLast(new ProcessorLibrary.StringData(request,"list121async1")); - list123.incoming().markComplete(); - list1231.incoming().add(new ProcessorLibrary.StringData(request,"list13231async1")); - list1231.incoming().addLast(new ProcessorLibrary.StringData(request,"list1231async2")); - list13.incoming().add(new ProcessorLibrary.StringData(request,"list13async1")); - list13.incoming().addLast(new ProcessorLibrary.StringData(request,"list13async2")); - - assertEqualsIgnoreObjectNumbers("Uncompleted tree, incoming complete", uncompletedTreeCompletedIncoming, Responses.recursiveToString(list1)); - - // complete all - Response.recursiveComplete(list1).get(); - assertEqualsIgnoreObjectNumbers("Completed tree", completedTree, Responses.recursiveToString(list1)); - } - - private void assertEqualsIgnoreObjectNumbers(String explanation,String expected,String actual) { - assertEquals(explanation,expected,removeObjectNumbers(actual)); - } - - /** Removes all object numbers (occurrences of @hexnumber) */ - private String removeObjectNumbers(String s) { - return s.replaceAll("@[0-9a-f]+",""); - } - - private static final String uncompletedTreeUncompletedIncoming= - "com.yahoo.processing.response.ArrayDataList [incomplete, (no incoming)]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, (no incoming)]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, incoming: incomplete, data []]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, incoming: incomplete, data []]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, (no incoming)]\n" + - " list122\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, incoming: incomplete, data []]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, incoming: incomplete, data []]\n" + - " list1231\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, (no incoming)]\n" + - " list12\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, incoming: incomplete, data []]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, (no incoming)]\n" + - " list14\n" + - " list1\n"; - - private static final String uncompletedTreeCompletedIncoming= - "com.yahoo.processing.response.ArrayDataList [incomplete, (no incoming)]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, (no incoming)]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, incoming: complete, data []]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, incoming: complete, data [list121async1]]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, (no incoming)]\n" + - " list122\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, incoming: complete, data []]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, incoming: complete, data [list13231async1, list1231async2]]\n" + - " list1231\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, (no incoming)]\n" + - " list12\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, incoming: complete, data [list13async1, list13async2]]\n" + - " com.yahoo.processing.response.ArrayDataList [incomplete, (no incoming)]\n" + - " list14\n" + - " list1\n"; - - private static final String completedTree= - "com.yahoo.processing.response.ArrayDataList [completed]\n" + - " com.yahoo.processing.response.ArrayDataList [completed]\n" + - " com.yahoo.processing.response.ArrayDataList [completed]\n" + - " com.yahoo.processing.response.ArrayDataList [completed]\n" + - " list121async1\n" + - " com.yahoo.processing.response.ArrayDataList [completed]\n" + - " list122\n" + - " com.yahoo.processing.response.ArrayDataList [completed]\n" + - " com.yahoo.processing.response.ArrayDataList [completed]\n" + - " list1231\n" + - " list13231async1\n" + - " list1231async2\n" + - " com.yahoo.processing.response.ArrayDataList [completed]\n" + - " list12\n" + - " com.yahoo.processing.response.ArrayDataList [completed]\n" + - " list13async1\n" + - " list13async2\n" + - " com.yahoo.processing.response.ArrayDataList [completed]\n" + - " list14\n" + - " list1\n"; -} diff --git a/processing/src/test/java/com/yahoo/processing/execution/test/AsyncExecutionTestCase.java b/processing/src/test/java/com/yahoo/processing/execution/test/AsyncExecutionTestCase.java deleted file mode 100644 index b821461fdc6..00000000000 --- a/processing/src/test/java/com/yahoo/processing/execution/test/AsyncExecutionTestCase.java +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.execution.test; - -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.execution.Execution; -import org.junit.Test; - -import static com.yahoo.processing.test.ProcessorLibrary.*; -import static org.junit.Assert.assertEquals; - -/** - * @author bratseth - */ -public class AsyncExecutionTestCase { - - /** Execute a processing chain which forks off into multiple threads */ - @Test - public void testAsyncExecution() { - // Create a chain - Chain<Processor> chain=new Chain<>(new CombineData(),new BlockingSplitter(2),new Get6DataItems(), new DataSource()); - - // Execute it - Request request=new Request(); - request.properties().set("appendage",1); - Response response=Execution.createRoot(chain,0,Execution.Environment.createEmpty()).process(request); - - // Verify the result - assertEquals(6*2-1,response.data().asList().size()); - assertEquals("first.2, third.2",response.data().get(0).toString()); - assertEquals("second.2",response.data().get(1).toString()); - assertEquals("first.3",response.data().get(2).toString()); - assertEquals("second.3",response.data().get(3).toString()); - assertEquals("third.3",response.data().get(4).toString()); - // from the parallel execution - assertEquals("first.2",response.data().get(5).toString()); - assertEquals("second.2",response.data().get(6).toString()); - assertEquals("third.2",response.data().get(7).toString()); - assertEquals("first.3",response.data().get(8).toString()); - assertEquals("second.3",response.data().get(9).toString()); - assertEquals("third.3",response.data().get(10).toString()); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/execution/test/ExecutionContextTestCase.java b/processing/src/test/java/com/yahoo/processing/execution/test/ExecutionContextTestCase.java deleted file mode 100644 index 9c4d4de47dc..00000000000 --- a/processing/src/test/java/com/yahoo/processing/execution/test/ExecutionContextTestCase.java +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.execution.test; - -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.Processor; -import com.yahoo.processing.execution.Execution; -import com.yahoo.processing.test.ProcessorLibrary; -import org.junit.Test; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -/** - * @author bratseth - */ -public class ExecutionContextTestCase { - - private final Chain<Processor> chain = new Chain<Processor>(new ProcessorLibrary.DataSource()); - - /** Tests combined use of trace messages, context values and access log entries */ - @Test - public void testtrace() { - Execution execution1=Execution.createRoot(chain,2,Execution.Environment.createEmpty()); - execution1.trace().setProperty("a","a1"); - execution1.trace().logValue("a","a1"); - execution1.trace().trace("root 1", 2); - execution1.trace().setProperty("a","a2"); - execution1.trace().setProperty("b","b1"); - execution1.trace().logValue("a","a2"); - execution1.trace().logValue("b","b1"); - - Execution execution2=new Execution(chain,execution1); - execution2.trace().setProperty("b","b2"); - execution2.trace().logValue("b","b2"); - execution2.trace().trace(" child-1 1", 2); - execution2.trace().setProperty("b", "b3"); - execution2.trace().logValue("b","b3"); - - execution1.trace().setProperty("b","b4"); - execution1.trace().logValue("b","b4"); - - Execution execution3=new Execution(chain,execution1); - execution3.trace().setProperty("b","b5"); - execution3.trace().setProperty("c","c1"); - execution3.trace().logValue("b","b5"); - execution3.trace().logValue("c","c1"); - execution3.trace().trace(" child-2 1", 2); - - execution2.trace().setProperty("c","c2"); - execution2.trace().logValue("c","c2"); - - execution1.trace().trace("root 2", 2); - execution3.trace().setProperty("d", "d1"); - execution1.trace().logValue("d","d1"); - - execution2.trace().trace(" child-1 2", 2); - execution2.trace().setProperty("c", "c3"); - execution2.trace().logValue("c","c3"); - - execution1.trace().setProperty("c","c4"); - execution1.trace().logValue("c","c4"); - - Iterator<String> traceIterator=execution1.trace().traceNode().root().descendants(String.class).iterator(); - assertEquals("root 1",traceIterator.next()); - assertEquals(" child-1 1",traceIterator.next()); - assertEquals(" child-1 2",traceIterator.next()); - assertEquals(" child-2 1",traceIterator.next()); - assertEquals("root 2",traceIterator.next()); - assertFalse(traceIterator.hasNext()); - - // Verify context variables - assertEquals("a2", execution1.trace().getProperty("a")); - assertEquals("b5", execution1.trace().getProperty("b")); - assertEquals("c4", execution1.trace().getProperty("c")); - assertEquals("d1", execution1.trace().getProperty("d")); - assertNull(execution1.trace().getProperty("e")); - - // Verify access log - Set<String> logValues=new HashSet<>(); - for (Iterator<Execution.Trace.LogValue> logValueIterator=execution1.trace().logValueIterator(); logValueIterator.hasNext(); ) - logValues.add(logValueIterator.next().toString()); - assertEquals(12,logValues.size()); - assertTrue(logValues.contains("a=a1")); - assertTrue(logValues.contains("a=a2")); - assertTrue(logValues.contains("b=b1")); - assertTrue(logValues.contains("b=b2")); - assertTrue(logValues.contains("b=b3")); - assertTrue(logValues.contains("b=b4")); - assertTrue(logValues.contains("b=b5")); - assertTrue(logValues.contains("c=c1")); - assertTrue(logValues.contains("c=c2")); - assertTrue(logValues.contains("d=d1")); - assertTrue(logValues.contains("c=c3")); - assertTrue(logValues.contains("c=c4")); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/execution/test/FutureDataTestCase.java b/processing/src/test/java/com/yahoo/processing/execution/test/FutureDataTestCase.java deleted file mode 100644 index c22e34515bf..00000000000 --- a/processing/src/test/java/com/yahoo/processing/execution/test/FutureDataTestCase.java +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.execution.test; - -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.execution.Execution; -import com.yahoo.processing.response.DataList; -import org.junit.Test; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import static com.yahoo.processing.test.ProcessorLibrary.*; -import static org.junit.Assert.assertEquals; - -/** - * Tests scenarios where a data producer returns a promise of some future data rather than the data itself. - * As no processor waits for the data it is returned all the way to the caller. - * - * @author bratseth - */ -public class FutureDataTestCase { - - /** Run a chain which ends in a processor which returns a response containing future data. */ - @SuppressWarnings("unchecked") - @Test - public void testFutureDataPassThrough() throws InterruptedException, ExecutionException, TimeoutException { - // Set up - FutureDataSource futureDataSource=new FutureDataSource(); - Chain<Processor> chain=new Chain<>(new DataCounter(),futureDataSource); - - // Execute - Request request=new Request(); - Response response=Execution.createRoot(chain,0,Execution.Environment.createEmpty()).process(request); // Urk ... - - // Verify the result prior to completion of delayed data - assertEquals(1,response.data().asList().size()); - assertEquals("Data count: 0",response.data().get(0).toString()); - - // complete delayed data - assertEquals("Delayed data was requested once", 1, futureDataSource.incomingData.size()); - futureDataSource.incomingData.get(0).add(new StringData(request, "d1")); - futureDataSource.incomingData.get(0).addLast(new StringData(request, "d2")); - assertEquals("New data is not visible because we haven't asked for it", 1, response.data().asList().size()); - response.data().complete().get(1000, TimeUnit.MILLISECONDS); - assertEquals("Now the data is available", 3, response.data().asList().size()); - assertEquals("d1",response.data().get(1).toString().toString()); - assertEquals("d2",response.data().get(2).toString().toString()); - } - - /** Federate to one source which returns data immediately and one who return future data */ - @SuppressWarnings("unchecked") - @Test - public void testFederateSyncAndAsyncData() throws InterruptedException, ExecutionException, TimeoutException { - // Set up - FutureDataSource futureDataSource=new FutureDataSource(); - Chain<Processor> chain=new Chain<>(new DataCounter(),new Federator(new Chain<>(new DataSource()),new Chain<>(futureDataSource))); - - // Execute - Request request=new Request(); - request.properties().set("appendage",1); - Response response=Execution.createRoot(chain,0,Execution.Environment.createEmpty()).process(request); - - // Verify the result prior to completion of delayed data - assertEquals(3,response.data().asList().size()); // The sync data list + the (currently empty) future data list) + the data count - DataList syncData=(DataList)response.data().get(0); - DataList asyncData=(DataList)response.data().get(1); - StringData countData=(StringData)response.data().get(2); - - assertEquals("The sync data is available",3,syncData.asList().size()); - assertEquals( "first.1",syncData.get(0).toString()); - assertEquals("second.1", syncData.get(1).toString()); - assertEquals( "third.1",syncData.get(2).toString()); - assertEquals("No async data yet",0,asyncData.asList().size()); - assertEquals("The data counter has run and accessed the sync data","Data count: 3",countData.toString()); - - // complete async data - futureDataSource.incomingData.get(0).add(new StringData(request, "d1")); - futureDataSource.incomingData.get(0).addLast(new StringData(request, "d2")); - assertEquals("New data is not visible because we haven't asked for it", 0, asyncData.asList().size()); - asyncData.complete().get(1000, TimeUnit.MILLISECONDS); - assertEquals("Now the data is available", 2, asyncData.asList().size()); - assertEquals("d1",asyncData.get(0).toString().toString()); - assertEquals("d2", asyncData.get(1).toString().toString()); - } - - /** Register a chain which will be called when some async data is available */ - @SuppressWarnings("unchecked") - @Test - public void testAsyncDataProcessing() throws InterruptedException, ExecutionException, TimeoutException { - // Set up - FutureDataSource futureDataSource=new FutureDataSource(); - Chain<Processor> asyncChain=new Chain<Processor>(new DataCounter()); - Chain<Processor> chain=new Chain<>(new AsyncDataProcessingInitiator(asyncChain),futureDataSource); - - // Execute - Request request=new Request(); - Response response=Execution.createRoot(chain,0,Execution.Environment.createEmpty()).process(request); - - // Verify the result prior to completion of delayed data - assertEquals("No data yet",0,response.data().asList().size()); - - // complete async data - futureDataSource.incomingData.get(0).add(new StringData(request, "d1")); - assertEquals("New data is not visible because it is not complete", 0, response.data().asList().size()); - futureDataSource.incomingData.get(0).addLast(new StringData(request, "d2")); - assertEquals("Not visible because it has not been synced yet", 0, response.data().asList().size()); - response.data().complete().get(1000, TimeUnit.MILLISECONDS); - assertEquals("Now the data as well as the count is available", 3, response.data().asList().size()); - assertEquals("d1",response.data().get(0).toString().toString()); - assertEquals("d2",response.data().get(1).toString().toString()); - assertEquals("Data count: 2",response.data().get(2).toString()); - } - - /** - * Register a chain which federates over three sources, two of which are future. - * When the first of the futures are done one additional chain is to be run. - * When both are done another chain is to be run. - */ - @SuppressWarnings("unchecked") - @Test - public void testAsyncDataProcessingOfFederatedResult() throws InterruptedException, ExecutionException, TimeoutException { - // Set up - // Source 1 (async with completion chain) - FutureDataSource futureSource1=new FutureDataSource(); - Chain<Processor> asyncChainSource1=new Chain<Processor>(new DataCounter("source1")); - Chain<Processor> chainSource1=new Chain<>(new AsyncDataProcessingInitiator(asyncChainSource1),futureSource1); - // Source 2 (async source) - FutureDataSource futureSource2=new FutureDataSource(); - Chain<Processor> chainSource2=new Chain<Processor>(futureSource2); - // Source 3 (sync source) - Chain<Processor> chainSource3=new Chain<Processor>(new DataSource()); - // Main chain federating to the above - not waiting for source 1 and 2 but invoking asyncMain when both are complete - Chain<Processor> asyncMain=new Chain<Processor>(new DataCounter("main")); - Chain<Processor> main=new Chain<>(new AsyncDataProcessingInitiator(asyncMain),new Federator(chainSource1,chainSource2,chainSource3)); - - // Execute - Request request=new Request(); - Response response=Execution.createRoot(main,0,Execution.Environment.createEmpty()).process(request); - - // Verify the result prior to completion of delayed data - assertEquals("We have the sync data plus placeholders for the async lists",3,response.data().asList().size()); - DataList source1Data=((DataList)response.data().get(0)); - DataList source2Data=((DataList)response.data().get(1)); - DataList source3Data=((DataList)response.data().get(2)); - - assertEquals("No data yet",0,source1Data.asList().size()); - assertEquals("No data yet",0,source2Data.asList().size()); - assertEquals(3,source3Data.asList().size()); - - // complete async data in source1 - futureSource1.incomingData.get(0).addLast(new StringData(request,"source1Data")); - assertEquals("Not visible yet", 0, source1Data.asList().size()); - source1Data.complete().get(1000, TimeUnit.MILLISECONDS); - assertEquals(2, source1Data.asList().size()); - assertEquals("source1Data",source1Data.get(0).toString()); - assertEquals("Completion listener chain on this has run", "[source1] Data count: 1", source1Data.get(1).toString()); - - // source2 & main completion - assertEquals("Main completion listener has not run", 3, response.data().asList().size()); - futureSource2.incomingData.get(0).addLast(new StringData(request, "source2Data")); - assertEquals("Main completion listener has not run", 3, response.data().asList().size()); - - Response.recursiveComplete(response.data()).get(); - assertEquals("Main completion listener has run", 4, response.data().asList().size()); - assertEquals("The main data counter saw all sync data, but not source2 data as it executes after this", - "[main] Data count: " + (2 + 0 + 3), response.data().get(3).toString()); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/execution/test/StreamingTestCase.java b/processing/src/test/java/com/yahoo/processing/execution/test/StreamingTestCase.java deleted file mode 100644 index 6ab37f54d7b..00000000000 --- a/processing/src/test/java/com/yahoo/processing/execution/test/StreamingTestCase.java +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.execution.test; - -import com.google.common.util.concurrent.MoreExecutors; -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.execution.Execution; -import com.yahoo.processing.response.Data; -import com.yahoo.processing.response.IncomingData; -import com.yahoo.processing.test.ProcessorLibrary; -import org.junit.Test; - -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import static org.junit.Assert.assertEquals; - -/** - * Tests listening on every available new piece of data in a response - * - * @author bratseth - */ -public class StreamingTestCase { - - /** Tests adding a chain which is called every time new data is added to a data list */ - @SuppressWarnings("unchecked") - @Test - public void testStreamingData() throws InterruptedException, ExecutionException, TimeoutException { - // Set up - StreamProcessor streamProcessor = new StreamProcessor(); - Chain<Processor> streamProcessing = new Chain<Processor>(streamProcessor); - ProcessorLibrary.FutureDataSource futureDataSource=new ProcessorLibrary.FutureDataSource(); - Chain<Processor> main=new Chain<>(new ProcessorLibrary.DataCounter(), - new ProcessorLibrary.StreamProcessingInitiator(streamProcessing), - futureDataSource); - - // Execute - Request request=new Request(); - Response response= Execution.createRoot(main, 0, Execution.Environment.createEmpty()).process(request); - IncomingData incomingData = futureDataSource.incomingData.get(0); - - // State prior to receiving any additional data - assertEquals(1,response.data().asList().size()); - assertEquals("Data count: 0",response.data().get(0).toString()); - assertEquals("Add data listener invoked also for DataCounter", 1, streamProcessor.invocationCount); - assertEquals("Initial data count", 1, response.data().asList().size()); - - // add first data - we have no listener so the data is held in the incoming buffer - incomingData.add(new ProcessorLibrary.StringData(request, "d1")); - assertEquals("Data add listener not invoked as we are not listening on new data yet",1, streamProcessor.invocationCount); - assertEquals("New data is not consumed", 1, response.data().asList().size()); - - // start listening on incoming data - this is what a renderer will do - incomingData.addNewDataListener(new MockNewDataListener(incomingData), MoreExecutors.directExecutor()); - assertEquals("We got a data add event for the data which was already added", 2, streamProcessor.invocationCount); - assertEquals("New data is consumed", 2, response.data().asList().size()); - - incomingData.add(new ProcessorLibrary.StringData(request, "d2")); - assertEquals("We are now getting data add events each time", 3, streamProcessor.invocationCount); - assertEquals("New data is consumed", 3, response.data().asList().size()); - - incomingData.addLast(new ProcessorLibrary.StringData(request, "d3")); - assertEquals("We are getting data add events also the last time", 4, streamProcessor.invocationCount); - assertEquals("New data is consumed", 4, response.data().asList().size()); - - response.data().complete().get(1000, TimeUnit.MILLISECONDS); // no-op here - assertEquals("d1",response.data().get(1).toString().toString()); - assertEquals("d2",response.data().get(2).toString().toString()); - assertEquals("d3",response.data().get(3).toString().toString()); - } - - private static class MockNewDataListener implements Runnable { - - private final IncomingData<Data> incomingData; - - public MockNewDataListener(IncomingData<Data> incomingData) { - this.incomingData = incomingData; - } - - @Override - public void run() { - // consume new data - for (Data newData : incomingData.drain()) { - incomingData.getOwner().add(newData); - } - // actual rendering would go here (at this point data add listeners will have executed) - } - - } - - private static class StreamProcessor extends Processor { - - int invocationCount; - - @Override - public Response process(Request request, Execution execution) { - invocationCount++; - return execution.process(request); - } - - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/request/CompoundNameTestCase.java b/processing/src/test/java/com/yahoo/processing/request/CompoundNameTestCase.java deleted file mode 100644 index 382abe8d2ca..00000000000 --- a/processing/src/test/java/com/yahoo/processing/request/CompoundNameTestCase.java +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request; - -import static org.junit.Assert.*; - -import java.util.Iterator; -import java.util.List; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.google.common.base.Splitter; -import com.yahoo.text.Lowercase; - -/** - * Module local test of the basic property name building block. - * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> - */ -public class CompoundNameTestCase { - - private static final String NAME = "com.yahoo.processing.request.CompoundNameTestCase"; - private CompoundName cn; - - @Before - public void setUp() throws Exception { - cn = new CompoundName(NAME); - } - - @After - public void tearDown() throws Exception { - } - - @Test - public final void testLast() { - assertEquals(NAME.substring(NAME.lastIndexOf('.') + 1), cn.last()); - } - - @Test - public final void testFirst() { - assertEquals(NAME.substring(0, NAME.indexOf('.')), cn.first()); - } - - @Test - public final void testRest() { - assertEquals(NAME.substring(NAME.indexOf('.') + 1), cn.rest().toString()); - } - - @Test - public final void testRestN() { - assertEquals("a.b.c.d.e", new CompoundName("a.b.c.d.e").rest(0).toString()); - assertEquals("b.c.d.e", new CompoundName("a.b.c.d.e").rest(1).toString()); - assertEquals("c.d.e", new CompoundName("a.b.c.d.e").rest(2).toString()); - assertEquals("d.e", new CompoundName("a.b.c.d.e").rest(3).toString()); - assertEquals("e", new CompoundName("a.b.c.d.e").rest(4).toString()); - assertEquals("", new CompoundName("a.b.c.d.e").rest(5).toString()); - } - - @Test - public final void testPrefix() { - assertTrue(new CompoundName("a.b.c").hasPrefix(new CompoundName(""))); - assertTrue(new CompoundName("a.b.c").hasPrefix(new CompoundName("a"))); - assertTrue(new CompoundName("a.b.c").hasPrefix(new CompoundName("a.b"))); - assertTrue(new CompoundName("a.b.c").hasPrefix(new CompoundName("a.b.c"))); - - assertFalse(new CompoundName("a.b.c").hasPrefix(new CompoundName("a.b.c.d"))); - assertFalse(new CompoundName("a.b.c").hasPrefix(new CompoundName("a.b.d"))); - } - - @Test - public final void testSize() { - Splitter s = Splitter.on('.'); - Iterable<String> i = s.split(NAME); - int n = 0; - for (@SuppressWarnings("unused") String x : i) { - ++n; - } - assertEquals(n, cn.size()); - } - - @Test - public final void testGet() { - String s = cn.get(0); - assertEquals(NAME.substring(0, NAME.indexOf('.')), s); - } - - @Test - public final void testIsCompound() { - assertTrue(cn.isCompound()); - } - - @Test - public final void testIsEmpty() { - assertFalse(cn.isEmpty()); - } - - @Test - public final void testAsList() { - List<String> l = cn.asList(); - Splitter peoplesFront = Splitter.on('.'); - Iterable<String> answer = peoplesFront.split(NAME); - Iterator<String> expected = answer.iterator(); - for (int i = 0; i < l.size(); ++i) { - assertEquals(expected.next(), l.get(i)); - } - assertFalse(expected.hasNext()); - } - - @Test - public final void testEqualsObject() { - assertFalse(cn.equals(NAME)); - assertFalse(cn.equals(null)); - assertTrue(cn.equals(cn)); - assertTrue(cn.equals(new CompoundName(NAME))); - } - - @Test - public final void testEmptyNonEmpty() { - assertTrue(new CompoundName("").isEmpty()); - assertEquals(0, new CompoundName("").size()); - assertFalse(new CompoundName("a").isEmpty()); - assertEquals(1, new CompoundName("a").size()); - CompoundName empty = new CompoundName("a.b.c"); - assertTrue(empty == empty.rest(0)); - assertFalse(empty == empty.rest(1)); - } - - @Test - public final void testGetLowerCasedName() { - assertEquals(Lowercase.toLowerCase(NAME), cn.getLowerCasedName()); - } - - @Test - public void testAppend() { - assertEquals(new CompoundName("a.b.c.d"), new CompoundName("").append(new CompoundName("a.b.c.d"))); - assertEquals(new CompoundName("a.b.c.d"), new CompoundName("a").append(new CompoundName("b.c.d"))); - assertEquals(new CompoundName("a.b.c.d"), new CompoundName("a.b").append(new CompoundName("c.d"))); - assertEquals(new CompoundName("a.b.c.d"), new CompoundName("a.b.c").append(new CompoundName("d"))); - assertEquals(new CompoundName("a.b.c.d"), new CompoundName("a.b.c.d").append(new CompoundName(""))); - } - - @Test - public void empty_CompoundName_is_prefix_of_any_CompoundName() { - CompoundName empty = new CompoundName(""); - - assertTrue(empty.hasPrefix(empty)); - assertTrue(new CompoundName("a").hasPrefix(empty)); - } - - @Test - public void whole_components_must_match_to_be_prefix() { - CompoundName stringPrefix = new CompoundName("a"); - CompoundName name = new CompoundName("aa"); - - assertFalse(name.hasPrefix(stringPrefix)); - } -} diff --git a/processing/src/test/java/com/yahoo/processing/request/test/CompoundNameBenchmark.java b/processing/src/test/java/com/yahoo/processing/request/test/CompoundNameBenchmark.java deleted file mode 100644 index 002b6bac4a8..00000000000 --- a/processing/src/test/java/com/yahoo/processing/request/test/CompoundNameBenchmark.java +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request.test; - -import com.yahoo.processing.request.CompoundName; - -/** - * @author baldersheim - */ -public class CompoundNameBenchmark { - public void run() { - long result=0; - String strings[] = createStrings(1000); - // Warm-up - out("Warming up..."); - for (int i=0; i<10*1000; i++) - result+=createCompundName(strings); - - long startTime=System.currentTimeMillis(); - out("Running..."); - for (int i=0; i<100*1000; i++) - result+=createCompundName(strings); - out("Ignore this: " + result); // Make sure we are not fooled by optimization by creating an observable result - long endTime=System.currentTimeMillis(); - out("Compoundification 1000 strings 100.000 times took " + (endTime-startTime) + " ms"); - } - - private final String [] createStrings(int num) { - String strings [] = new String [num]; - for(int i=0; i < strings.length; i++) { - strings[i] = "this.is.a.short.compound.name." + i; - } - return strings; - } - - private final int createCompundName(String [] strings) { - int retval = 0; - for (int i=0; i < strings.length; i++) { - CompoundName n = new CompoundName(strings[i]); - retval += n.size(); - } - return retval; - } - - private void out(String string) { - System.out.println(string); - } - - public static void main(String[] args) { - new CompoundNameBenchmark().run(); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/request/test/CompoundNameTestCase.java b/processing/src/test/java/com/yahoo/processing/request/test/CompoundNameTestCase.java deleted file mode 100644 index f5033565786..00000000000 --- a/processing/src/test/java/com/yahoo/processing/request/test/CompoundNameTestCase.java +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request.test; - -import com.yahoo.processing.request.CompoundName; -import static org.junit.Assert.assertEquals; -import org.junit.Test; - -/** - * @author bratseth - */ -public class CompoundNameTestCase { - - @Test - public void testFirstRest() { - assertEquals(CompoundName.empty, CompoundName.empty.rest()); - - CompoundName n=new CompoundName("on.two.three"); - assertEquals("on", n.first()); - assertEquals("two.three", n.rest().toString()); - n=n.rest(); - assertEquals("two", n.first()); - assertEquals("three", n.rest().toString()); - n=n.rest(); - assertEquals("three", n.first()); - assertEquals("", n.rest().toString()); - n=n.rest(); - assertEquals("", n.first()); - assertEquals("", n.rest().toString()); - n=n.rest(); - assertEquals("", n.first()); - assertEquals("", n.rest().toString()); - } - - @Test - public void testHashCodeAndEquals() { - CompoundName n1 = new CompoundName("venn.d.a"); - CompoundName n2 = new CompoundName(n1.asList()); - assertEquals(n1.hashCode(), n2.hashCode()); - assertEquals(n1, n2); - } - - @Test - public void testAppend() { - assertEquals("a",new CompoundName("a").append("").toString()); - assertEquals("a",new CompoundName("").append("a").toString()); - assertEquals("a.b",new CompoundName("a").append("b").toString()); - - CompoundName name = new CompoundName("a.b"); - assertEquals("a.b.c",name.append("c").toString()); - assertEquals("a.b.d",name.append("d").toString()); - } - - @Test - public void testEmpty() { - CompoundName empty=new CompoundName(""); - assertEquals("", empty.toString()); - assertEquals(0, empty.asList().size()); - } - - @Test - public void testAsList() { - assertEquals("[one]", new CompoundName("one").asList().toString()); - assertEquals("[one, two, three]", new CompoundName("one.two.three").asList().toString()); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/request/test/ErrorMessageTestCase.java b/processing/src/test/java/com/yahoo/processing/request/test/ErrorMessageTestCase.java deleted file mode 100644 index 70f4a7720ee..00000000000 --- a/processing/src/test/java/com/yahoo/processing/request/test/ErrorMessageTestCase.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request.test; - -import com.yahoo.processing.request.ErrorMessage; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; - -/** - * @author bratseth - */ -public class ErrorMessageTestCase { - - @Test - public void testToString() { - assertEquals("message",new ErrorMessage("message").toString()); - assertEquals("message: hello",new ErrorMessage("message",new Exception("hello")).toString()); - assertEquals("message: detail",new ErrorMessage("message","detail").toString()); - assertEquals("37: message: detail",new ErrorMessage(37,"message","detail").toString()); - assertEquals("message: detail: hello",new ErrorMessage("message","detail",new Exception("hello")).toString()); - assertEquals("message: detail: hello: world",new ErrorMessage("message","detail",new Exception("hello",new Exception("world"))).toString()); - assertEquals("message: detail: hello: Exception",new ErrorMessage("message","detail",new Exception("hello",new Exception())).toString()); - assertEquals("message: detail: hello",new ErrorMessage("message","detail",new Exception(new Exception("hello"))).toString()); - assertEquals("message: detail: java.lang.Exception: Exception",new ErrorMessage("message","detail",new Exception(new Exception())).toString()); - } - - @Test - public void testAccessors() { - ErrorMessage m = new ErrorMessage(37,"message","detail",new Exception("hello")); - assertEquals(37,m.getCode()); - assertEquals("message",m.getMessage()); - assertEquals("detail",m.getDetailedMessage()); - assertEquals("hello",m.getCause().getMessage()); - } - - @Test - public void testEquality() { - assertEquals(new ErrorMessage(37,"message","detail",new Exception("hello")), - new ErrorMessage(37,"message","detail",new Exception("hello"))); - assertEquals(new ErrorMessage("message","detail",new Exception("hello")), - new ErrorMessage("message","detail",new Exception("hello"))); - assertEquals(new ErrorMessage("message",new Exception("hello")), - new ErrorMessage("message",new Exception("hello"))); - assertEquals(new ErrorMessage("message"), - new ErrorMessage("message")); - assertEquals(new ErrorMessage("message",new Exception()), - new ErrorMessage("message")); - assertNotEquals(new ErrorMessage("message"), - new ErrorMessage("message","detail")); - assertNotEquals(new ErrorMessage(37,"message"), - new ErrorMessage("message")); - assertNotEquals(new ErrorMessage(37,"message"), - new ErrorMessage(38,"message")); - assertNotEquals(new ErrorMessage("message","detail1"), - new ErrorMessage("message","detail2")); - assertNotEquals(new ErrorMessage("message1"), - new ErrorMessage("message2")); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/request/test/PropertyMapTestCase.java b/processing/src/test/java/com/yahoo/processing/request/test/PropertyMapTestCase.java deleted file mode 100644 index 3c351d341d0..00000000000 --- a/processing/src/test/java/com/yahoo/processing/request/test/PropertyMapTestCase.java +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request.test; - -import com.yahoo.processing.request.properties.PropertyMap; -import com.yahoo.processing.request.properties.PublicCloneable; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - * @author bratseth - */ -public class PropertyMapTestCase { - - @Test - public void testObjectCloning() { - PropertyMap map = new PropertyMap(); - map.set("clonable", new ClonableObject()); - map.set("publicClonable", new PublicClonableObject()); - map.set("nonclonable", new NonClonableObject()); - map.set("clonableArray", new ClonableObject[] {new ClonableObject()}); - map.set("publicClonableArray", new ClonableObject[] {new ClonableObject()}); - map.set("nonclonableArray", new NonClonableObject[] {new NonClonableObject()}); - map.set("clonableList", Collections.singletonList(new ClonableObject())); - map.set("nonclonableList", Collections.singletonList(new NonClonableObject())); - assertNotNull(map.get("clonable")); - assertNotNull(map.get("nonclonable")); - - PropertyMap mapClone=map.clone(); - assertTrue(map.get("clonable") != mapClone.get("clonable")); - assertTrue(map.get("publicClonable")!= mapClone.get("publicClonable")); - assertTrue(map.get("nonclonable") == mapClone.get("nonclonable")); - - assertTrue(map.get("clonableArray") != mapClone.get("clonableArray")); - assertTrue(first(map.get("clonableArray")) != first(mapClone.get("clonableArray"))); - assertTrue(map.get("publicClonableArray") != mapClone.get("publicClonableArray")); - assertTrue(first(map.get("publicClonableArray")) != first(mapClone.get("publicClonableArray"))); - assertTrue(first(map.get("nonclonableArray")) == first(mapClone.get("nonclonableArray"))); - } - - @Test - public void testArrayCloning() { - PropertyMap map = new PropertyMap(); - byte[] byteArray = new byte[] {2, 4, 7}; - map.set("byteArray", byteArray); - - PropertyMap mapClone = map.clone(); - assertArrayEquals(byteArray, (byte[])mapClone.get("byteArray")); - assertTrue("Array was cloned", mapClone.get("byteArray") != byteArray); - } - - private Object first(Object object) { - if (object instanceof Object[]) - return ((Object[])object)[0]; - if (object instanceof List) - return ((List<?>)object).get(0); - throw new IllegalArgumentException(); - } - - public static class ClonableObject implements Cloneable { - - @Override - public ClonableObject clone() { - try { - return (ClonableObject)super.clone(); - } - catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - - } - - public static class PublicClonableObject implements PublicCloneable<PublicClonableObject> { - - @Override - public PublicClonableObject clone() { - try { - return (PublicClonableObject)super.clone(); - } - catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } - - } - - private static class NonClonableObject { - - } - - -} diff --git a/processing/src/test/java/com/yahoo/processing/request/test/RequestTestCase.java b/processing/src/test/java/com/yahoo/processing/request/test/RequestTestCase.java deleted file mode 100644 index 032fdd71f88..00000000000 --- a/processing/src/test/java/com/yahoo/processing/request/test/RequestTestCase.java +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.request.test; - -import com.yahoo.processing.Request; -import com.yahoo.processing.request.CompoundName; -import com.yahoo.processing.request.ErrorMessage; -import com.yahoo.processing.request.Properties; -import com.yahoo.processing.request.properties.PropertyMap; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -/** - * Tests using requests - * - * @author bratseth - */ -public class RequestTestCase { - - private static final double delta = 0.0000000001; - - @Test - public void testProperties() { - Properties p = new PropertyMap(); - p.set("a", "a1"); - Request r = new Request(p); - r.properties().set("b", "b1"); - assertEquals(2, r.properties().listProperties().size()); - assertEquals("a1", r.properties().get("a")); - - assertEquals("b1", r.properties().get("b")); - assertEquals("b1", r.properties().get("b", "default")); - assertEquals("default", r.properties().get("c", "default")); - assertNull(r.properties().get("c")); - assertEquals("b1", r.properties().get(new CompoundName("b"))); - assertEquals("b1", r.properties().get(new CompoundName("b"), "default")); - assertEquals("default", r.properties().get(new CompoundName("c"), "default")); - assertNull(r.properties().get(new CompoundName("c"))); - - assertEquals("b1", r.properties().getString("b")); - assertEquals("b1", r.properties().getString("b","default")); - assertEquals("default", r.properties().getString("c","default")); - assertEquals(null, r.properties().getString("c")); - assertEquals("b1", r.properties().getString(new CompoundName("b"))); - assertEquals("b1", r.properties().getString(new CompoundName("b"),"default")); - assertEquals("default", r.properties().getString(new CompoundName("c"),"default")); - assertEquals(null, r.properties().getString(new CompoundName("c"))); - - r.properties().set("i",7); - assertEquals(7, (int)r.properties().getInteger("i")); - assertEquals(7, (int)r.properties().getInteger("i",3)); - assertEquals(3, (int)r.properties().getInteger("n",3)); - assertNull(r.properties().getInteger("n")); - assertEquals(7, (int)r.properties().getInteger(new CompoundName("i"))); - assertEquals(7, (int)r.properties().getInteger(new CompoundName("i"),3)); - assertEquals(3, (int)r.properties().getInteger(new CompoundName("n"),3)); - assertNull(r.properties().getInteger("n")); - - r.properties().set(new CompoundName("l"), 7); - assertEquals(7, (long) r.properties().getLong("l")); - assertEquals(7, (long)r.properties().getLong("l",3l)); - assertEquals(3, (long)r.properties().getLong("m",3l)); - assertNull(r.properties().getInteger("m")); - assertEquals(7, (long)r.properties().getLong(new CompoundName("l"))); - assertEquals(7, (long)r.properties().getLong(new CompoundName("l"),3l)); - assertEquals(3, (long)r.properties().getLong(new CompoundName("m"),3l)); - assertNull(r.properties().getInteger("m")); - - r.properties().set("d", 7.3); - assertEquals(7.3, r.properties().getDouble("d"), delta); - assertEquals(7.3, r.properties().getDouble("d",3.4d), delta); - assertEquals(3.4, r.properties().getDouble("f",3.4d), delta); - assertNull(r.properties().getDouble("f")); - assertEquals(7.3, r.properties().getDouble(new CompoundName("d")), delta); - assertEquals(7.3, r.properties().getDouble(new CompoundName("d"),3.4d), delta); - assertEquals(3.4, r.properties().getDouble(new CompoundName("f"),3.4d), delta); - assertNull(r.properties().getDouble("f")); - - r.properties().set("o",true); - assertEquals(true, r.properties().getBoolean("o")); - assertEquals(true, r.properties().getBoolean("o",true)); - assertEquals(true, r.properties().getBoolean("g",true)); - assertEquals(false, r.properties().getBoolean("g")); - assertEquals(true, r.properties().getBoolean(new CompoundName("o"))); - assertEquals(true, r.properties().getBoolean(new CompoundName("o"),true)); - assertEquals(true, r.properties().getBoolean(new CompoundName("g"),true)); - assertEquals(false, r.properties().getBoolean("g")); - - r.properties().set(new CompoundName("x.y"), "x1.y1"); - r.properties().set("x.z", "x1.z1"); - - assertEquals(8, r.properties().listProperties().size()); - assertEquals(0, r.properties().listProperties("a").size()); - assertEquals(0, r.properties().listProperties(new CompoundName("a")).size()); - assertEquals(0, r.properties().listProperties(new CompoundName("none")).size()); - assertEquals(2, r.properties().listProperties(new CompoundName("x")).size()); - assertEquals(2, r.properties().listProperties("x").size()); - } - - @Test - public void testErrorMessages() { - Request r = new Request(); - r.errors().add(new ErrorMessage("foo")); - r.errors().add(new ErrorMessage("bar")); - assertEquals(2,r.errors().size()); - assertEquals("foo", r.errors().get(0).getMessage()); - assertEquals("bar", r.errors().get(1).getMessage()); - } - - @Test - public void testCloning() { - Request request = new Request(); - request.properties().set("a","a1"); - request.properties().set("b","b1"); - request.errors().add(new ErrorMessage("foo")); - request.errors().add(new ErrorMessage("bar")); - Request rcloned = request.clone(); - rcloned.properties().set("c", "c1"); - rcloned.errors().add(new ErrorMessage("baz")); - request.properties().set("d", "d1"); - request.errors().add(new ErrorMessage("boz")); - - assertEquals("a1", request.properties().get("a")); - assertEquals("a1", rcloned.properties().get("a")); - assertEquals("b1", request.properties().get("b")); - assertEquals("b1", rcloned.properties().get("b")); - assertEquals(null, request.properties().get("c")); - assertEquals("c1", rcloned.properties().get("c")); - assertEquals("d1", request.properties().get("d")); - assertEquals(null, rcloned.properties().get("d")); - - assertEquals(3, request.errors().size()); - assertEquals(1, rcloned.errors().size()); - assertEquals("foo",request.errors().get(0).getMessage()); - assertEquals("bar",request.errors().get(1).getMessage()); - assertEquals("boz",request.errors().get(2).getMessage()); - assertEquals("baz",rcloned.errors().get(0).getMessage()); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/test/DocumentationTestCase.java b/processing/src/test/java/com/yahoo/processing/test/DocumentationTestCase.java deleted file mode 100644 index ca8fb377f09..00000000000 --- a/processing/src/test/java/com/yahoo/processing/test/DocumentationTestCase.java +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.test; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.execution.Execution; -import com.yahoo.processing.test.documentation.AsyncDataProcessingInitiator; -import com.yahoo.processing.test.documentation.AsyncDataProducer; -import com.yahoo.processing.test.documentation.ExampleProcessor; -import com.yahoo.processing.test.documentation.Federator; - -/** - * See to it we can actually run the examples in the doc. - * - * @author <a href="mailto:steinar@yahoo-inc.com">Steinar Knutsen</a> - */ -public class DocumentationTestCase { - - @SuppressWarnings("unchecked") - @Test - public final void test() { - Processor p = new ExampleProcessor(); - Chain<Processor> basic = new Chain<>(p); - Processor initiator = new AsyncDataProcessingInitiator(basic); - Chain<Processor> postProcessing = new Chain<>(initiator); - Execution e = Execution.createRoot(postProcessing, 0, Execution.Environment.createEmpty()); - Response r = e.process(new Request()); - // just adds a listener to the result returned from basic - assertEquals(0, r.data().asList().size()); - Processor producer = new AsyncDataProducer(); - Chain<Processor> asyncChain = new Chain<>(producer); - Processor federator = new Federator(basic, asyncChain); - e = Execution.createRoot(federator, 0, Execution.Environment.createEmpty()); - r = e.process(new Request()); - assertEquals(2, r.data().asList().size()); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/test/ProcessingTestCase.java b/processing/src/test/java/com/yahoo/processing/test/ProcessingTestCase.java deleted file mode 100644 index 77c2ca7d10d..00000000000 --- a/processing/src/test/java/com/yahoo/processing/test/ProcessingTestCase.java +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.test; - -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.execution.Execution; -import org.junit.Test; - -import static com.yahoo.processing.test.ProcessorLibrary.*; -import static org.junit.Assert.assertEquals; - -/** - * Tests the basic of the processing framework - */ -public class ProcessingTestCase { - - /** Execute three simple processors doing some phony processing */ - @Test - public void testChainedProcessing1() { - // Create a chain - Chain<Processor> chain=new Chain<>(new CombineData(),new Get6DataItems(), new DataSource()); - - // Execute it - Request request=new Request(); - request.properties().set("appendage",1); - Response response=Execution.createRoot(chain,0,Execution.Environment.createEmpty()).process(request); - - // Verify the result - assertEquals(6-1,response.data().asList().size()); - assertEquals("first.2, third.2",response.data().get(0).toString()); - assertEquals("second.2",response.data().get(1).toString()); - assertEquals("first.3",response.data().get(2).toString()); - assertEquals("second.3",response.data().get(3).toString()); - assertEquals("third.3",response.data().get(4).toString()); - } - - /** Execute the same processors in a different order */ - @Test - public void testChainedProcessing2() { - // Create a chain - Chain<Processor> chain=new Chain<>(new Get6DataItems(),new CombineData(), new DataSource()); - - // Execute it - Request request=new Request(); - request.properties().set("appendage",1); - Response response=Execution.createRoot(chain,0,Execution.Environment.createEmpty()).process(request); - - // Check the result - assertEquals(6,response.data().asList().size()); - assertEquals("first.2, third.2",response.data().get(0).toString()); - assertEquals("second.2",response.data().get(1).toString()); - assertEquals("first.4, third.4",response.data().get(2).toString()); - assertEquals("second.4",response.data().get(3).toString()); - assertEquals("first.6, third.6",response.data().get(4).toString()); - assertEquals("second.6",response.data().get(5).toString()); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/test/documentation/AsyncDataProcessingInitiator.java b/processing/src/test/java/com/yahoo/processing/test/documentation/AsyncDataProcessingInitiator.java deleted file mode 100644 index 0de20b962d7..00000000000 --- a/processing/src/test/java/com/yahoo/processing/test/documentation/AsyncDataProcessingInitiator.java +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.test.documentation; - -import com.google.common.util.concurrent.MoreExecutors; -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.*; -import com.yahoo.processing.execution.*; - -/** - * A processor which registers a listener on the future completion of - * asynchronously arriving data to perform another chain at that point. - */ -public class AsyncDataProcessingInitiator extends Processor { - - private final Chain<Processor> asyncChain; - - public AsyncDataProcessingInitiator(Chain<Processor> asyncChain) { - this.asyncChain=asyncChain; - } - - @Override - public Response process(Request request, Execution execution) { - Response response=execution.process(request); - response.data().complete().addListener(new RunnableExecution(request, - new ExecutionWithResponse(asyncChain, response, execution)), - MoreExecutors.directExecutor()); - return response; - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/test/documentation/AsyncDataProducer.java b/processing/src/test/java/com/yahoo/processing/test/documentation/AsyncDataProducer.java deleted file mode 100644 index c6c9c0d785b..00000000000 --- a/processing/src/test/java/com/yahoo/processing/test/documentation/AsyncDataProducer.java +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.test.documentation; - -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.execution.Execution; -import com.yahoo.processing.response.ArrayDataList; -import com.yahoo.processing.response.DataList; -import com.yahoo.processing.response.IncomingData; -import com.yahoo.processing.test.ProcessorLibrary.StringData; - -/** - * A data producer which producer data which will receive asynchronously. - * This is not a realistic, thread safe implementation as only the incoming data - * from the last created incoming data can be completed. - */ -public class AsyncDataProducer extends Processor { - - private IncomingData incomingData; - - @SuppressWarnings("unchecked") - @Override - public Response process(Request request, Execution execution) { - DataList dataList = ArrayDataList.createAsync(request); // Default implementation - incomingData=dataList.incoming(); - return new Response(dataList); - } - - /** Called by some other data producing thread, later */ - @SuppressWarnings("unchecked") - public void completeLateData() { - incomingData.addLast(new StringData(incomingData.getOwner().request(), - "A late hello, world!")); - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/test/documentation/ExampleProcessor.java b/processing/src/test/java/com/yahoo/processing/test/documentation/ExampleProcessor.java deleted file mode 100644 index 6a1e0cbdd58..00000000000 --- a/processing/src/test/java/com/yahoo/processing/test/documentation/ExampleProcessor.java +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.test.documentation; - -import com.yahoo.processing.*; -import com.yahoo.processing.execution.Execution; -import com.yahoo.processing.test.ProcessorLibrary.StringData; - -public class ExampleProcessor extends Processor { - - @SuppressWarnings("unchecked") - @Override - public Response process(Request request, Execution execution) { - // Process the Request: - request.properties().set("foo","bar"); - - // Pass it down the chain to get a response - Response response=execution.process(request); - - // process the response - response.data().add(new StringData(request,"Hello, world!")); - - return response; - } - -} diff --git a/processing/src/test/java/com/yahoo/processing/test/documentation/Federator.java b/processing/src/test/java/com/yahoo/processing/test/documentation/Federator.java deleted file mode 100644 index 079c4912fd9..00000000000 --- a/processing/src/test/java/com/yahoo/processing/test/documentation/Federator.java +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.processing.test.documentation; - -import com.yahoo.component.chain.Chain; -import com.yahoo.processing.Processor; -import com.yahoo.processing.Request; -import com.yahoo.processing.Response; -import com.yahoo.processing.execution.AsyncExecution; -import com.yahoo.processing.execution.Execution; -import com.yahoo.processing.response.FutureResponse; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Call a number of chains in parallel - */ -public class Federator extends Processor { - - private final List<Chain<? extends Processor>> chains; - - @SafeVarargs - @SuppressWarnings("varargs") - public Federator(Chain<? extends Processor> ... chains) { - this.chains = Arrays.asList(chains); - } - - @SuppressWarnings("unchecked") - @Override - public Response process(Request request, Execution execution) { - List<FutureResponse> futureResponses=new ArrayList<>(chains.size()); - for (Chain<? extends Processor> chain : chains) { - futureResponses.add(new AsyncExecution(chain,execution).process(request)); - } - Response response=execution.process(request); - AsyncExecution.waitForAll(futureResponses,1000); - for (FutureResponse futureResponse : futureResponses) { - Response federatedResponse=futureResponse.get(); - response.data().add(federatedResponse.data()); - response.mergeWith(federatedResponse); - } - return response; - } -} |