You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stanbol.apache.org by rw...@apache.org on 2012/02/01 12:59:38 UTC
svn commit: r1239097 [2/2] - in /incubator/stanbol/trunk:
enhancer/chain/list/src/main/java/org/apache/stanbol/enhancer/chain/list/impl/
enhancer/chain/list/src/main/resources/OSGI-INF/metatype/
enhancer/generic/servicesapi/src/main/java/org/apache/sta...
Modified: incubator/stanbol/trunk/enhancer/jersey/src/main/java/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/java/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource.java?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/java/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource.java (original)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/java/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource.java Wed Feb 1 11:59:37 2012
@@ -25,12 +25,16 @@ import static org.apache.stanbol.commons
import static org.apache.stanbol.commons.web.base.CorsHelper.enableCORS;
import static org.apache.stanbol.commons.web.base.utils.MediaTypeUtil.SUPPORTED_RDF_TYPES;
import static org.apache.stanbol.commons.web.base.utils.MediaTypeUtil.isAcceptableMediaType;
+import static org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper.getReference;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.getExecutionNode;
import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.isOptional;
import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionPlan.EXECUTION_NODE;
import static org.apache.stanbol.enhancer.servicesapi.rdf.Properties.RDF_TYPE;
import java.io.IOException;
+import java.net.URI;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -58,6 +62,8 @@ import org.apache.clerezza.rdf.core.Grap
import org.apache.clerezza.rdf.core.MGraph;
import org.apache.clerezza.rdf.core.NonLiteral;
import org.apache.clerezza.rdf.core.Triple;
+import org.apache.clerezza.rdf.core.TripleCollection;
+import org.apache.clerezza.rdf.core.UriRef;
import org.apache.clerezza.rdf.core.access.TcManager;
import org.apache.clerezza.rdf.core.impl.PlainLiteralImpl;
import org.apache.clerezza.rdf.core.serializedform.Serializer;
@@ -74,8 +80,12 @@ import org.apache.stanbol.enhancer.servi
import org.apache.stanbol.enhancer.servicesapi.EnhancementEngineManager;
import org.apache.stanbol.enhancer.servicesapi.EnhancementException;
import org.apache.stanbol.enhancer.servicesapi.EnhancementJobManager;
+import org.apache.stanbol.enhancer.servicesapi.NoSuchPartException;
+import org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper;
+import org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper;
import org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper;
import org.apache.stanbol.enhancer.servicesapi.helper.InMemoryContentItem;
+import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata;
import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionPlan;
import org.apache.stanbol.enhancer.servicesapi.rdf.Properties;
import org.slf4j.Logger;
@@ -121,6 +131,10 @@ public class EnhancerRootResource extend
chain = chainManager.getDefault();
}
+ public URI getServiceUrl(){
+ return uriInfo.getAbsolutePath();
+ }
+
@OPTIONS
public Response handleCorsPreflight(@Context HttpHeaders headers){
ResponseBuilder res = Response.ok();
@@ -251,7 +265,7 @@ public class EnhancerRootResource extend
@Context HttpHeaders headers) throws EnhancementException, IOException {
log.info("enhance from From: " + content);
ContentItem ci = new InMemoryContentItem(content.getBytes("UTF-8"), TEXT_PLAIN);
- return enhanceAndBuildResponse(format, headers, ci, buildAjaxview);
+ return enhanceAndBuildResponse(format, headers, ci, false ,buildAjaxview);
}
/**
@@ -269,6 +283,7 @@ public class EnhancerRootResource extend
@Consumes(WILDCARD)
public Response enhanceFromData(byte[] data,
@QueryParam(value = "uri") String uri,
+ @QueryParam(value = "executionmetadata") boolean inclExecMetadata,
@Context HttpHeaders headers) throws EnhancementException, IOException {
String format = TEXT_PLAIN;
if (headers.getMediaType() != null) {
@@ -279,12 +294,13 @@ public class EnhancerRootResource extend
uri = null;
}
ContentItem ci = new InMemoryContentItem(uri, data, format);
- return enhanceAndBuildResponse(null, headers, ci, false);
+ return enhanceAndBuildResponse(null, headers, ci, inclExecMetadata, false);
}
protected Response enhanceAndBuildResponse(String format,
HttpHeaders headers,
ContentItem ci,
+ boolean inclExecMetadata ,
boolean buildAjaxview) throws EnhancementException, IOException {
if (jobManager != null) {
jobManager.enhanceContent(ci,chain);
@@ -302,6 +318,13 @@ public class EnhancerRootResource extend
}
MGraph graph = ci.getMetadata();
+ if(inclExecMetadata){
+ try {
+ graph.addAll(ci.getPart(ExecutionMetadata.CHAIN_EXECUTION, MGraph.class));
+ } catch (NoSuchPartException e) {
+ // no executionMetadata available
+ }
+ }
ResponseBuilder rb = Response.ok(graph);
List<String> accepted = headers.getRequestHeader(HttpHeaders.ACCEPT);
MediaType mediaType = MediaTypeUtil.getAcceptableMediaType(headers,null);
@@ -321,11 +344,11 @@ public class EnhancerRootResource extend
public class ExecutionNode {
private final NonLiteral node;
- private final Graph ep;
+ private final TripleCollection ep;
private final boolean optional;
private final String engineName;
- public ExecutionNode(Graph executionPlan, NonLiteral node) {
+ public ExecutionNode(TripleCollection executionPlan, NonLiteral node) {
this.node = node;
this.ep = executionPlan;
this.optional = ExecutionPlanHelper.isOptional(ep, node);
@@ -354,4 +377,5 @@ public class EnhancerRootResource extend
return o instanceof ExecutionNode && ((ExecutionNode)o).node.equals(node);
}
}
+
}
Modified: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/ajax/contentitem.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/ajax/contentitem.ftl?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/ajax/contentitem.ftl (original)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/ajax/contentitem.ftl Wed Feb 1 11:59:37 2012
@@ -15,8 +15,11 @@
limitations under the License.
-->
<#import "/imports/contentitem.ftl" as contentitem>
+<#import "/imports/executionmetadata.ftl" as executionmetadata>
<#escape x as x?html>
+<@executionmetadata.view />
+
<@contentitem.view />
<h3>Raw RDF output</h3>
Added: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/imports/executionmetadata.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/imports/executionmetadata.ftl?rev=1239097&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/imports/executionmetadata.ftl (added)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/imports/executionmetadata.ftl Wed Feb 1 11:59:37 2012
@@ -0,0 +1,78 @@
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<#macro view>
+
+<h3>Enhancement Process Metadata</h3>
+<div id="executionmetadata" class="enginelisting">
+ <script>
+ $("#executionmetadata p").click(function () {
+ $(this).parents("div").toggleClass("collapsed");
+ });
+ </script>
+ <#if !it.chainExecution??>
+ <p> No metadata available <small>
+ (This indicates that the used EnhancementJobManager
+ does not support this feature)</small><p>
+ <#else>
+ <#if it.chainExecution.failed>
+ <div>
+ <#else>
+ <div class="collapsed">
+ </#if>
+ <p class="collapseheader"> Execution of Chain
+ <#if it.chainExecution.completed>
+ <span style="color:#006600">
+ <#elseif it.chainExecution.failed>
+ <span style="color:#660000">
+ <#else>
+ <span>
+ </#if>
+ <strong>${it.chainExecution.chainName}</strong>
+ ${it.chainExecution.statusText} </span>
+ in <strong>${it.chainExecution.durationText}</strong>.
+ </p>
+ <div class="collapsable">
+ <ul>
+ <#list it.engineExecutions as node>
+ <li><#if node.offsetText??>${node.offsetText}<#else>${node.startTime}</#if>:
+ <#if node.completed>
+ <span style="color:#006600">
+ <#elseif node.failed && node.executionNode.optional>
+ <span style="color:#666666">
+ <#elseif node.failed && !node.executionNode.optional>
+ <span style="color:#660000">
+ <#else>
+ <span>
+ </#if>
+ <b>${node.statusText}</b></span>
+ in ${node.durationText} :
+ <b>${node.executionNode.engineName}</b>
+ <small>(
+ <#if node.executionNode.optional> optional <#else> required </#if>,
+ start: ${node.startTime}, completion: ${node.completionTime})
+ </small>
+ </span>
+ </li>
+ </#list>
+ </ul>
+ </div>
+ </div>
+ </#if>
+</div>
+
+
+</#macro>
Added: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/ChainsRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/ChainsRootResource/index.ftl?rev=1239097&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/ChainsRootResource/index.ftl (added)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/ChainsRootResource/index.ftl Wed Feb 1 11:59:37 2012
@@ -0,0 +1,62 @@
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<#import "/imports/common.ftl" as common>
+<#escape x as x?html>
+<@common.page title="Enhancement Chains" hasrestapi=true>
+
+
+<div class="panel" id="webview">
+<p> Enhancement Chains define a set of Enhancement Engines as well as the
+execution oder of those used to enhance content parsed to the Stanbol Enhancer.<p>
+Currently the following Chains are available:
+<ul>
+ <#list it.chains as chain>
+ <#assign name = chain.name >
+ <li> <a href="${it.publicBaseUri}enhancer/chain/${name}">${name}</a>
+ (<#if it.isDefault(name)><b>default</b>,</#if>
+ id: ${it.getServiceId(name)}, ranking: ${it.getServiceRanking(name)},
+ impl: ${chain.class.simpleName}
+ )<#if it.getServicePid(name)??>:
+ <a href="/system/console/configMgr/${it.getServicePid(name)}">configure</a></#if>
+ </#list>
+</ul>
+<p>Enhancement Request for the <a href="${it.publicBaseUri}enhancer">
+/enhancer</a> and <a href="${it.publicBaseUri}engines">
+/engines</a> endpoints are processed by using the default chain - the engine
+in the above list marked as <b>default</b>. </p><p>
+The default Chain is defined as (1) the Chain with the name "default"
+and the highest <code>service.ranking</code> or (2) if no Chain has the name
+"default" is active than the Chain with the highest <code>service.ranking</code>
+(regardless of the name).<p>
+
+<p class="note">
+You can configure Chains by using the the <a href="/system/console/configMgr">
+Configuration Tab</a> of the OSGi console.</p>
+
+</div>
+
+<div class="panel" id="restapi" style="display: none;">
+<h3>Enhancement Chains RESTful API</h3>
+
+<p>This stateless interface allows the caller to query all available
+Enhancement Chains</p>
+
+</div>
+
+
+</...@common.page>
+</#escape>
Added: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEngineResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEngineResource/index.ftl?rev=1239097&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEngineResource/index.ftl (added)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEngineResource/index.ftl Wed Feb 1 11:59:37 2012
@@ -0,0 +1,58 @@
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<#import "/imports/common.ftl" as common>
+<#escape x as x?html>
+<@common.page title="Enhancement Engine ${it.name}" hasrestapi=true>
+
+
+<div class="panel" id="webview">
+<p> Enhancement Engine Details: <ul>
+<li> name: ${it.name}
+<li> class: ${it.engine.class}
+<li> ordering: ${it.ordering}
+<li> service.id : ${it.id}
+<li> service.ranking: ${it.ranking}
+</ul>
+<p class="note"> You can <a href="/system/console/configMgr/${it.pid}">
+configure this engine</a> by using the the Configuration Tab of the OSGi console.</p>
+
+<#--
+<p> This is the list of all active Enhancement Engines active for
+the name ${it.name}:
+<ul>
+ <#list it.engines as engine>
+ <li> <a href="${it.publicBaseUri}enhancer/engine/${engine.name}">${engine.name}</a>
+ (impl: ${engine.class.simpleName})
+ </#list>
+</ul>
+<p>
+
+-->
+</div>
+
+<div class="panel" id="restapi" style="display: none;">
+<h3>Enhancement Engines RESTful API</h3>
+
+<p>This stateless interface allows the caller to query all available
+Enhancement Engines</p>
+
+
+</div>
+
+
+</...@common.page>
+</#escape>
Added: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEnginesRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEnginesRootResource/index.ftl?rev=1239097&view=auto
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEnginesRootResource/index.ftl (added)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancementEnginesRootResource/index.ftl Wed Feb 1 11:59:37 2012
@@ -0,0 +1,54 @@
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<#import "/imports/common.ftl" as common>
+<#escape x as x?html>
+<@common.page title="Enhancement Engines" hasrestapi=true>
+
+
+<div class="panel" id="webview">
+
+<p> This is the list of all active Enhancement Engines.
+<ul>
+ <#list it.engines as engine>
+ <#assign name = engine.name >
+ <li> <a href="${it.publicBaseUri}enhancer/engine/${name}">${name}</a>
+ (id: ${it.getServiceId(name)}, ranking: ${it.getServiceRanking(name)},
+ impl: ${engine.class.simpleName}
+ )<#if it.getServicePid(name)??>:
+ <a href="/system/console/configMgr/${it.getServicePid(name)}">configure</a></#if>
+ </#list>
+</ul>
+<p>
+EnhancementEngines are used to define <a href="${it.publicBaseUri}enhancer/chain">
+Enhancement Chains</a> that can than be used to enhance content parsed to the
+Stanbol Enhancer.</p>
+<p class="note"> You can configure Chains by using the the
+<a href="/system/console/configMgr">Configuration Tab</a> of the OSGi console.</p>
+</div>
+
+<div class="panel" id="restapi" style="display: none;">
+<h3>Enhancement Engines RESTful API</h3>
+
+<p>This stateless interface allows the caller to query all available
+Enhancement Engines</p>
+
+
+</div>
+
+
+</...@common.page>
+</#escape>
Modified: incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource/index.ftl
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource/index.ftl?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource/index.ftl (original)
+++ incubator/stanbol/trunk/enhancer/jersey/src/main/resources/org/apache/stanbol/enhancer/jersey/templates/org/apache/stanbol/enhancer/jersey/resource/EnhancerRootResource/index.ftl Wed Feb 1 11:59:37 2012
@@ -16,7 +16,7 @@
-->
<#import "/imports/common.ftl" as common>
<#escape x as x?html>
-<@common.page title="Enhancement Engines" hasrestapi=true>
+<@common.page title="Apache Stanbol Enhancer" hasrestapi=true>
<div class="panel" id="webview">
@@ -36,16 +36,20 @@
<#else>
<div>
</#if>
- <p class="collapseheader">There are currently
- <#if it.activeNodes?size < it.executionNodes?size>
- <strong>${it.activeNodes?size}/</strong><#else>all </#if><strong>${it.executionNodes?size}</strong>
- engines available for enhancement chain
+ <p class="collapseheader">Enhancement Chain:
<#if it.chainAvailable>
<span style="color:#006600">
<#else>
<span style="color:#660000">
</#if>
- <strong>${it.chain.name}</strong></span></p>
+ <strong>${it.chain.name}</strong></span>
+ <#if it.activeNodes?size < it.executionNodes?size>
+ <strong>${it.activeNodes?size}/</strong><#else> all </#if><strong>${it.executionNodes?size}</strong>
+ engines available
+ <span style="float: right; margin-right: 25px;">
+ < List of <a href="#">Enhancement Chains</a> >
+ </span>
+ </p>
<div class="collapsable">
<ul>
<#list executionNodes as node>
@@ -78,10 +82,17 @@
<script>
$(".enginelisting p").click(function () {
$(this).parents("div").toggleClass("collapsed");
-});
+})
+.find("a").click(function(e){
+ e.stopPropagation();
+ //link to all active Enhancement Chains
+ window.location = "${it.publicBaseUri}enhancer/chain";
+ return false;
+});
</script>
-
- <p>Paste some text below and submit the form to let the active engines enhance it:</p>
+</#if>
+<#if it.chainAvailable>
+ <p>Paste some text below and submit the form to let the Enhancement Chain ${it.chain.name} enhance it:</p>
<form id="enginesInput" method="POST" accept-charset="utf-8">
<p><textarea rows="15" name="content"></textarea></p>
<p class="submitButtons">Output format:
@@ -150,7 +161,7 @@ in the format specified in the <code>Acc
<pre>
curl -X POST -H "Accept: text/turtle" -H "Content-type: text/plain" \
- --data "John Smith was born in London." ${it.publicBaseUri}engines
+ --data "John Smith was born in London." ${it.serviceUrl}
</pre>
<p>The list of mimetypes accepted as inputs depends on the deployed engines. By default only
@@ -165,16 +176,28 @@ curl -X POST -H "Accept: text/turtle" -H
<li><code>text/rdf+nt</code> (N-TRIPLES)</li>
</ul>
-<p>By default the URI of the content item being enhanced is a local, non
-de-referencable URI automatically built out of a hash digest of the binary
-content. Sometimes it might be helpful to provide the URI of the content-item
-to be used in the enhancements RDF graph. This can be achieved by passing a
-<code>uri</code> request parameter as follows:</p>
+<p> Additional supported QueryParameters:<ul>
+<li><code>uri={content-item-uri}</code>: By default the URI of the content
+ item being enhanced is a local, non de-referencable URI automatically built
+ out of a hash digest of the binary content. Sometimes it might be helpful
+ to provide the URI of the content-item to be used in the enhancements RDF
+ graph.
+<code>uri</code> request parameter
+<li><code>executionmetadata=true/false</code>:
+ Allows the include of execution metadata in the response. Such data include
+ the ExecutionPlan as provided by the enhancement chain as well as
+ information about the actual execution of that plan. The default value
+ is <code>false</code>.</li>
+</ul>
+
+<p>The following example shows how to send an enhancement request with a
+custom content item URI that will include the execution metadata in the
+response.</p>
<pre>
curl -X POST -H "Accept: text/turtle" -H "Content-type: text/plain" \
--data "John Smith was born in London." \
- "${it.publicBaseUri}engines?uri=urn:fise-example-content-item"
+ "${it.serviceUrl}?uri=urn:fise-example-content-item&executionmetadata=true"
</pre>
</div>
Propchange: incubator/stanbol/trunk/enhancer/jobmanager/event/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Feb 1 11:59:37 2012
@@ -3,3 +3,5 @@
.classpath
target
+
+.settings
Modified: incubator/stanbol/trunk/enhancer/jobmanager/event/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jobmanager/event/pom.xml?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jobmanager/event/pom.xml (original)
+++ incubator/stanbol/trunk/enhancer/jobmanager/event/pom.xml Wed Feb 1 11:59:37 2012
@@ -84,10 +84,10 @@
<groupId>org.apache.clerezza</groupId>
<artifactId>rdf.core</artifactId>
</dependency>
-<!-- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- </dependency> -->
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
<!-- for tests -->
<dependency>
<groupId>junit</groupId>
Modified: incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/Constants.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/Constants.java?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/Constants.java (original)
+++ incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/Constants.java Wed Feb 1 11:59:37 2012
@@ -2,6 +2,7 @@ package org.apache.stanbol.enhancer.jobm
import org.apache.clerezza.rdf.core.NonLiteral;
import org.apache.stanbol.enhancer.jobmanager.event.impl.EnhancementJob;
+import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventConstants;
@@ -24,8 +25,9 @@ public interface Constants {
*/
String PROPERTY_JOB_MANAGER = "stanbol.enhancer.jobmanager.event.job";
/**
- * Property used to provide the {@link NonLiteral} node to execute
+ * Property used to provide the {@link NonLiteral} describing the
+ * {@link ExecutionMetadata#EXECUTION} instance
*/
- String PROPERTY_NODE = "stanbol.enhancer.jobmanager.event.node";
+ String PROPERTY_EXECUTION = "stanbol.enhancer.jobmanager.event.execution";
}
Modified: incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJob.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJob.java?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJob.java (original)
+++ incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJob.java Wed Feb 1 11:59:37 2012
@@ -1,25 +1,60 @@
package org.apache.stanbol.enhancer.jobmanager.event.impl;
+import static org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper.getReference;
+import static org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper.getString;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.createChainExecutionNode;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.getChainExecution;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.getExecutionPlanNode;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.initExecutionMetadata;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.initExecutionMetadataContentPart;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.isExecutionFailed;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.setExecutionCompleted;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.setExecutionFaild;
+import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper.setExecutionInProgress;
import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.getDependend;
import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.getEngine;
import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.isOptional;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.CHAIN_EXECUTION;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.ENHANCED_BY;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.ENHANCES;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS_IN_PROGRESS;
+import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionPlan.CHAIN;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import org.apache.clerezza.rdf.core.Graph;
+import org.apache.clerezza.rdf.core.MGraph;
import org.apache.clerezza.rdf.core.NonLiteral;
+import org.apache.clerezza.rdf.core.Triple;
+import org.apache.clerezza.rdf.core.TripleCollection;
+import org.apache.clerezza.rdf.core.UriRef;
+import org.apache.clerezza.rdf.core.access.LockableMGraph;
+import org.apache.clerezza.rdf.core.access.LockableMGraphWrapper;
+import org.apache.clerezza.rdf.core.impl.PlainLiteralImpl;
+import org.apache.clerezza.rdf.core.impl.SimpleMGraph;
+import org.apache.commons.collections.BidiMap;
+import org.apache.commons.collections.bidimap.DualHashBidiMap;
import org.apache.stanbol.enhancer.servicesapi.Chain;
import org.apache.stanbol.enhancer.servicesapi.ContentItem;
import org.apache.stanbol.enhancer.servicesapi.EnhancementEngine;
import org.apache.stanbol.enhancer.servicesapi.EnhancementJobManager;
+import org.apache.stanbol.enhancer.servicesapi.NoSuchPartException;
+import org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper;
+import org.apache.stanbol.enhancer.servicesapi.helper.ExecutionMetadataHelper;
import org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper;
+import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata;
+import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionPlan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,36 +83,201 @@ public class EnhancementJob {
private final Lock readLock;
private final Lock writeLock;
+ /**
+ * The read only executionPlan
+ */
private final Graph executionPlan;
+ /**
+ * The read/write able execution metadata. Also accessible via
+ * {@link ContentItem#getPart(UriRef, Class)} with the URI
+ * {@link ExecutionMetadata#CHAIN_EXECUTION}
+ */
+ private final MGraph executionMetadata;
+ /**
+ * Map with the em:Execution nodes of the em:ChainExecution for this
+ * ContentItem. Values are are ep:ExecutionNodes of the ep:ExecutionPlan
+ */
+ private final BidiMap executionsMap;
+ /**
+ * The em:ChainExecution for this {@link ContentItem}
+ */
+ private final NonLiteral chainExecutionNode;
+ /**
+ * The ep:ExecutionPlan for this {@link ContentItem}
+ */
+ private final NonLiteral executionPlanNode;
+ /**
+ * The name of the {@link Chain} used to enhance this {@link ContentItem}.
+ */
private final String chain;
+ /**
+ * The ContentItem
+ */
private final ContentItem contentItem;
- private final Set<NonLiteral> completed;
- private final Set<NonLiteral> unmodCompleted;
- private final Set<NonLiteral> running;
- private final Set<NonLiteral> unmodRunning;
+ /**
+ * The completed ep:ExecutionPlan nodes. <p>
+ * NOTE: This contains ep:ExecutionNodes and NOT em:Exetution instances!
+ */
+ private final Set<NonLiteral> completed = new HashSet<NonLiteral>();
+ /**
+ * Unmodifiable and final set of completed executables. Replaced by a new
+ * instance every time {@link #completed} changes
+ */
+ private Set<NonLiteral> completedExec = Collections.emptySet();
+ /**
+ * The running ep:ExecutionPlan nodes <p>
+ * NOTE: This contains ep:ExecutionNodes and NOT em:Exetution instances!
+ */
+ private final Set<NonLiteral> running = new HashSet<NonLiteral>();
+ /**
+ * Unmodifiable and final set of running executables. Replaced by a new
+ * instance every time {@link #running} changes.
+ */
+ private Set<NonLiteral> runningExec = Collections.emptySet();
+ /**
+ * Unmodifiable and final set of executable em:Execution nodes.
+ * Replaced by a new instance every time {@link #running} or
+ * {@link #completed} changes.
+ */
private Set<NonLiteral> executable;
- private boolean failed = false;
- private List<String> errormessages = new ArrayList<String>();
+ /**
+ * Used to store any {@link Exception} parsed with the call to
+ * {@link #setFailed(NonLiteral, EnhancementEngine, Exception)} causing the
+ * enhancement process to fail. This Exception is typically re-thrown by the
+ * {@link EnhancementJobManager#enhanceContent(ContentItem, Chain)} method.
+ * @see #getError()
+ */
private Exception error = null;
-
- public EnhancementJob(ContentItem contentItem, String chainName, Graph executionPlan) {
+ /**
+ * Constructor used to create and initialise a new enhancement job. This
+ * will create the initial set of ExecutionMetadata and add them as
+ * ContentPart with the URI {@link ExecutionMetadata#CHAIN_EXECUTION} to the
+ * ContentItem.
+ * @param contentItem
+ * @param chainName
+ * @param executionPlan
+ * @param isDefaultChain
+ */
+ public EnhancementJob(ContentItem contentItem, String chainName, Graph executionPlan, boolean isDefaultChain) {
if (contentItem == null || chainName == null || executionPlan == null) {
throw new IllegalArgumentException("The parsed contentItem and executionPlan MUST NOT be NULL");
}
- this.contentItem = contentItem;
this.readLock = contentItem.getLock().readLock();
this.writeLock = contentItem.getLock().writeLock();
+ executionMetadata = initExecutionMetadataContentPart(contentItem);
+ if(executionMetadata.isEmpty()){
+ //if we init from scratch
+ this.executionsMap = new DualHashBidiMap(initExecutionMetadata(executionMetadata, executionPlan,
+ contentItem.getUri(), chainName, isDefaultChain));
+ chainExecutionNode = getChainExecution(executionMetadata, contentItem.getUri());
+ executionPlanNode = getExecutionPlanNode(executionMetadata, chainExecutionNode);
+ executionMetadata.addAll(executionPlan);
+ } else {
+ throw new IllegalArgumentException("Unable to create EnhancementJob for "
+ + "a parsed execution plan if the ContentItem already contains "
+ + "some Execution Metadata!");
+ }
+ this.contentItem = contentItem;
this.executionPlan = executionPlan;
this.chain = chainName;
- completed = new HashSet<NonLiteral>();
- unmodCompleted = Collections.unmodifiableSet(completed);
- running = new HashSet<NonLiteral>();
- unmodRunning = Collections.unmodifiableSet(running);
//check the first engines to execute
checkExecutable();
}
+ /**
+ * Creates an EnhancemenJob based on already existing execution metadata present
+ * for a ContentItem.
+ * @param contentItem the ContentItem with an already existing content part
+ * containing an {@link MGraph} with all required execution metadata and the
+ * execution plan.
+ * @throws IllegalArgumentException if the parsed {@link ContentItem} does
+ * not provide the required data to (re)initialise the EnhancementJob.
+ */
+ public EnhancementJob(ContentItem contentItem){
+ if (contentItem == null){
+ throw new IllegalArgumentException("The parsed ContentItem MUST NOT be NULL!");
+ }
+ this.contentItem = contentItem;
+ this.readLock = contentItem.getLock().readLock();
+ this.writeLock = contentItem.getLock().writeLock();
+ try {
+ contentItem.getPart(ExecutionMetadata.CHAIN_EXECUTION, MGraph.class);
+ } catch (NoSuchPartException e) {
+ throw new IllegalArgumentException("Cannot (re)initialise an EnhancementJob" +
+ "without existing execution metadata content part!",e);
+ }
+ executionMetadata = initExecutionMetadataContentPart(contentItem);
+ this.executionPlan = executionMetadata.getGraph();
+ chainExecutionNode = getChainExecution(executionMetadata, contentItem.getUri());
+ if(chainExecutionNode == null){
+ throw new IllegalArgumentException("Cannot (re)initialise an EnhancementJob" +
+ "because the ExecutionMetadata do not contain an em:ChainExecution" +
+ "for the given ContentItem '"+contentItem.getUri()+"'!");
+ }
+ executionPlanNode = getExecutionPlanNode(executionMetadata, chainExecutionNode);
+ if(executionPlanNode == null){
+ throw new IllegalArgumentException("Cannot (re)initialise an EnhancementJob" +
+ "because the ExecutionMetadata do not contain an ep:ExecutionPlan" +
+ "for the given ContentItem '"+contentItem.getUri()+"'!");
+ }
+ this.chain = getString(executionPlan, executionPlanNode, CHAIN);
+ if(chain == null || chain.isEmpty()){
+ throw new IllegalArgumentException("Cannot (re)initialise an EnhancementJob " +
+ "because the ExecutionMetadata do not define a valid chain name for " +
+ "the ep:ExecutionPlan node '" + executionPlanNode+"' as used to " +
+ "enhance ContentItem '"+contentItem.getUri()+"'!");
+ }
+ //the executionPlan is part of the execution metadata
+ Map<NonLiteral,NonLiteral> executionsMap = initExecutionMetadata(executionMetadata,
+ executionPlan, contentItem.getUri(), null, null);
+ for(Entry<NonLiteral,NonLiteral> executionEntry : executionsMap.entrySet()){
+ UriRef status = getReference(executionMetadata, executionEntry.getKey(), STATUS);
+ if(status == null){
+ throw new IllegalArgumentException("The ex:Execution '"
+ + executionEntry.getKey()+"' of the ex:ChainExecution for ContentItme '"
+ + contentItem.getUri()+"' is missing a required value for the property '"
+ + STATUS+"'!");
+ }
+ if(status.equals(STATUS_IN_PROGRESS)){
+ //re-schedule unfinished enhancement jobs
+ ExecutionMetadataHelper.setExecutionScheduled(executionMetadata, executionEntry.getKey());
+ } else if(status.equals(ExecutionMetadata.STATUS_COMPLETED) ||
+ status.equals(ExecutionMetadata.STATUS_FAILED)){
+ completed.add(executionEntry.getValue());
+ }
+ }
+ this.executionsMap = new DualHashBidiMap(executionsMap);
+ //check the first engines to execute after continuation
+ checkExecutable();
+ }
+
+ /**
+ * Getter for the ep:ExecutionNode linked to a em:Execution
+ * @return the ep:ExecutionNode instance
+ * @throws IllegalArgumentException if the parsed em:Execution is not
+ * part of the execution metadata of this enhancement job
+ */
+ public NonLiteral getExecutionNode(NonLiteral execution){
+ NonLiteral node = (NonLiteral)executionsMap.get(execution);
+ if(node == null){
+ throw new IllegalArgumentException("Unknown sp:ExecutionNode instance "+node);
+ }
+ return node;
+ }
+ /**
+ * Getter for the em:Execution linked to a ep:ExecutionNode
+ * @return the em:Execution instance
+ * @throws IllegalArgumentException if the parsed ep:ExecutionNode is not
+ * part of the execution plan of this enhancement job
+ */
+ public NonLiteral getExecution(NonLiteral executionNode){
+ NonLiteral execution = (NonLiteral)executionsMap.getKey(executionNode);
+ if(execution == null){
+ throw new IllegalArgumentException("Unknown em:Execution instance "+executionNode);
+ }
+ return execution;
+ }
/**
* The used execution plan for processing the {@link ContentItem}
@@ -132,7 +332,7 @@ public class EnhancementJob {
readLock.lock();
try {
log.debug(">> r: {}","getRunning");
- return unmodRunning;
+ return runningExec;
} finally {
log.debug("<< r: {}","getRunning");
readLock.unlock();
@@ -149,7 +349,7 @@ public class EnhancementJob {
readLock.lock();
try {
log.debug(">> r: {}","getCompleted");
- return unmodCompleted;
+ return completedExec;
} finally {
log.debug("<< r: {}","getCompleted");
readLock.unlock();
@@ -161,151 +361,207 @@ public class EnhancementJob {
* confirms to the ExectionPlan (e.g. if all nodes the parsed node depends on are also marked as
* completed).
*
- * @param executionNode
- * the exectionNode to be marked as running
+ * @param execution
+ * the exection to be marked as running
* @throws IllegalArgumentException
* if <code>null</code> is parsed as execution node
* @throws IllegalStateException
* if the parsed execution node can not be marked as completed because some of its
* depended nodes are not yet marked as completed.
*/
- public void setCompleted(NonLiteral executionNode) {
- if (executionNode != null) {
- String engine = getEngine(executionPlan, executionNode);
- boolean optional = isOptional(executionPlan, executionNode);
- Set<NonLiteral> dependsOn = getDependend(executionPlan, executionNode);
- log.debug("++ w: {}: {}","setCompleted",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
- writeLock.lock();
- try {
- log.debug(">> w: {}: {}","setCompleted",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
- if (completed.contains(executionNode)) {
- log.warn("Execution of Engine '{}' for ContentItem {} already "
- + "marked as completed(chain: {}, node: {}, optional {})."
- + " -> call ignored",
- new Object[] {engine, contentItem.getUri().getUnicodeString(),
- chain, executionNode, optional});
- return;
- }
- if (!completed.containsAll(dependsOn)) {
- // TODO maybe define an own Exception for such cases
- throw new IllegalStateException(
- "Unable to set state of ExectionNode '"
- + executionNode+ "' (chain '"+ chain
- + "' | contentItem '"+ contentItem.getUri()
- + "') to completed, because some of its depended "
- + "nodes are not marked completed yet. This indicates an Bug in the "
- + "implementation of the JobManager used to execute the ExecutionPlan. "
- + "(this.dependsOn=" + dependsOn + "| chain.completed " + completed
- + " | chain.running " + running + ")!");
- }
- if (running.remove(executionNode)) {
- log.info(
- "Execution of '{}' for ContentItem {} completed "
- + "(chain: {}, node: {}, optional {})",
- new Object[] {engine, contentItem.getUri().getUnicodeString(),
- chain, executionNode, optional});
- }
- completed.add(executionNode);
- // update the executables ... this will also recognise if finished
- checkExecutable();
- } finally {
- log.debug("<< w: {}: {}","setCompleted",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
- writeLock.unlock();
- }
+ public void setCompleted(NonLiteral execution) {
+ if(execution == null) {
+ throw new IllegalArgumentException("The parsed em:Execution instance MUST NOT be NULL!");
+ }
+ writeLock.lock();
+ log.debug("++ w: {}: {}","setCompleted",getEngine(executionPlan, execution));
+ try {
+ log.debug(">> w: {}: {}","setCompleted",getEngine(executionPlan, execution));
+ setNodeCompleted(getExecutionNode(execution));
+ setExecutionCompleted(executionMetadata, execution, null);
+ } finally {
+ log.debug("<< w: {}: {}","setCompleted",getEngine(executionPlan, execution));
+ writeLock.unlock();
}
}
+ /**
+ * Internally used to update the state kept in {@link #completed} and
+ * {@link #running} and {@link #executable} after an execution was set to
+ * {@link #setCompleted(NonLiteral) completed} or
+ * {@link #setFailed(NonLiteral, EnhancementEngine, Exception) failed}.<p>
+ * This method expects to be called within an active {@link #writeLock}.
+ * @param executionNode the ep:ExecutionNode linked to the em:Execution that
+ * finished.
+ */
+ private void setNodeCompleted(NonLiteral executionNode) {
+ String engine = getEngine(executionPlan, executionNode);
+ boolean optional = isOptional(executionPlan, executionNode);
+ Set<NonLiteral> dependsOn = getDependend(executionPlan, executionNode);
+ if (completed.contains(executionNode)) {
+ log.warn("Execution of Engine '{}' for ContentItem {} already "
+ + "marked as completed(chain: {}, node: {}, optional {})."
+ + " -> call ignored",
+ new Object[] {engine, contentItem.getUri().getUnicodeString(),
+ chain, executionNode, optional});
+ return;
+ }
+ if (!completed.containsAll(dependsOn)) {
+ // TODO maybe define an own Exception for such cases
+ throw new IllegalStateException("Unable to set state of ExectionNode '"
+ + executionNode+ "' (chain '"+ chain
+ + "' | contentItem '"+ contentItem.getUri()
+ + "') to completed, because some of its depended "
+ + "nodes are not marked completed yet. This indicates an Bug in the "
+ + "implementation of the JobManager used to execute the ExecutionPlan. "
+ + "(this.dependsOn=" + dependsOn + "| chain.completed " + completed
+ + " | chain.running " + running + ")!");
+ }
+ if (running.remove(executionNode)) {
+ log.info(
+ "Execution of '{}' for ContentItem {} completed "
+ + "(chain: {}, node: {}, optional {})",
+ new Object[] {engine, contentItem.getUri().getUnicodeString(),
+ chain, executionNode, optional});
+ }
+ completed.add(executionNode);
+ //update the set with the completed and running executables
+ updateCompletedExec();
+ updateRunningExec();
+ // update the executables ... this will also recognise if finished
+ checkExecutable();
+ }
/**
- * Sets the state of the parsed executionNode to running. This also validates if the new state
+ * Sets the state of the parsed execution to running. This also validates if the new state
* confirms to the ExectionPlan (e.g. if all nodes the parsed node depends on are already marked as
* completed).
*
- * @param executionNode
- * the exectionNode to be marked as running
+ * @param execution
+ * the execution to be marked as running
* @throws IllegalArgumentException
* if <code>null</code> is parsed as execution node
* @throws IllegalStateException
* if the parsed execution node can not be marked as running because some of its depended
* nodes are not yet marked as completed.
*/
- public void setRunning(NonLiteral executionNode) {
- if (executionNode != null) {
- String engine = getEngine(executionPlan, executionNode);
- boolean optional = isOptional(executionPlan, executionNode);
- Set<NonLiteral> dependsOn = getDependend(executionPlan, executionNode);
- log.debug("++ w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
- writeLock.lock();
- try {
- log.debug(">> w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
- if (completed.contains(executionNode)) {
- throw new IllegalStateException(
- "Unable to set state of ExectionNode '"+ executionNode
- + "'(chain '"+chain+ "' | contentItem '"
- + contentItem.getUri()+"') to running, because"
- + "it is already marked as completed. This indicates "
- + "an Bug in the implementation of the JobManager "
- + "used to execute the ExecutionPlan (chain state: "
- +"completed " + completed + " | running " + running
- + ")!");
- }
- if (!completed.containsAll(dependsOn)) {
- // TODO maybe define an own Exception for such cases
- throw new IllegalStateException(
- "Unable to set state of ExectionNode '"+ executionNode
- + "' (chain '"+chain+ "' | contentItem '"
- + contentItem.getUri()+"') to running, because "
- + "some of its depended nodes are not marked "
- + "completed yet. This indicates an Bug in the "
- + "implementation of the JobManager used to execute "
- + "the ExecutionPlan (this.dependsOn=" + dependsOn
- + "| chain.completed " + completed
- + " | chain.running " + running + ")!");
- }
- if (!running.add(executionNode)) {
- log.warn("Execution of Engine '{}' for ContentItem {} already "
- + "marked as running(chain: {}, node: {}, optional {})."
- + " -> call ignored",
- new Object[] {engine, contentItem.getUri().getUnicodeString(),
- chain, executionNode, optional});
- return;
- } else {
- log.info("Started Execution of '{}' for ContentItem {} "
- + "(chain: {}, node: {}, optional {})",
- new Object[] {engine, contentItem.getUri().getUnicodeString(), chain,
- executionNode, optional});
- // update the executables ... this will also recognise if finished
- checkExecutable();
- }
- } finally {
- log.debug("<< w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
- writeLock.unlock();
+ public void setRunning(NonLiteral execution) {
+ if(execution == null) {
+ throw new IllegalArgumentException("The parsed em:Execution instance MUST NOT be NULL!");
+ }
+ NonLiteral executionNode = getExecutionNode(execution);
+ String engine = getEngine(executionPlan, executionNode);
+ boolean optional = isOptional(executionPlan, executionNode);
+ Set<NonLiteral> dependsOn = getDependend(executionPlan, executionNode);
+ log.debug("++ w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
+ writeLock.lock();
+ try {
+ log.debug(">> w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
+ if (completed.contains(executionNode)) {
+ throw new IllegalStateException(
+ "Unable to set state of ExectionNode '"+ executionNode
+ + "'(chain '"+chain+ "' | contentItem '"
+ + contentItem.getUri()+"') to running, because"
+ + "it is already marked as completed. This indicates "
+ + "an Bug in the implementation of the JobManager "
+ + "used to execute the ExecutionPlan (chain state: "
+ +"completed " + completed + " | running " + running
+ + ")!");
}
- } else {
- throw new IllegalArgumentException("The parsed ExecutionNode MUST NOT be NULL!");
+ if (!completed.containsAll(dependsOn)) {
+ // TODO maybe define an own Exception for such cases
+ throw new IllegalStateException(
+ "Unable to set state of ExectionNode '"+ executionNode
+ + "' (chain '"+chain+ "' | contentItem '"
+ + contentItem.getUri()+"') to running, because "
+ + "some of its depended nodes are not marked "
+ + "completed yet. This indicates an Bug in the "
+ + "implementation of the JobManager used to execute "
+ + "the ExecutionPlan (this.dependsOn=" + dependsOn
+ + "| chain.completed " + completed
+ + " | chain.running " + running + ")!");
+ }
+ if (!running.add(executionNode)) {
+ log.warn("Execution of Engine '{}' for ContentItem {} already "
+ + "marked as running(chain: {}, node: {}, optional {})."
+ + " -> call ignored",
+ new Object[] {engine, contentItem.getUri().getUnicodeString(),
+ chain, executionNode, optional});
+ return;
+ } else { //added an engine to running
+ log.info("Started Execution of '{}' for ContentItem {} "
+ + "(chain: {}, node: {}, optional {})",
+ new Object[] {engine, contentItem.getUri().getUnicodeString(), chain,
+ executionNode, optional});
+ //set the status of the execution to be in progress
+ ExecutionMetadataHelper.setExecutionInProgress(executionMetadata, execution);
+ // update the executables ... this will also recognise if finished
+ updateRunningExec();
+ //update executables
+ checkExecutable();
+ }
+ } finally {
+ log.debug("<< w: {}: {}","setRunning",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
+ writeLock.unlock();
+ }
+ }
+ /**
+ * updates the {@link #runningExec} based on {@link #running}
+ */
+ private void updateRunningExec() {
+ Set<NonLiteral> runningExec = new HashSet<NonLiteral>(running.size());
+ for(NonLiteral node : running){
+ runningExec.add(getExecution(node));
+ }
+ this.runningExec = Collections.unmodifiableSet(runningExec);
+ }
+ /**
+ * updates the {@link #runningExec} based on {@link #running}
+ */
+ private void updateCompletedExec() {
+ Set<NonLiteral> completedExec = new HashSet<NonLiteral>(completed.size());
+ for(NonLiteral node : completed){
+ completedExec.add(getExecution(node));
}
+ this.completedExec = Collections.unmodifiableSet(completedExec);
}
/**
* updated the {@link #executable} and also checks for {@link #finished}<p>
* Assumed to be called within a write lock!
*/
private void checkExecutable(){
- Set<NonLiteral> executeable =
+ Set<NonLiteral> executeableNodes =
ExecutionPlanHelper.getExecutable(executionPlan, completed);
//a Chain finishes if no engine is running and no more nodes are executable
- if(!failed) {
- executeable.removeAll(running);
- if(log.isInfoEnabled()){
- Collection<String> engines = new ArrayList<String>(executeable.size());
- for(NonLiteral node : executeable){
+ if(!ExecutionMetadata.STATUS_FAILED.equals(
+ getReference(executionMetadata, chainExecutionNode, STATUS))) {
+ executeableNodes.removeAll(running);
+ if(log.isDebugEnabled()){
+ Collection<String> engines = new ArrayList<String>(executeableNodes.size());
+ for(NonLiteral node : executeableNodes){
engines.add(getEngine(executionPlan, node));
}
- log.info("MARK {} as executeable",engines);
+ log.debug("MARK {} as executeable",engines);
+ }
+ //we need to get the em:Executables for the ep:ExecutionNodes ...
+ if(executeableNodes.isEmpty()){
+ this.executable = Collections.emptySet();
+ } else if( executeableNodes.size() == 1){
+ this.executable = Collections.singleton(getExecution(executeableNodes.iterator().next()));
+ } else {
+ Set<NonLiteral> executable = new HashSet<NonLiteral>(executeableNodes.size());
+ for(NonLiteral exeutableNode : executeableNodes){
+ executable.add(getExecution(exeutableNode));
+ }
+ this.executable = Collections.unmodifiableSet(executable);
}
- this.executable = Collections.unmodifiableSet(executeable);
} else {
//do not mark engines as executeable if chain already failed
this.executable = Collections.emptySet();
}
+ if(isFinished() && !isFailed()){
+ //mark the execution process as completed
+ setExecutionCompleted(executionMetadata, chainExecutionNode, null);
+ }
}
/**
* Getter for the executable nodes.
@@ -332,34 +588,28 @@ public class EnhancementJob {
readLock.lock();
try {
log.debug(">> r: {}","isFinished");
- return this.executable.isEmpty() && running.isEmpty();
+ return executable.isEmpty() && running.isEmpty();
} finally {
log.debug("<< r: {}","isFinished");
readLock.unlock();
}
}
- public void setFailed(NonLiteral node, EnhancementEngine engine, Exception exception) {
- final boolean optional = isOptional(executionPlan, node);
- final String engineName = getEngine(executionPlan, node);
- log.debug("++ w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, node));
+ public void setFailed(NonLiteral execution, EnhancementEngine engine, Exception exception) {
+ if(execution == null) {
+ throw new IllegalArgumentException("The parsed em:Execution instance MUST NOT be NULL!");
+ }
+ NonLiteral executionNode = getExecutionNode(execution);
+ final boolean optional = isOptional(executionPlan, executionNode);
+ final String engineName = getEngine(executionPlan, executionNode);
+ log.debug("++ w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
writeLock.lock();
try {
- log.debug(">> w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, node));
- if(!optional && !failed){ //the first errors for this chain
- failed = true;
- error = exception;
- }
+ log.debug(">> w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
StringBuilder message = new StringBuilder();
- if(optional){
- message.append(String.format("Optional Engine '%s' of enhancement " +
- "Chain '%s' skiped for ContentItem %s because the Engine",
- engineName,chain,contentItem.getUri()));
- } else {
- message.append(String.format("Failed to enhance ContentItem '%s' by using " +
- "enhancement chain '%s' because the required Enhancement Engine %s ",
- contentItem.getUri(),chain, engineName));
- }
+ message.append(String.format("Unable to process ContentItem '%s' with " +
+ "Enhancement Engine %s because the engine ",
+ contentItem.getUri(), engineName));
if(engine == null){
message.append("is currently not active");
} else {
@@ -367,17 +617,24 @@ public class EnhancementJob {
"(Engine class: %s)",engine.getClass().getName()));
}
if(exception != null){
- message.append("(reason:").append(exception.getMessage()).append(')');
+ message.append("(Reason: ").append(exception.getMessage()).append(')');
}
message.append('!');
- if(optional){
- log.info(message.toString(),exception);
- } else {
- errormessages.add(message.toString());
+ setNodeCompleted(executionNode); //update the internal state
+ //set this execution to failed
+ setExecutionFaild(executionMetadata, execution, message.toString());
+ //if not optional and the chain is not yet failed
+ if(!optional && !isExecutionFailed(executionMetadata, chainExecutionNode)){
+ //set also the whole chain to faild!
+ String chainMessage = String.format(
+ "Enhancement Chain failed because of required Engine '%s' failed" +
+ "with Message: %s", engineName, message);
+ setExecutionFaild(executionMetadata, execution, chainMessage);
+ error = exception; //this member stores the exception to allow
+ //re-throwing by the EnhancementJobManager.
}
- setCompleted(node); //we are done with that node!
} finally {
- log.debug("<< w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, node));
+ log.debug("<< w: {}: {}","setFailed",ExecutionPlanHelper.getEngine(executionPlan, executionNode));
writeLock.unlock();
}
@@ -392,7 +649,7 @@ public class EnhancementJob {
readLock.lock();
try {
log.debug(">> r: {}","isFailed");
- return failed;
+ return isExecutionFailed(executionMetadata, chainExecutionNode);
} finally {
log.debug("<< r: {}","isFailed");
readLock.unlock();
@@ -412,14 +669,7 @@ public class EnhancementJob {
public String toString() {
return "EnhancementJob for ContentItem "+contentItem.getUri();
}
- /**
- * If {@link #isFailed()} this can be used to retrieve the message of the
- * occurred error.
- * @return the message of the error that caused the enhancement job to fail.
- */
- public String getErrorMessage(){
- return errormessages == null || errormessages.isEmpty() ? null : errormessages.get(0);
- }
+
/**
* if {@link #isFailed()} this may contain the {@link Exception} that caused
* the enhancement job to fail.
@@ -428,4 +678,34 @@ public class EnhancementJob {
public Exception getError(){
return error;
}
+ public String getErrorMessage() {
+ readLock.lock();
+ try {
+ return getString(executionMetadata, executionPlanNode, ExecutionMetadata.STATUS_MESSAGE);
+ } finally {
+ readLock.unlock();
+ }
+ }
+ /**
+ * Getter for the ExecutionMetadata.
+ * @return the execution metadata.
+ */
+ public MGraph getExecutionMetadata() {
+ return executionMetadata;
+ }
+ /**
+ * Marks the execution of the enhancement process as started. In other
+ * words this sets the status of the 'em:ChainExecution' instance that
+ * 'em:enhances' the {@link ContentItem} to
+ * {@link ExecutionMetadata#STATUS_IN_PROGRESS}
+ */
+ public void startProcessing() {
+ writeLock.lock();
+ try {
+ setExecutionInProgress(executionMetadata, chainExecutionNode);
+ } finally {
+ writeLock.unlock();
+ }
+
+ }
}
Modified: incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJobHandler.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJobHandler.java?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJobHandler.java (original)
+++ incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EnhancementJobHandler.java Wed Feb 1 11:59:37 2012
@@ -1,7 +1,7 @@
package org.apache.stanbol.enhancer.jobmanager.event.impl;
import static org.apache.stanbol.enhancer.jobmanager.event.Constants.PROPERTY_JOB_MANAGER;
-import static org.apache.stanbol.enhancer.jobmanager.event.Constants.PROPERTY_NODE;
+import static org.apache.stanbol.enhancer.jobmanager.event.Constants.PROPERTY_EXECUTION;
import static org.apache.stanbol.enhancer.jobmanager.event.Constants.TOPIC_JOB_MANAGER;
import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.getEngine;
@@ -126,6 +126,7 @@ public class EnhancementJobHandler imple
processingLock.writeLock().unlock();
}
if(init){
+ enhancementJob.startProcessing();
executeNextNodes(enhancementJob);
}
return o;
@@ -134,8 +135,51 @@ public class EnhancementJobHandler imple
@Override
public void handleEvent(Event event) {
EnhancementJob job = (EnhancementJob)event.getProperty(PROPERTY_JOB_MANAGER);
- NonLiteral node = (NonLiteral)event.getProperty(PROPERTY_NODE);
- String engineName = getEngine(job.getExecutionPlan(), node);
+ NonLiteral execution = (NonLiteral)event.getProperty(PROPERTY_EXECUTION);
+ if(job == null || execution == null){
+ log.warn("Unable to process EnhancementEvent where EnhancementJob " +
+ "{} or Execution node {} is null -> ignore",job,execution);
+ }
+ try {
+ processEvent(job, execution);
+ } catch (Throwable t) {
+ //this ensures that an runtime exception does not
+ job.setFailed(execution, null, new IllegalStateException(
+ "Unexpected Exception while processing ContentItem '"
+ + job.getContentItem().getUri()+"' with EnhancementJobManager: "
+ + EventJobManagerImpl.class,t));
+ }
+ //(2) trigger the next actions
+ log.debug("++ w: {}","check for next Executions");
+ job.getLock().writeLock().lock();
+ log.debug(">> w: {}","check for next Executions");
+ try {
+ if(job.isFinished()){
+ finish(job);
+ } else if(!job.isFailed()){
+ executeNextNodes(job);
+ } else {
+ if(log.isInfoEnabled()){
+ Collection<String> running = new ArrayList<String>(3);
+ for(NonLiteral runningNode : job.getRunning()){
+ running.add(getEngine(job.getExecutionPlan(), runningNode));
+ }
+ log.debug("Job {} failed, but {} still running!",
+ job.getContentItem().getUri(),running);
+ }
+ }
+ } finally {
+ log.debug("<< w: {}","check for next Executions");
+ job.getLock().writeLock().unlock();
+ }
+ }
+ /**
+ * @param job
+ * @param execution
+ */
+ private void processEvent(EnhancementJob job, NonLiteral execution) {
+ NonLiteral executionNode = job.getExecutionNode(execution);
+ String engineName = getEngine(job.getExecutionPlan(), executionNode);
//(1) execute the parsed ExecutionNode
EnhancementEngine engine = engineManager.getEngine(engineName);
if(engine != null){
@@ -158,9 +202,9 @@ public class EnhancementJobHandler imple
log.debug(">> w: {}: {}","start sync execution", engine.getName());
try {
engine.computeEnhancements(job.getContentItem());
- job.setCompleted(node);
+ job.setCompleted(execution);
} catch (EngineException e){
- job.setFailed(node, engine, e);
+ job.setFailed(execution, engine, e);
} finally{
log.debug("<< w: {}: {}","finished sync execution", engine.getName());
job.getLock().writeLock().unlock();
@@ -170,38 +214,15 @@ public class EnhancementJobHandler imple
log.debug("++ n: start async execution of Engine {}",engine.getName());
engine.computeEnhancements(job.getContentItem());
log.debug("++ n: finished async execution of Engine {}",engine.getName());
- job.setCompleted(node);
+ job.setCompleted(execution);
} catch (EngineException e) {
- job.setFailed(node, engine, e);
+ job.setFailed(execution, engine, e);
}
} else { //required engine is unable to enhance the content
- job.setFailed(node,engine,exception);
+ job.setFailed(execution,engine,exception);
}
} else { //engine with that name is not available
- job.setFailed(node, null, null);
- }
- //(2) trigger the next actions
- log.debug("++ w: {}: {}","check next after", engineName);
- job.getLock().writeLock().lock();
- log.debug(">> w: {}: {}","check next after", engineName);
- try {
- if(job.isFinished()){
- finish(job);
- } else if(!job.isFailed()){
- executeNextNodes(job);
- } else {
- if(log.isInfoEnabled()){
- Collection<String> running = new ArrayList<String>(3);
- for(NonLiteral runningNode : job.getRunning()){
- running.add(getEngine(job.getExecutionPlan(), runningNode));
- }
- log.debug("Job {} failed, but {} still running!",
- job.getContentItem().getUri(),running);
- }
- }
- } finally {
- log.debug("<< w: {}: {}","check next after", engineName);
- job.getLock().writeLock().unlock();
+ job.setFailed(execution, null, null);
}
}
/**
@@ -240,7 +261,7 @@ public class EnhancementJobHandler imple
for(NonLiteral executable : job.getExecutable()){
Dictionary<String,Object> properties = new Hashtable<String,Object>();
properties.put(PROPERTY_JOB_MANAGER, job);
- properties.put(PROPERTY_NODE, executable);
+ properties.put(PROPERTY_EXECUTION, executable);
job.setRunning(executable);
if(log.isDebugEnabled()){
log.debug("SHEDULE execution of Engine {}",ExecutionPlanHelper.getEngine(job.getExecutionPlan(), executable));
Modified: incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EventJobManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EventJobManagerImpl.java?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EventJobManagerImpl.java (original)
+++ incubator/stanbol/trunk/enhancer/jobmanager/event/src/main/java/org/apache/stanbol/enhancer/jobmanager/event/impl/EventJobManagerImpl.java Wed Feb 1 11:59:37 2012
@@ -61,6 +61,7 @@ public class EventJobManagerImpl impleme
private ServiceRegistration jobHandlerRegistration;
private EnhancementJobHandler jobHandler;
+
/**
* Instantiates and registers the {@link EnhancementJobHandler} as
* {@link EventHandler} for the topic
@@ -114,7 +115,8 @@ public class EventJobManagerImpl impleme
"' because NULL was parsed as enhancement chain");
}
long start = System.currentTimeMillis();
- EnhancementJob job = new EnhancementJob(ci, chain.getName(), chain.getExecutionPlan());
+ boolean isDefaultChain = chain.equals(chainManager.getDefault());
+ EnhancementJob job = new EnhancementJob(ci, chain.getName(), chain.getExecutionPlan(),isDefaultChain);
//start the execution
//wait for the results
Object object = jobHandler.register(job);
@@ -132,6 +134,11 @@ public class EventJobManagerImpl impleme
new Object[]{ job.isFailed() ? "Failed" : "Finished",
job.getContentItem().getUri(),
System.currentTimeMillis()-start});
+ //NOTE: ExecutionMetadata are not added to the metadata of the ContentItem
+ // by the EnhancementJobManager.
+ // However one could add this as an optional feature to the
+ // RESTful interface of the Enhancer!
+ //ci.getMetadata().addAll(job.getExecutionMetadata());
if(job.isFailed()){
throw new ChainException(job.getErrorMessage(), job.getError());
}
Modified: incubator/stanbol/trunk/integration-tests/pom.xml
URL: http://svn.apache.org/viewvc/incubator/stanbol/trunk/integration-tests/pom.xml?rev=1239097&r1=1239096&r2=1239097&view=diff
==============================================================================
--- incubator/stanbol/trunk/integration-tests/pom.xml (original)
+++ incubator/stanbol/trunk/integration-tests/pom.xml Wed Feb 1 11:59:37 2012
@@ -156,11 +156,12 @@
<keepJarRunning>${keepJarRunning}</keepJarRunning>
<server.ready.timeout.seconds>180</server.ready.timeout.seconds>
<server.ready.path.1>/:stanbol.css</server.ready.path.1>
- <server.ready.path.2>/engines:There are currently</server.ready.path.2>
+ <server.ready.path.2>/enhancer:Stateless REST analysis</server.ready.path.2>
<server.ready.path.3>/factstore:What is the FactStore</server.ready.path.3>
<server.ready.path.4>/contenthub:Recently uploaded Content Items</server.ready.path.4>
- <server.ready.path.5>/ontonet:Apache Stanbol OntoNet</server.ready.path.5>
- <!-- server.ready.path.6>/reasoners:Apache Stanbol Reasoners</server.ready.path.6 -->
+ <server.ready.path.5>/entityhub:The RESTful API of the Entityhub</server.ready.path.5>
+ <server.ready.path.6>/ontonet:Apache Stanbol OntoNet</server.ready.path.6>
+ <!-- server.ready.path.7>/reasoners:Apache Stanbol Reasoners</server.ready.path.7 -->
</systemPropertyVariables>
<excludes>
<!-- TODO: remove before commit -->