You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by de...@apache.org on 2014/11/26 20:48:32 UTC

svn commit: r1641905 - in /uima/sandbox/uima-ducc/trunk/uima-ducc-user/src: main/java/org/apache/uima/ducc/user/dd/ test/java/org/apache/uima/ducc/user/jd/test/

Author: degenaro
Date: Wed Nov 26 19:48:31 2014
New Revision: 1641905

URL: http://svn.apache.org/r1641905
Log:
UIMA-4068 Redesign of JD toward the main goal of classpath separation for container (user) code.

User-side DeploymentDescriptorGenerator and JUnit.

Added:
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DeploymentDescriptorGenerator.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregate.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregateComponent.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaDeploymentDescriptor.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregate.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregateComponent.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeployableConfiguration.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeploymentDescriptor.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IIdentity.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/InvalidOverrideParameterException.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/UimaUtils.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/Utils.java   (with props)
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/XStreamUtils.java   (with props)
Modified:
    uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/test/java/org/apache/uima/ducc/user/jd/test/TestSuite.java

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DeploymentDescriptorGenerator.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DeploymentDescriptorGenerator.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DeploymentDescriptorGenerator.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DeploymentDescriptorGenerator.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,214 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.uima.resourceSpecifier.factory.UimaASPrimitiveDeploymentDescriptor;
+import org.apache.uima.util.XMLInputSource;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+/**
+ * Generates UIMA AS deployment descriptor. Takes in as input implementations of 
+ * IDuccUimaDeployableConfiguration interface creates a DD. Currently two implementations
+ * of IDuccUimaDeployableConfiguration are supported:
+ * 
+ * 1) IDuccUimaDeploymentDescriptor - this contains a reference to an existing DD that a 
+ *    user provided when submitting a job. In this case, the code overrides a queue name
+ *    and a broker url and new descriptors are generated. 
+ * 
+ * 2) IDuccUimaAggregate - this contains a list of delegate components that must first
+ *    be assembled into UIMA Aggregate descriptor. After generating that descriptor the
+ *    code generates DD for it.
+ */
+public class DeploymentDescriptorGenerator {
+
+	private String userLogDir;  // where to write both descriptors
+	
+	public DeploymentDescriptorGenerator(String userLogDir) {
+		//	Type of ducc component this is using this class (ex.JD)
+		this.userLogDir = userLogDir;
+	}
+	public String generate(String serializedDeployableConfiguration, String jobId) throws Exception {
+		IDuccUimaDeployableConfiguration deployableConfiguration =
+				(IDuccUimaDeployableConfiguration)XStreamUtils.unmarshall(serializedDeployableConfiguration);
+		return generate(deployableConfiguration, jobId);
+	}
+
+	/**
+	 * Generates deployment descriptor for DUCC JPs.
+	 * 
+	 * @param configuration - deployment configuration for the deployment descriptor
+	 * @return - absolute path to the generated deployment descriptor
+	 * @throws Exception - failure
+	 */
+	public String generate(IDuccUimaDeployableConfiguration configuration, String jobId)
+			throws Exception {
+		if ( configuration instanceof IDuccUimaDeploymentDescriptor) {
+			// "DUCC Service Wrapper Generates Deployment Descriptor Based on DD Provided by a User"
+			// User provided descriptor is used as a basis for generating the actual DD with overriden 
+			// Broker URL and queue name. 
+			return generateDeploymentDescriptor((IDuccUimaDeploymentDescriptor)configuration, jobId);
+		} else if ( configuration instanceof IDuccUimaAggregate) {
+			// "DUCC Service Wrapper Generating UIMA AS Deployment Descriptor"
+			// First create UIMA aggregate descriptor and then a deployment descriptor.
+			return generateDeploymentDescriptor((IDuccUimaAggregate)configuration, jobId);
+		} else throw new Exception("Invalid IDuccUimaDeployableConfiguration. Expected IDuccUimaAggregate or IDuccUimaDeploymentDescriptor, but received "+configuration.getClass().getName());
+	}
+	/**
+	 * Writes a given content into a file in a given directory 
+	 * 
+	 * @param content - content in the file
+	 * @return - absolute path to the file created
+	 * 
+	 * @throws Exception
+	 */
+	private String writeDDFile(String content, String jobId) throws Exception {
+		File dir = new File(userLogDir);
+		if ( !dir.exists()) {
+			dir.mkdir();
+		}
+		//	compose the file name from a basename (from ducc.properties), constant (-uima-as.dd-) and PID
+		BufferedWriter out = null;
+		try {
+			//	using PID of the ducc component process in the DD file name
+			File file = new File(dir, jobId+"-uima-as-dd-"+Utils.getPID()+".xml");
+			out = new BufferedWriter(new FileWriter(file));
+			out.write(content);
+			out.flush();
+			return file.getAbsolutePath();
+		} catch( Exception e) {
+			throw e;
+		} finally {
+			if ( out != null ) {
+				out.close();
+			}
+		}
+	}
+	/**
+	 * Modifies user provided deployment descriptor by changing queue name and broker URL and
+	 * writes it to a new deployment descriptor file.
+	 *  
+	 * @param dd - user specified deployment descriptor
+	 * @return - absolute path to the generated deployment descriptor
+	 * @throws Exception
+	 */
+	public String generateDeploymentDescriptor(IDuccUimaDeploymentDescriptor dd, String jobId) throws Exception {
+	  //  parse DD into DOM 
+	  Document doc = parse(dd.getDeploymentDescriptorPath());
+	  //  locate the <inputQueue node within the xml
+    NodeList nodes = doc.getElementsByTagName("inputQueue");
+    //  should only be one such node
+    if ( nodes.getLength() > 0 ) {
+       Element element = (Element) nodes.item(0);
+       // replace queue name
+       element.setAttribute("endpoint", "ducc.jd.queue."+jobId);
+       // replace broker URL
+       element.setAttribute("brokerURL", System.getProperty("ducc.broker.url"));
+    } else {
+      throw new Exception("Invalid DD-"+dd.getDeploymentDescriptorPath()+". Missing required element <inputQueue ...");
+    }
+    //
+		//	write the adjusted deployment descriptor to the user log dir where dd2spring will
+		//  pick it up from
+    //
+		return writeDDFile(xml2String(doc), jobId);
+	}
+	/**
+	 * Parses xml into DOM
+	 * 
+	 * @param location - name of the xml file to parse
+	 * @return DOM
+	 * @throws Exception
+	 */
+	private Document parse(String location ) throws Exception {
+    //  Resolve the descriptor either by name or by location
+    XMLInputSource xmlin = 
+            UimaUtils.getXMLInputSource(location); // this guy does all the magic
+    //  Parse the descriptor into DOM
+    DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+    return db.parse(xmlin.getInputStream());
+	}
+	/**
+	 * Serializes Deployment Descriptor from DOM to a String
+	 * @param xmlDoc - xml to serialize
+	 * @return - serialized DD
+	 * @throws Exception
+	 */
+	private String xml2String(Document xmlDoc) throws Exception {
+    StringWriter writer = null;
+    
+    DOMSource domSource = new DOMSource(xmlDoc.getDocumentElement());
+    writer = new StringWriter();
+    
+    StreamResult streamResult = new StreamResult(writer);
+    TransformerFactory factory = TransformerFactory.newInstance();
+    Transformer transformer = factory.newTransformer();
+    transformer.transform(domSource, streamResult);
+    
+    StringBuffer serializedDD = writer.getBuffer();
+    return serializedDD.toString();
+  }
+	/**
+	 * Creates and returns absolute path to the UIMA AS deployment descriptor.
+	 * 
+	 * @param aggregateConfiguration - configuration object containing UIMA aggregate delegate
+	 *        configuration and overrides. 
+	 * 
+	 * @return - absolute path to the generated deployment descriptor
+	 * @throws Exception
+	 */
+	private String generateDeploymentDescriptor(IDuccUimaAggregate aggregateConfiguration, String jobId ) throws Exception {
+		
+		List<String> descriptorPaths = new ArrayList<String>();
+		List<List<String>> overrides = new ArrayList<List<String>>();
+		for( IDuccUimaAggregateComponent component: aggregateConfiguration.getComponents()) {
+			descriptorPaths.add(component.getDescriptor());
+			overrides.add(component.getOverrides());
+		}
+		UimaASPrimitiveDeploymentDescriptor dd = 
+				UimaUtils.createUimaASDeploymentDescriptor(
+				    aggregateConfiguration.getName(), 
+				    aggregateConfiguration.getDescription(), 
+				    aggregateConfiguration.getBrokerURL(), 
+				    aggregateConfiguration.getEndpoint(),	
+				    aggregateConfiguration.getThreadCount(), 
+				    userLogDir,
+				    jobId+"-uima-ae-descriptor-"+Utils.getPID()+".xml",
+					overrides, 
+					descriptorPaths.toArray(new String[descriptorPaths.size()])
+					);
+		return writeDDFile(dd.toXML(), jobId);
+	}
+
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DeploymentDescriptorGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregate.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregate.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregate.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregate.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,115 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DuccUimaAggregate implements IDuccUimaAggregate {
+
+	/**
+	 * please increment this sUID when removing or modifying a field 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	private List<IDuccUimaAggregateComponent> components = new ArrayList<IDuccUimaAggregateComponent>();
+	
+	private String name;
+	private String description;
+	private int threadCount = 1;
+	private String brokerURL;
+	private String endpoint;
+	
+	public DuccUimaAggregate(String name, String description, int threadCount, String brokerURL, String endpoint) {
+		setName(name);
+		setDescription(description);
+		setThreadCount(threadCount);
+		setBrokerURL(brokerURL);
+		setEndpoint(endpoint);
+	}
+	
+	public DuccUimaAggregate(String name, String description, int threadCount, String brokerURL, String endpoint,List<IDuccUimaAggregateComponent> components) {
+		setName(name);
+		setDescription(description);
+		setThreadCount(threadCount);
+		setBrokerURL(brokerURL);
+		setEndpoint(endpoint);
+		setComponents(components);
+	}
+	
+	
+	public List<IDuccUimaAggregateComponent> getComponents() {
+		return components;
+	}
+	
+	
+	public void setComponents(List<IDuccUimaAggregateComponent> components) {
+		this.components = components;
+	}
+	
+	
+	public String getName() {
+		return name;
+	}
+
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	
+	public String getDescription() {
+		return description;
+	}
+
+	
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	
+	public int getThreadCount() {
+		return threadCount;
+	}
+
+	
+	public void setThreadCount(int threadCount) {
+		this.threadCount = threadCount;
+	}
+
+	
+	public String getBrokerURL() {
+		return brokerURL;
+	}
+
+	
+	public void setBrokerURL(String brokerURL) {
+		this.brokerURL = brokerURL;
+	}
+
+	
+	public String getEndpoint() {
+		return endpoint;
+	}
+
+	
+	public void setEndpoint(String endpoint) {
+		this.endpoint = endpoint;
+	}
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregateComponent.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregateComponent.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregateComponent.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregateComponent.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,57 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+import java.util.List;
+
+public class DuccUimaAggregateComponent implements IDuccUimaAggregateComponent {
+
+	/**
+	 * please increment this sUID when removing or modifying a field 
+	 */
+	private static final long serialVersionUID = 1L;
+	private String descriptor;
+	private List<String> overrides;
+	
+	public DuccUimaAggregateComponent(String descriptor, List<String> overrides) {
+		setDescriptor(descriptor);
+		setOverrides(overrides);
+	}
+	
+	
+	public String getDescriptor() {
+		return this.descriptor;
+	}
+
+	
+	public void setDescriptor(String descriptor) {
+		this.descriptor = descriptor;
+	}
+
+	
+	public List<String> getOverrides() {
+		return this.overrides;
+	}
+
+	
+	public void setOverrides(List<String> overrides) {
+		this.overrides = overrides;
+	}
+
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaAggregateComponent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaDeploymentDescriptor.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaDeploymentDescriptor.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaDeploymentDescriptor.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaDeploymentDescriptor.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,36 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+public class DuccUimaDeploymentDescriptor implements IDuccUimaDeploymentDescriptor  {
+	
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 873886659538891891L;
+	private String deploymentDescriptorPath=null;
+	
+	public DuccUimaDeploymentDescriptor(String deploymentDescriptorPath) {
+		this.deploymentDescriptorPath = deploymentDescriptorPath;
+	}
+	public String getDeploymentDescriptorPath() {
+		return deploymentDescriptorPath;
+	}
+
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/DuccUimaDeploymentDescriptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregate.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregate.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregate.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregate.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,42 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+import java.util.List;
+
+public interface IDuccUimaAggregate extends IDuccUimaDeployableConfiguration {
+
+	public List<IDuccUimaAggregateComponent> getComponents();
+	public void setComponents(List<IDuccUimaAggregateComponent> components);
+	
+	public String getName();
+	public void setName(String name);
+	
+	public String getDescription();
+	public void setDescription(String description);
+	
+	public int getThreadCount();
+	public void setThreadCount(int threadCount);
+	
+	public String getBrokerURL();
+	public void setBrokerURL(String brokerURL);
+	
+	public String getEndpoint();
+	public void setEndpoint(String endpoint);
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregateComponent.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregateComponent.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregateComponent.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregateComponent.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,31 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface IDuccUimaAggregateComponent extends Serializable {
+
+	public String getDescriptor();
+	public void setDescriptor(String descriptor);
+	
+	public List<String> getOverrides();
+	public void setOverrides(List<String> overrides);
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaAggregateComponent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeployableConfiguration.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeployableConfiguration.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeployableConfiguration.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeployableConfiguration.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,24 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+import java.io.Serializable;
+
+public interface IDuccUimaDeployableConfiguration extends Serializable {
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeployableConfiguration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeploymentDescriptor.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeploymentDescriptor.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeploymentDescriptor.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeploymentDescriptor.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,23 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+public interface IDuccUimaDeploymentDescriptor extends IDuccUimaDeployableConfiguration {
+	public String getDeploymentDescriptorPath();
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IDuccUimaDeploymentDescriptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IIdentity.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IIdentity.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IIdentity.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IIdentity.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,26 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+import java.io.Serializable;
+
+public interface IIdentity extends Serializable {
+	public String getName();
+	public String getIP();
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/IIdentity.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/InvalidOverrideParameterException.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/InvalidOverrideParameterException.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/InvalidOverrideParameterException.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/InvalidOverrideParameterException.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,31 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+public class InvalidOverrideParameterException extends Exception {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -4948849140814646049L;
+
+	public InvalidOverrideParameterException(String msg) {
+		super(msg);
+	}
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/InvalidOverrideParameterException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/UimaUtils.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/UimaUtils.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/UimaUtils.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/UimaUtils.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,548 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.uima.Constants;
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.UIMARuntimeException;
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_impl;
+import org.apache.uima.analysis_engine.metadata.FixedFlow;
+import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration;
+import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl;
+import org.apache.uima.analysis_engine.metadata.impl.FlowControllerDeclaration_impl;
+import org.apache.uima.resource.RelativePathResolver;
+import org.apache.uima.resource.ResourceConfigurationException;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.impl.RelativePathResolver_impl;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations;
+import org.apache.uima.resource.metadata.ConfigurationParameterSettings;
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl;
+import org.apache.uima.resource.metadata.impl.Import_impl;
+import org.apache.uima.resourceSpecifier.factory.DeploymentDescriptorFactory;
+import org.apache.uima.resourceSpecifier.factory.ServiceContext;
+import org.apache.uima.resourceSpecifier.factory.UimaASPrimitiveDeploymentDescriptor;
+import org.apache.uima.resourceSpecifier.factory.impl.ServiceContextImpl;
+import org.apache.uima.util.InvalidXMLException;
+import org.apache.uima.util.XMLInputSource;
+
+
+public class UimaUtils {
+	public static final String FlowControllerKey="FixedFlowController";
+	public static final String FlowControllerResourceSpecifier="ducc.flow-controller.specifier";
+	public static RelativePathResolver resolver = new RelativePathResolver_impl();
+
+
+	/**
+	 * Creates and returns UIMA AS deployment descriptor from provided parts. It
+	 * first creates UIMA AE aggregate descriptor and then creates UIMA AS
+	 * primitive deployment descriptor for it.
+	 * 
+	 * @param name
+	 *            - name of the UIMA AS service
+	 * @param description
+	 *            - description of the UIMA AS service
+	 * @param brokerURL
+	 *            - broker the UIMA AS service will connect to
+	 * @param endpoint
+	 *            - queue name of the UIMA AS service
+	 * @param scaleup
+	 *            - how many pipelines (threads) UIMA AS will deploy in the jvm
+	 * 
+	 * @param aeDescriptors
+	 *            - vararg of AE descriptor paths
+	 * 
+	 * @return instance of UimaASPrimitiveDeploymentDescriptor
+	 * 
+	 * @throws Exception
+	 */
+	public static UimaASPrimitiveDeploymentDescriptor createUimaASDeploymentDescriptor(
+			String name, String description, String brokerURL, String endpoint,
+			int scaleup, String directory, String fname, String... aeDescriptors)
+			throws Exception {
+		List<List<String>> overrides = new ArrayList<List<String>>();
+		return createUimaASDeploymentDescriptor(name, description, brokerURL,
+				endpoint, scaleup, directory, fname, overrides, aeDescriptors);
+	}
+
+	/**
+	 * Creates and returns UIMA AS deployment descriptor from provided parts. It
+	 * first creates UIMA AE aggregate descriptor and then creates UIMA AS
+	 * primitive deployment descriptor for it.
+	 * 
+	 * @param name
+	 *            - name of the UIMA AS service
+	 * @param description
+	 *            - description of the UIMA AS service
+	 * @param brokerURL
+	 *            - broker the UIMA AS service will connect to
+	 * @param endpoint
+	 *            - queue name of the UIMA AS service
+	 * @param scaleup
+	 *            - how many pipelines (threads) UIMA AS will deploy in the jvm
+	 * @param overrides
+	 *            - a list containing overrides. Each component override is a
+	 *            separate list containing strings with format <name>=<value>
+	 * 
+	 * @param aeDescriptors
+	 *            - vararg of AE descriptor paths
+	 * 
+	 * @return instance of UimaASPrimitiveDeploymentDescriptor
+	 * 
+	 * @throws Exception
+	 */
+	public static UimaASPrimitiveDeploymentDescriptor createUimaASDeploymentDescriptor(
+			String name, String description, String brokerURL, String endpoint,
+			int scaleup, String directory, String fname, List<List<String>> overrides,
+			String... aeDescriptors) throws Exception {
+		// First create UIMA AE aggregate descriptor from provided aeDescriptor
+		// paths
+		AnalysisEngineDescription aed = createAggregateDescription((scaleup > 1),overrides,
+				aeDescriptors);
+		aed.getMetaData().setName(name);
+		// Create a temporary file where AE descriptor will be saved
+		//File tempAEDescriptorFile = null;
+		File file = null;
+		File dir = new File(directory);
+		if (!dir.exists()) {
+			dir.mkdir();
+		}
+		FileOutputStream fos = null;
+		try {
+			file = new File(dir, fname);//+"-uima-ae-descriptor-"+Utils.getPID()+".xml");
+			fos = new FileOutputStream(file);
+			aed.toXML(fos);
+			
+		} catch(Exception e) {
+			throw e;
+		} finally {
+			if ( fos != null ) {
+				fos.close();
+			}
+		}
+		// Set up a context object containing service deployment information
+		ServiceContext context = new ServiceContextImpl(name, description,
+				file.getAbsolutePath().replace('\\', '/'),
+				endpoint, brokerURL);
+		// how many pipelines to deploy in the jvm
+		context.setScaleup(scaleup);
+		context.setProcessErrorThresholdCount(1);
+		// Create UIMA AS deployment descriptor
+		UimaASPrimitiveDeploymentDescriptor dd = DeploymentDescriptorFactory
+				.createPrimitiveDeploymentDescriptor(context);
+		return dd;
+	}
+
+	/**
+	 * Creates UIMA aggregate AE description from provided parts. Takes as input
+	 * vararg of AE descriptor paths for CM, AE, and CC. It creates an aggregate
+	 * description with each component identified by its implementation class.
+	 * The generated aggregate uses fixed flow.
+	 * 
+	 * @param descriptorPaths
+	 *            - paths to uima component descriptors
+	 * 
+	 * @return - instantiated aggregate {@link AnalysisEngineDescription}
+	 * 
+	 * @throws Exception
+	 */
+	public static AnalysisEngineDescription createAggregateDescription(boolean multipleDeploymentsAllowed,
+			String... descriptorPaths) throws Exception {
+		List<List<String>> overrides = new ArrayList<List<String>>();
+		return createAggregateDescription(multipleDeploymentsAllowed, overrides, descriptorPaths);
+	}
+
+//	public static URL resolveRelativePath(URL aRelativeUrl) {
+//		// fallback on classloader
+//		String f = aRelativeUrl.getFile();
+//		URL absURL;
+//		if (aRelativeUrl.getClass().getClassLoader() != null) {
+//			absURL = aRelativeUrl.getClass().getClassLoader().getResource(f);
+//		} else // if no ClassLoader specified (could be the bootstrap
+//				// classloader), try the system
+//		// classloader
+//		{
+//			absURL = ClassLoader.getSystemClassLoader().getResource(f);
+//		}
+//		if (absURL != null) {
+//			return absURL;
+//		}
+//
+//		// no file could be found
+//		return null;
+//	}
+
+	public static URL getRelativePathWithProtocol(String aRelativePath)
+			throws MalformedURLException {
+		URL relativeUrl;
+		try {
+			relativeUrl = new URL(aRelativePath);
+		} catch (MalformedURLException e) {
+			relativeUrl = new URL("file", "", aRelativePath);
+		}
+		return relativeUrl;
+		//		return resolveRelativePath(relativeUrl);
+	}
+
+	public static ResourceSpecifier getResourceSpecifier(String resourceFile) throws Exception {
+		return UIMAFramework.getXMLParser().parseResourceSpecifier(getXMLInputSource(resourceFile));
+    }
+
+	public static XMLInputSource getXMLInputSource(String resourceFile)
+        throws InvalidXMLException
+    {
+        //
+        // If the resourceFile ends in .xml then we look in the filesystem, end of story.
+        //
+        // If not, then we turn it into a path by replacing . with / and appending .xml.
+        // We then have two places we need to look: 
+        // a) in the user's classpath directly as a file (not inside a jar), or
+        // b) in the jar files in the user's classpath
+        // 
+
+        try {
+            resourceFile = Utils.resolvePlaceholderIfExists(resourceFile,
+                                                            System.getProperties());
+            XMLInputSource in = null;
+            if (resourceFile.endsWith(".xml")) {
+                in = new XMLInputSource(resourceFile);
+            } else {
+                resourceFile = resourceFile.replace('.', '/') + ".xml";
+                URL relativeURL = resolver
+					.resolveRelativePath(getRelativePathWithProtocol(resourceFile));
+                in = new XMLInputSource(relativeURL);
+            }
+            return in;
+        } catch (NullPointerException npe) {
+            throw new InvalidXMLException(InvalidXMLException.IMPORT_BY_NAME_TARGET_NOT_FOUND, new String[] {resourceFile});
+        } catch (IOException e ) {
+            throw new InvalidXMLException(InvalidXMLException.IMPORT_FAILED_COULD_NOT_READ_FROM_URL, new String[] {resourceFile});
+        }
+
+	}
+
+	/**
+	 * Creates UIMA aggregate AE description from provided parts. Takes as input
+	 * vararg of AE descriptor paths for CM, AE, and CC. It creates an aggregate
+	 * description with each component identified by its implementation class.
+	 * The generated aggregate uses fixed flow.
+	 * 
+	 * @param overrides
+	 *            - a list containing overrides. Each component override is a
+	 *            separate list containing strings with format <name>=<value>
+	 * 
+	 * @param descriptorPaths
+	 *            - paths to uima component descriptors
+	 * 
+	 * @return - instantiated aggregate {@link AnalysisEngineDescription}
+	 * 
+	 * @throws Exception
+	 */
+	public static AnalysisEngineDescription createAggregateDescription(
+			boolean multipleDeploymentAllowed, List<List<String>> overrides, String... descriptorPaths)
+			throws Exception {
+
+		// create the descriptor and set configuration parameters
+		AnalysisEngineDescription desc = new AnalysisEngineDescription_impl();
+		resolver.setPathResolverClassLoader(desc.getClass().getClassLoader());
+		desc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME);
+		desc.setPrimitive(false);
+		ResourceSpecifier[] specifiers = new ResourceSpecifier[descriptorPaths.length];
+
+		// Allow scale up
+		desc.getAnalysisEngineMetaData().getOperationalProperties()
+				.setMultipleDeploymentAllowed(multipleDeploymentAllowed);
+		// Stores component names derived from implementation class
+		List<String> flowNames = new ArrayList<String>();
+		int inx = 0;
+		// First produce ResourceSpecifiers from provided descriptors
+		for (String aeDescription : descriptorPaths) {
+			/*
+			aeDescription = Utils.resolvePlaceholderIfExists(aeDescription,
+					System.getProperties());
+			XMLInputSource in = null;
+			if (!aeDescription.endsWith(".xml")) {
+				aeDescription = aeDescription.replace('.', '/') + ".xml";
+				URL relativeURL = resolver.resolveRelativePath(getRelativePathWithProtocol(aeDescription));
+//				URL relativeURL = resolveRelativePath(aeDescription);
+				in = new XMLInputSource(relativeURL);
+			} else {
+				in = new XMLInputSource(aeDescription);
+			}
+			// XMLInputSource in = new XMLInputSource(aeDescription);
+			ResourceSpecifier specifier = UIMAFramework.getXMLParser()
+					.parseResourceSpecifier(in);
+			specifiers[inx++] = specifier;
+			*/
+			specifiers[inx++] = getResourceSpecifier(aeDescription);
+			// UimaClassFactory.produceResourceSpecifier(aeDescription);
+		}
+
+		for (String aeDescription : descriptorPaths) {
+			Import descriptorImport = new Import_impl();
+			// If user provides a descriptor with .xml at the end, assume he
+			// wants import by location
+			if (aeDescription.endsWith(".xml")) {
+				aeDescription = Utils.resolvePlaceholderIfExists(aeDescription,
+						System.getProperties());
+				if (!aeDescription.startsWith("file:")) {
+					aeDescription = "file:" + aeDescription;
+				}
+				descriptorImport.setLocation(aeDescription);
+			} else {
+				// uima import by name expects dot separated path as in
+				// a.b.descriptor and no .xml at the end
+				descriptorImport.setName(aeDescription);
+			}
+			String key = new String(aeDescription);
+			if (key.startsWith("file:")) {
+				key = key.substring(5); // skip "file:"
+			}
+			if (key.endsWith(".xml")) {
+				key = key.substring(0, key.indexOf(".xml")); // strip ".xml"
+			}
+			// preprocess the ae descriptor name to replace "/" and
+			// "\" with ".". We will use the ae
+			// descriptor name as AE key in the aggregate
+			if (key.indexOf("/") != -1) {
+				key = key.replaceAll("/", ".");
+			}
+			if (key.indexOf("\\") != -1) {
+				key = key.replaceAll("\\\\", ".");
+			}
+			key = key.substring(key.lastIndexOf(".") + 1);
+			desc.getDelegateAnalysisEngineSpecifiersWithImports().put(key,
+					descriptorImport);
+			flowNames.add(key);
+
+		}
+		String fcsn;
+		if ( (fcsn = getProperty(FlowControllerResourceSpecifier)) != null ) {
+			FlowControllerDeclaration fcd = new FlowControllerDeclaration_impl();
+			desc.setFlowControllerDeclaration(fcd);
+			fcd.setImport(new Import_impl());		
+			fcd.setKey(FlowControllerKey);
+			fcd.getImport().setName(fcsn);
+		}
+		
+		FixedFlow fixedFlow = new FixedFlow_impl();
+		fixedFlow.setFixedFlow(flowNames.toArray(new String[flowNames.size()]));
+		desc.getAnalysisEngineMetaData().setFlowConstraints(fixedFlow);
+		addOverrides(overrides, desc, specifiers, flowNames);
+
+		return desc;
+	}
+	
+	public static ConfigurationParameter findConfigurationParameter(ConfigurationParameterDeclarations configurationParameterDeclarations, String name) {
+		ConfigurationParameter retVal = null;
+		for (ConfigurationParameter parameter : configurationParameterDeclarations.getConfigurationParameters()) {
+			if (name.equals(parameter.getName())) {
+				retVal = parameter;
+				break;
+			}
+		}
+		return retVal;
+	}
+	
+	public static Object getOverrideValueObject(ConfigurationParameter configurationParameter, String value) throws ResourceConfigurationException {
+        Object retVal = value;
+        try {
+            if (configurationParameter.getType().equals("Integer")) {
+                retVal = Integer.parseInt(value);
+            } else if (configurationParameter.getType().equals("Boolean")) {
+                retVal = Boolean.parseBoolean(value);
+            } else if (configurationParameter.getType().equals("Float")) {
+                retVal = Float.parseFloat(value);
+            }
+        } catch (Throwable t) {
+            throw new ResourceConfigurationException(t);
+        }
+        return retVal;
+	}
+
+	private static String getProperty(String propertyName) {
+		//DuccPropertiesResolver.getInstance().getProperty(propertyName);
+		return null;
+	}
+	
+	private static void addOverrides(List<List<String>> overrides,
+			AnalysisEngineDescription desc, ResourceSpecifier[] specifiers,
+			List<String> flowNames) throws Exception {
+
+		ConfigurationParameterDeclarations aggregateDeclarations = desc
+				.getAnalysisEngineMetaData()
+				.getConfigurationParameterDeclarations();
+		ConfigurationParameterSettings aggregateSetttings = desc
+				.getAnalysisEngineMetaData()
+				.getConfigurationParameterSettings();
+		int indx = 0;
+		for (List<String> componentOverrides : overrides) {
+			if ( specifiers[indx] instanceof ResourceCreationSpecifier ) {
+				addComponentOverrides(flowNames.get(indx), componentOverrides,
+						(ResourceCreationSpecifier) specifiers[indx],
+						aggregateDeclarations, aggregateSetttings);
+			}
+			indx++;
+		}
+		
+	}
+
+	/**
+	 * Modifies aggregate descriptor by adding component specific overrides.
+	 * 
+	 * @param key
+	 *            - component key
+	 * @param componentOverrides
+	 *            - List of override params where element is expressed as String
+	 *            with format <name>=<value>
+	 * @param specifier
+	 *            - component resource specifier
+	 * @param aggregateDeclarations
+	 *            - aggregate ConfigurationParameterDeclarations
+	 * @param aggregateSetttings
+	 *            - aggregate ConfigurationParameterSettings
+	 */
+	private static void addComponentOverrides(String key,
+			List<String> componentOverrides,
+//			AnalysisEngineDescription specifier,
+			ResourceCreationSpecifier specifier,
+			ConfigurationParameterDeclarations aggregateDeclarations,
+			ConfigurationParameterSettings aggregateSetttings) throws Exception {
+
+		if (componentOverrides == null || componentOverrides.isEmpty()) { // no
+																			// overrides
+			return; // nothing to do
+		}
+		processOverrides(key, componentOverrides,
+			specifier, aggregateDeclarations,
+			//	(ResourceCreationSpecifier) specifier, aggregateDeclarations,
+				aggregateSetttings);
+
+	}
+
+	private static void processOverrides(String key,
+			List<String> componentOverrides,
+			ResourceCreationSpecifier specifier,
+			ConfigurationParameterDeclarations aggregateDeclarations,
+			ConfigurationParameterSettings aggregateSetttings) throws Exception {
+		// Process overrides
+		for (String cmOverride : componentOverrides) {
+			System.out.println(".... Processing Override:"+cmOverride);
+			// each override is expressed as <name>=<value> pair, so split on
+			// the first '=' found ... in case the value contains an '='
+			String[] nvp = cmOverride.split("=", 2);
+			// Fetch component parameter declarations to get the primitive type
+			// of the parameter
+			ConfigurationParameterDeclarations componentParameterDeclarations = specifier
+					.getMetaData().getConfigurationParameterDeclarations();
+			// Iterate over component parameter declarations looking to find one
+			// with the same name
+			// as provided in the override. On match, add an override to the
+			// aggregate and preserve
+			// the type defined for the parameter in the component descriptor.
+			// If no match, throw
+			// an exception
+			boolean found = false;
+			for (ConfigurationParameter parameter : componentParameterDeclarations
+					.getConfigurationParameters()) {
+				if (nvp[0].equals(parameter.getName())) {
+					addParam(key, nvp, parameter, aggregateDeclarations);
+					addParamValue(nvp, parameter, aggregateSetttings);
+					found = true;
+					break;
+				}
+			}
+			if (!found) {
+				throw new UIMARuntimeException(
+						new InvalidOverrideParameterException(
+								"Override Parameter:"
+										+ nvp[0]
+										+ " is not defined for the component with key: "
+										+ key));
+			}
+		}
+
+	}
+
+	/**
+	 * Adds parameter to aggregate ConfigurationParameterDeclarations.
+	 * 
+	 * @param key
+	 *            - component key
+	 * @param nvp
+	 *            - override name value pair
+	 * @param parameter
+	 *            - matching ConfigurationParameter instance from component
+	 *            descriptor or null
+	 * @param aggregateDeclarations
+	 *            - aggregate ConfigurationParameterDeclarations instance
+	 */
+	private static void addParam(String key, String[] nvp,
+			ConfigurationParameter parameter,
+			ConfigurationParameterDeclarations aggregateDeclarations) {
+		ConfigurationParameter cfgParam = new ConfigurationParameter_impl();
+		cfgParam.setName(nvp[0]);
+		if (parameter == null) { // component descriptor doesnt contain a
+									// parameter provided in the override list.
+									// Default to String
+			cfgParam.setType("String"); // create String param as default
+		} else {
+			cfgParam.setType(parameter.getType());
+		}
+//		if ( key.equals(FlowControllerKey)) {
+//			cfgParam.addOverride(key + "/ActionAfterCasMultiplier");
+//		} else {
+//			cfgParam.addOverride(key + "/" + nvp[0]);
+//		}
+		cfgParam.addOverride(key + "/" + nvp[0]);
+		aggregateDeclarations.addConfigurationParameter(cfgParam);
+
+	}
+
+	private static void addParamValue(String[] nvp,
+			ConfigurationParameter parameter,
+			ConfigurationParameterSettings aggregateSettings) {
+
+		Object value = nvp[1]; // default is String value
+		if (parameter != null) {
+			if (parameter.getType().equals("Integer")) {
+				value = Integer.parseInt(nvp[1]);
+			} else if (parameter.getType().equals("Boolean")) {
+				value = Boolean.parseBoolean(nvp[1]);
+			} else if (parameter.getType().equals("Float")) {
+				value = Float.parseFloat(nvp[1]);
+			}
+			aggregateSettings.setParameterValue(nvp[0], value);
+		} else {
+			aggregateSettings.setParameterValue(nvp[0], value);
+		}
+	}
+
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/UimaUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/Utils.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/Utils.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/Utils.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/Utils.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,357 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Field;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.rmi.server.UID;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+import java.util.regex.Pattern;
+
+import org.springframework.util.PropertyPlaceholderHelper;
+
+public class Utils {
+  public static final String FileSeparator = System.getProperty("file.separator");
+  
+	public static boolean isIpAddress( String ip ) {
+		String two_five_five = "(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2(?:[0-4][0-9]|5[0-5]))";
+        Pattern IPPattern = Pattern.compile("^(?:"+two_five_five+"\\.){3}"+two_five_five+"$");
+        return IPPattern.matcher(ip).matches();
+	}
+	public static int findFreePort() {
+	    ServerSocket socket = null;
+	    try {
+	      //  by passing 0 as an arg, let ServerSocket choose an arbitrary
+	      //  port that is available.
+	      socket = new ServerSocket(0);
+	    } catch (IOException e) {
+	    } finally { 
+	      try {
+	        // Clean up
+	        if (socket != null) {
+	          socket.close(); 
+	        } 
+	      } catch( Exception ex) {}
+	    }
+	    return socket.getLocalPort();
+	  }
+	public static boolean portAvailable(int port ) {
+		ServerSocket sock = null;
+		try {
+			sock = new ServerSocket();
+			sock.bind(new InetSocketAddress(port));
+			return true;
+		} catch( Exception e) {
+			return false;
+		} finally {
+		    if ( sock != null ) {
+		    	try {
+					sock.close();
+		    	} catch( Exception e) {
+		    		return false;
+		    	}
+		    }
+		}
+	}
+	public static boolean isThisNode(String node, String thisNodeIP) throws Exception {
+		if (Utils.isIpAddress(node)) {
+			if (thisNodeIP.equals(node.trim()) ) {
+				return true;
+			} 
+		}
+		return false;
+	}
+	
+	private static boolean isThisNode(String node, List<IIdentity> nodeIdentities) throws Exception {
+		if (Utils.isIpAddress(node)) {
+			for( IIdentity identity : nodeIdentities ) {
+				if (identity.getIP().startsWith(node) ) {
+					return true;
+				} 
+			}
+		}
+		return false;
+	}
+	
+	
+	
+//	public static boolean isTargetNodeForMessage(String targetNodeList) throws Exception{
+//		String[] nodes = targetNodeList.split(",");
+//		for ( String node : nodes ) {
+//			if ( isThisNode(node) ) {
+//				return true;
+//			}
+//		}
+//		return false;
+//	}
+	public static boolean isTargetNodeForMessage(String targetNodeList, String thisNodeIP) throws Exception{
+		String[] nodes = targetNodeList.split(",");
+		for ( String node : nodes ) {
+			if( isThisNode(node,thisNodeIP) ) {
+				return true;
+			}
+		}
+		return false;
+	}
+	public static boolean isTargetNodeForMessage(String targetNodeList, List<IIdentity> nodeIdentities) throws Exception{
+		String[] nodes = targetNodeList.split(",");
+		for ( String node : nodes ) {
+			if( isThisNode(node,nodeIdentities) ) {
+				return true;
+			}
+		}
+		return false;
+	}
+	public static Properties loadPropertiesFromClasspathForResource(String resource) throws Exception {
+		InputStream in = null;
+		Properties properties = new Properties();
+		ClassLoader loader = Thread.currentThread ().getContextClassLoader ();
+		if ( !resource.endsWith(".properties") ) {
+			resource += ".properties";
+		}
+		in = loader.getResourceAsStream (resource);
+        if (in != null)
+        {
+        	properties = new Properties ();
+        	properties.load (in); // Can throw IOException
+        } else {
+        	throw new IOException("Process Group Configuration File:"+resource+".properties Not Found in the Classpath");
+        }
+		return properties;
+	}
+	public static List<String> getHostsFromFile(String hostFilePath)
+			throws Exception {
+		List<String> nodeList = new ArrayList<String>();
+		File nodesFile = new File(hostFilePath);
+		if (nodesFile.exists()) {
+			// Open the file that is the first
+			// command line parameter
+			FileInputStream fstream = new FileInputStream(nodesFile);
+			DataInputStream in = null;
+			try {
+				// Get the object of DataInputStream
+				in = new DataInputStream(fstream);
+				BufferedReader br = new BufferedReader(
+						new InputStreamReader(in));
+				String node;
+				// Read File Line By Line
+				while ((node = br.readLine()) != null) {
+					// Print the content on the console
+					nodeList.add(node);
+				}
+			} catch (Exception e) {
+				throw e;
+			} finally {
+				// Close the input stream
+				in.close();
+			}
+		}
+		return nodeList; // empty list
+	}
+	public static String generateUniqueId() {
+		return new UID().toString();
+	}
+
+	public static boolean isLinux() {
+		return System.getProperty("os.name").toLowerCase().equals("linux");
+	}
+	public static boolean isWindows() {
+		return System.getProperty("os.name").toLowerCase().startsWith("windows");
+	}
+	public static boolean isMac() {
+		return System.getProperty("os.name").toLowerCase().startsWith("mac");
+	}
+	public static String getPID() {
+		String pid = ManagementFactory.getRuntimeMXBean().getName();
+		return pid.split("@")[0];
+	}
+	public static boolean isNumber(String number) {
+		try {
+			Integer.parseInt(number);
+			return true;
+		} catch( NumberFormatException e) {
+			return false;
+		}
+	}
+  /**
+   * Resolves placeholders in provided contents using java's Matcher. Finds
+   * all occurances of ${<placeholder>} and resolves each using System properties
+   * which holds <placeholder>=<value> pairs.
+   *  
+   * @param contents - target text containing placeholder(s)
+   * @param props - Properties object holding key/value pairs
+   * @return - text with resolved placeholders
+   * 
+   * @throws Exception
+   */
+    public static String resolvePlaceholders(String contents) 
+    {
+        return resolvePlaceholders(contents, System.getProperties());
+    }
+
+	/**
+	 * Resolves placeholders in provided contents using java's Matcher. Finds
+	 * all occurances of ${<placeholder>} and resolves each using provided
+	 * Properties object which holds <placeholder>=<value> pairs.
+	 * If the placeholder not found then tries the System properties.
+	 *  
+	 * @param contents - target text containing placeholder(s)
+	 * @param props - Properties object holding key/value pairs
+	 * @return - text with resolved placeholders
+	 * 
+	 * @throws Exception
+	 */
+	public static String resolvePlaceholders(String contents, Properties props ) 
+    {
+        //  Placeholders syntax ${<placeholder>}
+        Pattern placeHolderPattern = Pattern.compile("\\$\\{(.*?)\\}");
+      
+        java.util.regex.Matcher matcher = 
+            placeHolderPattern.matcher(contents); 
+
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            // extract placeholder
+            final String key = matcher.group(1);
+            //  Find value for extracted placeholder. 
+            String placeholderValue = props.getProperty(key);
+            if (placeholderValue == null) {
+                placeholderValue = System.getProperty(key);
+                if (placeholderValue == null) {
+                    throw new IllegalArgumentException("Missing value for placeholder: " + key);
+                }
+            }
+            matcher.appendReplacement(sb, placeholderValue);        
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+	}
+	
+	/**
+	 * Resolves placeholder using Spring Framework utility class
+	 *  
+	 * 
+	 * @param value
+	 * @param props
+	 * @return
+	 */
+	public static String resolvePlaceholderIfExists(String value, Properties props ) {
+		if ( value != null && value.contains("${")) {
+            PropertyPlaceholderHelper pph = new PropertyPlaceholderHelper("${","}");
+            value = pph.replacePlaceholders(value, props);
+        }
+		return value;  
+	}
+	/**
+	 * Concatenates multiple arrays into one array of type <A> 
+	 * 
+	 * @return array of type <A>
+	 */
+	public static <A> A[] concatAllArrays(A[] first, A[]... next) {
+		int totalLength = first.length;
+		//	compute the total size of all arrays
+		for (A[] array : next) {
+			totalLength += array.length;
+		}
+		A[] result = Arrays.copyOf(first, totalLength);
+		int offset = first.length;
+		for (A[] array : next) {
+			System.arraycopy(array, 0, result, offset, array.length);
+			offset += array.length;
+		}
+		return result;
+	}
+	public static int getPID(Process process) {
+		int pid = -1;
+		if (process.getClass().getName().equals("java.lang.UNIXProcess")) {
+			try {
+				Field f = process.getClass().getDeclaredField("pid");
+				f.setAccessible(true);
+				pid = f.getInt(process);
+			} catch (Throwable e) {
+				// ignore
+			}
+		}
+		return pid;
+	}
+	
+	private static boolean compare(String s1, String s2) {
+		boolean retVal = false;
+		if(s1 != null) {
+			if(s2 != null) {
+				if(s1.equals(s2)) {
+					retVal = true;
+				}
+			}
+		}
+		return retVal;
+	}
+	
+	public static boolean isMachineNameMatch(String m1, String m2) {
+		boolean retVal = false;
+		if(compare(m1,m2)) {
+			retVal = true;
+		}
+		else {
+			int ndx1 = m1.indexOf(".");
+		    int ndx2 = m2.indexOf(".");
+		    if ( (ndx1 > 0) && (ndx2 > 0) ) {
+		       	//retVal = false;  
+		    }
+		    else {
+		      	String n1 = m1;
+		      	if ( ndx1 > 0 ) {
+		      		n1 = m1.substring(0, ndx1);
+		       	}
+		       	String n2 = m2;
+		       	if ( ndx2 > 0 ) {
+		       		n2 = m2.substring(0, ndx2);
+		       	}
+		       	if(compare(n1,n2)) {
+					retVal = true;
+				}
+			}
+		}
+		return retVal;
+	}
+
+	public static void main(String[] args) {
+		try {
+			if ( Utils.isThisNode("192.168.3.3", "192.168.3.3") ) {
+				System.out.println("Nodes equal");
+			} else {
+				System.out.println("Nodes NOT equal");
+			}
+		} catch( Exception e) {
+			e.printStackTrace();
+		}
+	}
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/Utils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/XStreamUtils.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/XStreamUtils.java?rev=1641905&view=auto
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/XStreamUtils.java (added)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/XStreamUtils.java Wed Nov 26 19:48:31 2014
@@ -0,0 +1,34 @@
+/*
+ * 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.
+*/
+package org.apache.uima.ducc.user.dd;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+public class XStreamUtils {
+	
+	public static String marshall( Object targetToMarshall) throws Exception {
+        XStream xStream = new XStream(new DomDriver());
+        return xStream.toXML(targetToMarshall);
+	}
+	public static Object unmarshall( String targetToUnmarshall) throws Exception {
+		XStream xStream = new XStream(new DomDriver());
+		return xStream.fromXML(targetToUnmarshall);
+	}
+}

Propchange: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/dd/XStreamUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/test/java/org/apache/uima/ducc/user/jd/test/TestSuite.java
URL: http://svn.apache.org/viewvc/uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/test/java/org/apache/uima/ducc/user/jd/test/TestSuite.java?rev=1641905&r1=1641904&r2=1641905&view=diff
==============================================================================
--- uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/test/java/org/apache/uima/ducc/user/jd/test/TestSuite.java (original)
+++ uima/sandbox/uima-ducc/trunk/uima-ducc-user/src/test/java/org/apache/uima/ducc/user/jd/test/TestSuite.java Wed Nov 26 19:48:31 2014
@@ -21,9 +21,18 @@ package org.apache.uima.ducc.user.jd.tes
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 
+import org.apache.uima.ducc.user.dd.DeploymentDescriptorGenerator;
+import org.apache.uima.ducc.user.dd.DuccUimaAggregate;
+import org.apache.uima.ducc.user.dd.DuccUimaAggregateComponent;
+import org.apache.uima.ducc.user.dd.IDuccUimaAggregateComponent;
+import org.apache.uima.ducc.user.dd.IDuccUimaDeployableConfiguration;
 import org.apache.uima.ducc.user.jd.JdUserCollectionReader;
 import org.apache.uima.ducc.user.jd.JdUserException;
 import org.apache.uima.ducc.user.jd.JdUserMetaCas;
@@ -323,4 +332,75 @@ public class TestSuite {
 			fail("Exception");
 		}
 	}
+	
+	private void delete(File directory) {
+		try {
+			for(File file : directory.listFiles()) {
+				debug("delete: "+file.getName());
+				file.delete();
+			}
+			debug("delete: "+directory.getName());
+			directory.delete();
+		}
+		catch(Exception e) {
+			e.printStackTrace();
+		}
+	}
+	
+	private IDuccUimaDeployableConfiguration getIDuccUimaDeployableConfiguration() {
+		String ddName = "name";
+		String ddDescription = "description";
+		int ddThreadCount = 1;
+		String ddBrokerURL = "brokerURL";
+		String ddEndpoint = "endpoint";
+		ArrayList<IDuccUimaAggregateComponent> ddComponents = new ArrayList<IDuccUimaAggregateComponent>();
+		URL url = this.getClass().getResource("/CR100.xml");
+		File file = new File(url.getFile());
+		String aeDescriptor = file.getAbsolutePath();
+		List<String> aeOverrides = null;
+		DuccUimaAggregateComponent aeComponent = new DuccUimaAggregateComponent(aeDescriptor, aeOverrides);
+		ddComponents.add(aeComponent);
+		IDuccUimaDeployableConfiguration configuration = new DuccUimaAggregate(ddName, ddDescription, ddThreadCount, ddBrokerURL, ddEndpoint, ddComponents);
+		return configuration;
+	}
+	
+	private void show(String name) {
+		try {
+			BufferedReader br = new BufferedReader(new FileReader(name));
+			String line = null;
+			while ((line = br.readLine()) != null) {
+				System.out.println(line);
+			}
+			br.close();
+		}
+		catch(Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	@Test
+	public void test10() {
+		try {
+			URL url = this.getClass().getResource("/");
+			File root = new File(url.getFile());
+			String name = root.getAbsolutePath();
+			debug(name);
+			assertTrue(root.isDirectory());
+			String nameWorking = name+File.separator+"working";
+			File working = new File(nameWorking);
+			delete(working);
+			working.mkdir();
+			DeploymentDescriptorGenerator ddg = new DeploymentDescriptorGenerator(working.getAbsolutePath());
+			IDuccUimaDeployableConfiguration configuration = getIDuccUimaDeployableConfiguration();
+			String jobId = "12345";
+			String dd = ddg.generate(configuration, jobId);
+			debug(dd);
+			show(dd);
+			delete(working);
+		}
+		catch(Exception e) {
+			e.printStackTrace();
+			fail("Exception");
+		}
+	}
 }