You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@manifoldcf.apache.org by kw...@apache.org on 2011/08/04 18:32:43 UTC

svn commit: r1153921 - in /incubator/lcf/branches/CONNECTORS-236: connectors/cmis/ lib/ tests/ tests/cmis/ tests/cmis/src/ tests/cmis/src/test/ tests/cmis/src/test/java/ tests/cmis/src/test/java/org/ tests/cmis/src/test/java/org/apache/ tests/cmis/src/...

Author: kwright
Date: Thu Aug  4 16:32:41 2011
New Revision: 1153921

URL: http://svn.apache.org/viewvc?rev=1153921&view=rev
Log:
Stuff from Piergiorgio, except for the change to jetty-runner's pom.xml, which I didn't see the need for.

Added:
    incubator/lcf/branches/CONNECTORS-236/lib/chemistry-opencmis-server-inmemory-war-0.5.0-SNAPSHOT.war   (with props)
    incubator/lcf/branches/CONNECTORS-236/tests/cmis/
    incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/
    incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/
    incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/
    incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/
    incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/
    incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/
    incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/
    incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/APISanityTest.java
    incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/Base.java
Modified:
    incubator/lcf/branches/CONNECTORS-236/connectors/cmis/pom.xml
    incubator/lcf/branches/CONNECTORS-236/tests/pom.xml

Modified: incubator/lcf/branches/CONNECTORS-236/connectors/cmis/pom.xml
URL: http://svn.apache.org/viewvc/incubator/lcf/branches/CONNECTORS-236/connectors/cmis/pom.xml?rev=1153921&r1=1153920&r2=1153921&view=diff
==============================================================================
--- incubator/lcf/branches/CONNECTORS-236/connectors/cmis/pom.xml (original)
+++ incubator/lcf/branches/CONNECTORS-236/connectors/cmis/pom.xml Thu Aug  4 16:32:41 2011
@@ -66,7 +66,7 @@
 		<dependency>
     		<groupId>org.apache.chemistry.opencmis</groupId>
     		<artifactId>chemistry-opencmis-client-impl</artifactId>
-    		<version>0.4.0</version>
+    		<version>0.5.0-SNAPSHOT</version>
  		</dependency>
  		<dependency>
     		<groupId>commons-lang</groupId>

Added: incubator/lcf/branches/CONNECTORS-236/lib/chemistry-opencmis-server-inmemory-war-0.5.0-SNAPSHOT.war
URL: http://svn.apache.org/viewvc/incubator/lcf/branches/CONNECTORS-236/lib/chemistry-opencmis-server-inmemory-war-0.5.0-SNAPSHOT.war?rev=1153921&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/lcf/branches/CONNECTORS-236/lib/chemistry-opencmis-server-inmemory-war-0.5.0-SNAPSHOT.war
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/APISanityTest.java
URL: http://svn.apache.org/viewvc/incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/APISanityTest.java?rev=1153921&view=auto
==============================================================================
--- incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/APISanityTest.java (added)
+++ incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/APISanityTest.java Thu Aug  4 16:32:41 2011
@@ -0,0 +1,532 @@
+package org.apache.manifoldcf.cmis_tests;
+/* $Id$ */
+
+/**
+* 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 java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.chemistry.opencmis.client.api.Folder;
+import org.apache.chemistry.opencmis.client.api.ItemIterable;
+import org.apache.chemistry.opencmis.client.api.QueryResult;
+import org.apache.chemistry.opencmis.client.api.Session;
+import org.apache.chemistry.opencmis.client.api.SessionFactory;
+import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
+import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.SessionParameter;
+import org.apache.chemistry.opencmis.commons.data.ContentStream;
+import org.apache.chemistry.opencmis.commons.enums.BindingType;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
+import org.apache.chemistry.opencmis.commons.spi.Holder;
+import org.apache.chemistry.opencmis.commons.spi.ObjectService;
+import org.apache.commons.lang.StringUtils;
+import org.apache.manifoldcf.core.interfaces.Configuration;
+import org.apache.manifoldcf.core.interfaces.ConfigurationNode;
+import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
+import org.apache.manifoldcf.crawler.system.ManifoldCF;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Piergiorgio Lucidi
+ */
+public class APISanityTest extends Base
+{
+  private static final String REPLACER = "?";
+  private static final String CMIS_TEST_QUERY_CHANGE_DOC = "SELECT * FROM cmis:document WHERE cmis:name='"+REPLACER+"'";
+  private static final String CMIS_TEST_QUERY = "SELECT * FROM cmis:folder WHERE cmis:name='testdata'";
+  
+  private static final String CMIS_ENDPOINT_TEST_SERVER = "http://localhost:9090/chemistry-opencmis-server-inmemory/atom";
+  private static final String CMIS_USERNAME = "dummyuser"; 
+  private static final String CMIS_PASSWORD = "dummysecret";
+  
+  private Session cmisClientSession = null;
+  
+  private Session getCmisClientSession(){
+    // default factory implementation
+    SessionFactory factory = SessionFactoryImpl.newInstance();
+    Map<String, String> parameters = new HashMap<String, String>();
+
+    // user credentials
+    parameters.put(SessionParameter.USER, CMIS_USERNAME);
+    parameters.put(SessionParameter.PASSWORD, CMIS_USERNAME);
+
+    // connection settings
+    parameters.put(SessionParameter.ATOMPUB_URL, CMIS_ENDPOINT_TEST_SERVER);
+    parameters.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
+
+    // create session
+    return factory.getRepositories(parameters).get(0).createSession();
+  }
+  
+  public Folder getTestFolder(Session session){
+    Folder testFolder = null;
+    ItemIterable<QueryResult> results = session.query(CMIS_TEST_QUERY, false);
+    for (QueryResult result : results) {
+      String folderId = result.getPropertyById("cmis:objectId").getFirstValue().toString();
+      testFolder = (Folder)session.getObject(folderId);
+    }
+    return testFolder;
+  }
+  
+  public void createNewDocument(Folder folder, String name) throws IOException{
+    // properties 
+    // (minimal set: name and object type id)
+    Map<String, Object> contentProperties = new HashMap<String, Object>();
+    contentProperties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:document");
+    contentProperties.put(PropertyIds.NAME, name);
+  
+    // content
+    String contentString = "CMIS Testdata "+name;
+    byte[] content = contentString.getBytes();
+    InputStream stream = new ByteArrayInputStream(content);
+    ContentStream contentStream = new ContentStreamImpl(name, new BigInteger(content), "text/plain", stream);
+  
+    // create a major version
+    folder.createDocument(contentProperties, contentStream, null);
+    stream.close();
+  }
+  
+  /**
+   * change the document content with the new one provided as an argument
+   * @param session
+   * @param name
+   * @param newContent
+   */
+  public void changeDocument(Session session, String name, String newContent){
+    String cmisQuery = StringUtils.replace(CMIS_TEST_QUERY_CHANGE_DOC, REPLACER, name);
+    ItemIterable<QueryResult> results = session.query(cmisQuery, false);
+    String objectId = StringUtils.EMPTY;
+    for (QueryResult result : results) {
+      objectId = result.getPropertyById("cmis:objectId").getFirstValue().toString();
+    }
+    String repositoryId = session.getRepositoryInfo().getId();
+    Holder<String> objectIdHolder = new Holder<String>(objectId);
+    Boolean overwriteFlag = true;
+    byte[] newContentByteArray = newContent.getBytes();
+    InputStream stream = new ByteArrayInputStream(newContentByteArray);
+    ContentStream contentStream = new ContentStreamImpl(name, new BigInteger(newContentByteArray), "text/plain", stream);
+    ObjectService objectService = session.getBinding().getObjectService();
+    objectService.setContentStream(repositoryId, objectIdHolder, overwriteFlag, null, contentStream, null);
+  }
+  
+  public void removeDocument(Session session, String name){
+    String cmisQuery = StringUtils.replace(CMIS_TEST_QUERY_CHANGE_DOC, REPLACER, name);
+    ItemIterable<QueryResult> results = session.query(cmisQuery, false);
+    String objectId = StringUtils.EMPTY;
+    for (QueryResult result : results) {
+      objectId = result.getPropertyById("cmis:objectId").getFirstValue().toString();
+    }
+    String repositoryId = session.getRepositoryInfo().getId();
+    ObjectService objectService = session.getBinding().getObjectService();
+    objectService.deleteObject(repositoryId, objectId, true, null);
+  }
+  
+  @Before
+  public void createTestArea()
+    throws Exception
+  {
+    try
+    {
+      cmisClientSession = getCmisClientSession();
+
+      //creating a new folder
+      Folder root = cmisClientSession.getRootFolder();
+      
+      ItemIterable<QueryResult> results = cmisClientSession.query(CMIS_TEST_QUERY, false);
+      for (QueryResult result : results) {
+         String repositoryId = cmisClientSession.getRepositoryInfo().getId();
+        String folderId = result.getPropertyById("cmis:objectId").getFirstValue().toString();
+        cmisClientSession.getBinding().getObjectService().deleteTree(repositoryId, folderId, true, null, false, null);
+      }
+
+      Map<String, Object> folderProperties = new HashMap<String, Object>();
+      folderProperties.put(PropertyIds.OBJECT_TYPE_ID, "cmis:folder");
+      folderProperties.put(PropertyIds.NAME, "testdata");
+  
+      Folder newFolder = root.createFolder(folderProperties);
+
+      String name = "testdata1.txt";
+      createNewDocument(newFolder, name);
+      
+      name = "testdata2.txt";
+      createNewDocument(newFolder,name);
+      
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+  
+  @After
+  public void removeTestArea()
+    throws Exception
+  {
+    // we don't need to remove anything
+  }
+  
+  @Test
+  public void sanityCheck()
+    throws Exception
+  {
+    try
+    {
+      
+      int i;
+
+      // Create a basic file system connection, and save it.
+      ConfigurationNode connectionObject;
+      ConfigurationNode child;
+      Configuration requestObject;
+      Configuration result;
+      
+      connectionObject = new ConfigurationNode("repositoryconnection");
+      
+      child = new ConfigurationNode("name");
+      child.setValue("CMIS Connection");
+      connectionObject.addChild(connectionObject.getChildCount(),child);
+      
+      child = new ConfigurationNode("class_name");
+      child.setValue("org.apache.manifoldcf.crawler.connectors.cmis.CmisRepositoryConnector");
+      connectionObject.addChild(connectionObject.getChildCount(),child);
+      
+      child = new ConfigurationNode("description");
+      child.setValue("CMIS Connection");
+      connectionObject.addChild(connectionObject.getChildCount(),child);
+
+      child = new ConfigurationNode("max_connections");
+      child.setValue("10");
+      connectionObject.addChild(connectionObject.getChildCount(),child);
+      
+      child = new ConfigurationNode("configuration");
+      
+      //CMIS Repository Connector parameters
+      
+      //username
+      ConfigurationNode cmisUsernameNode = new ConfigurationNode("_PARAMETER_");
+      cmisUsernameNode.setAttribute("name", "username");
+      cmisUsernameNode.setValue(CMIS_USERNAME);
+      child.addChild(child.getChildCount(), cmisUsernameNode);
+      
+      //password
+      ConfigurationNode cmisPasswordNode = new ConfigurationNode("_PARAMETER_");
+      cmisPasswordNode.setAttribute("name", "password");
+      cmisPasswordNode.setValue(CMIS_PASSWORD);
+      child.addChild(child.getChildCount(), cmisPasswordNode);
+      
+      //endpoint
+      ConfigurationNode cmisEndpointNode = new ConfigurationNode("_PARAMETER_");
+      cmisEndpointNode.setAttribute("name", "endpoint");
+      cmisEndpointNode.setValue(CMIS_ENDPOINT_TEST_SERVER);
+      child.addChild(child.getChildCount(), cmisEndpointNode);
+      
+      connectionObject.addChild(connectionObject.getChildCount(),child);
+
+      requestObject = new Configuration();
+      requestObject.addChild(0,connectionObject);
+      
+      result = performAPIPutOperationViaNodes("repositoryconnections/CMIS%20Connection",201,requestObject);
+      
+      i = 0;
+      while (i < result.getChildCount())
+      {
+        ConfigurationNode resultNode = result.findChild(i++);
+        if (resultNode.getType().equals("error"))
+          throw new Exception(resultNode.getValue());
+      }
+      
+      // Create a basic null output connection, and save it.
+      connectionObject = new ConfigurationNode("outputconnection");
+      
+      child = new ConfigurationNode("name");
+      child.setValue("Null Connection");
+      connectionObject.addChild(connectionObject.getChildCount(),child);
+      
+      child = new ConfigurationNode("class_name");
+      child.setValue("org.apache.manifoldcf.agents.output.nullconnector.NullConnector");
+      connectionObject.addChild(connectionObject.getChildCount(),child);
+      
+      child = new ConfigurationNode("description");
+      child.setValue("Null Connection");
+      connectionObject.addChild(connectionObject.getChildCount(),child);
+
+      child = new ConfigurationNode("max_connections");
+      child.setValue("100");
+      connectionObject.addChild(connectionObject.getChildCount(),child);
+
+      requestObject = new Configuration();
+      requestObject.addChild(0,connectionObject);
+      
+      result = performAPIPutOperationViaNodes("outputconnections/Null%20Connection",201,requestObject);
+      
+      i = 0;
+      while (i < result.getChildCount())
+      {
+        ConfigurationNode resultNode = result.findChild(i++);
+        if (resultNode.getType().equals("error"))
+          throw new Exception(resultNode.getValue());
+      }
+
+      // Create a job.
+      ConfigurationNode jobObject = new ConfigurationNode("job");
+      
+      child = new ConfigurationNode("description");
+      child.setValue("Test Job");
+      jobObject.addChild(jobObject.getChildCount(),child);
+
+      child = new ConfigurationNode("repository_connection");
+      child.setValue("CMIS Connection");
+      jobObject.addChild(jobObject.getChildCount(),child);
+
+      child = new ConfigurationNode("output_connection");
+      child.setValue("Null Connection");
+      jobObject.addChild(jobObject.getChildCount(),child);
+
+      child = new ConfigurationNode("run_mode");
+      child.setValue("scan once");
+      jobObject.addChild(jobObject.getChildCount(),child);
+
+      child = new ConfigurationNode("start_mode");
+      child.setValue("manual");
+      jobObject.addChild(jobObject.getChildCount(),child);
+
+      child = new ConfigurationNode("hopcount_mode");
+      child.setValue("accurate");
+      jobObject.addChild(jobObject.getChildCount(),child);
+
+      child = new ConfigurationNode("document_specification");
+      
+      
+      //Job configuration
+      ConfigurationNode sn = new ConfigurationNode("startpoint");
+      sn.setAttribute("cmisQuery",CMIS_TEST_QUERY);
+      
+      child.addChild(child.getChildCount(),sn);
+      jobObject.addChild(jobObject.getChildCount(),child);
+      
+      requestObject = new Configuration();
+      requestObject.addChild(0,jobObject);
+      
+      result = performAPIPostOperationViaNodes("jobs",201,requestObject);
+      
+      String jobIDString = null;
+      i = 0;
+      while (i < result.getChildCount())
+      {
+        ConfigurationNode resultNode = result.findChild(i++);
+        if (resultNode.getType().equals("error"))
+          throw new Exception(resultNode.getValue());
+        else if (resultNode.getType().equals("job_id"))
+          jobIDString = resultNode.getValue();
+      }
+      if (jobIDString == null)
+        throw new Exception("Missing job_id from return!");
+      
+      // Now, start the job, and wait until it completes.
+      startJob(jobIDString);
+      waitJobInactive(jobIDString, 120000L);
+
+      // Check to be sure we actually processed the right number of documents.
+      // The test data area has 3 documents and one directory, and we have to count the root directory too.
+      long count;
+      count = getJobDocumentsProcessed(jobIDString);
+      if (count != 3)
+        throw new ManifoldCFException("Wrong number of documents processed - expected 3, saw "+new Long(count).toString());
+      
+      // Add a file and recrawl
+      Folder testFolder = getTestFolder(cmisClientSession);
+      createNewDocument(testFolder, "testdata3.txt");
+      createNewDocument(testFolder, "testdata4.txt");
+
+      // Now, start the job, and wait until it completes.
+      startJob(jobIDString);
+      waitJobInactive(jobIDString, 120000L);
+
+      // The test data area has 4 documents and one directory, and we have to count the root directory too.
+      count = getJobDocumentsProcessed(jobIDString);
+      if (count != 5)
+        throw new ManifoldCFException("Wrong number of documents processed after add - expected 5, saw "+new Long(count).toString());
+
+      // Change a document, and recrawl
+      changeDocument(cmisClientSession,"testdata1.txt","MODIFIED - CMIS Testdata - MODIFIED");
+      
+      // Now, start the job, and wait until it completes.
+      startJob(jobIDString);
+      waitJobInactive(jobIDString, 120000L);
+
+      // The test data area has 4 documents and one directory, and we have to count the root directory too.
+      count = getJobDocumentsProcessed(jobIDString);
+      if (count != 5)
+        throw new ManifoldCFException("Wrong number of documents processed after change - expected 5, saw "+new Long(count).toString());
+      
+      // We also need to make sure the new document was indexed.  Have to think about how to do this though.
+      // MHL
+      
+      // Delete a file, and recrawl
+      removeDocument(cmisClientSession, "testdata2.txt");
+      
+      // Now, start the job, and wait until it completes.
+      startJob(jobIDString);
+      waitJobInactive(jobIDString, 120000L);
+
+      // Check to be sure we actually processed the right number of documents.
+      // The test data area has 3 documents and one directory, and we have to count the root directory too.
+      count = getJobDocumentsProcessed(jobIDString);
+      if (count != 4)
+        throw new ManifoldCFException("Wrong number of documents processed after delete - expected 5, saw "+new Long(count).toString());
+
+      // Now, delete the job.
+      deleteJob(jobIDString);
+
+      waitJobDeleted(jobIDString, 120000L);
+      
+      // Cleanup is automatic by the base class, so we can feel free to leave jobs and connections lying around.
+    }
+    catch (Exception e)
+    {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+  
+  protected void startJob(String jobIDString)
+    throws Exception
+  {
+    Configuration requestObject = new Configuration();
+    
+    Configuration result = performAPIPutOperationViaNodes("start/"+jobIDString,201,requestObject);
+    int i = 0;
+    while (i < result.getChildCount())
+    {
+      ConfigurationNode resultNode = result.findChild(i++);
+      if (resultNode.getType().equals("error"))
+        throw new Exception(resultNode.getValue());
+    }
+  }
+  
+  protected void deleteJob(String jobIDString)
+    throws Exception
+  {
+    Configuration result = performAPIDeleteOperationViaNodes("jobs/"+jobIDString,200);
+    int i = 0;
+    while (i < result.getChildCount())
+    {
+      ConfigurationNode resultNode = result.findChild(i++);
+      if (resultNode.getType().equals("error"))
+        throw new Exception(resultNode.getValue());
+    }
+
+  }
+  
+  protected String getJobStatus(String jobIDString)
+    throws Exception
+  {
+    Configuration result = performAPIGetOperationViaNodes("jobstatuses/"+jobIDString,200);
+    String status = null;
+    int i = 0;
+    while (i < result.getChildCount())
+    {
+      ConfigurationNode resultNode = result.findChild(i++);
+      if (resultNode.getType().equals("error"))
+        throw new Exception(resultNode.getValue());
+      else if (resultNode.getType().equals("jobstatus"))
+      {
+        int j = 0;
+        while (j < resultNode.getChildCount())
+        {
+          ConfigurationNode childNode = resultNode.findChild(j++);
+          if (childNode.getType().equals("status"))
+            status = childNode.getValue();
+        }
+      }
+    }
+    return status;
+  }
+
+  protected long getJobDocumentsProcessed(String jobIDString)
+    throws Exception
+  {
+    Configuration result = performAPIGetOperationViaNodes("jobstatuses/"+jobIDString,200);
+    String documentsProcessed = null;
+    int i = 0;
+    while (i < result.getChildCount())
+    {
+      ConfigurationNode resultNode = result.findChild(i++);
+      if (resultNode.getType().equals("error"))
+        throw new Exception(resultNode.getValue());
+      else if (resultNode.getType().equals("jobstatus"))
+      {
+        int j = 0;
+        while (j < resultNode.getChildCount())
+        {
+          ConfigurationNode childNode = resultNode.findChild(j++);
+          if (childNode.getType().equals("documents_processed"))
+            documentsProcessed = childNode.getValue();
+        }
+      }
+    }
+    if (documentsProcessed == null)
+      throw new Exception("Expected a documents_processed field, didn't find it");
+    return new Long(documentsProcessed).longValue();
+  }
+
+  protected void waitJobInactive(String jobIDString, long maxTime)
+    throws Exception
+  {
+    long startTime = System.currentTimeMillis();
+    while (System.currentTimeMillis() < startTime + maxTime)
+    {
+      String status = getJobStatus(jobIDString);
+      if (status == null)
+        throw new Exception("No such job: '"+jobIDString+"'");
+      if (status.equals("not yet run"))
+        throw new Exception("Job was never started.");
+      if (status.equals("done"))
+        return;
+      if (status.equals("error"))
+        throw new Exception("Job reports error.");
+      ManifoldCF.sleep(1000L);
+      continue;
+    }
+    throw new ManifoldCFException("ManifoldCF did not terminate in the allotted time of "+new Long(maxTime).toString()+" milliseconds");
+  }
+  
+  protected void waitJobDeleted(String jobIDString, long maxTime)
+    throws Exception
+  {
+    long startTime = System.currentTimeMillis();
+    while (System.currentTimeMillis() < startTime + maxTime)
+    {
+      String status = getJobStatus(jobIDString);
+      if (status == null)
+        return;
+      ManifoldCF.sleep(1000L);
+    }
+    throw new ManifoldCFException("ManifoldCF did not delete in the allotted time of "+new Long(maxTime).toString()+" milliseconds");
+  }
+    
+
+}

Added: incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/Base.java
URL: http://svn.apache.org/viewvc/incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/Base.java?rev=1153921&view=auto
==============================================================================
--- incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/Base.java (added)
+++ incubator/lcf/branches/CONNECTORS-236/tests/cmis/src/test/java/org/apache/manifoldcf/cmis_tests/Base.java Thu Aug  4 16:32:41 2011
@@ -0,0 +1,481 @@
+/* $Id$ */
+
+/**
+* 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.manifoldcf.cmis_tests;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.DeleteMethod;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.manifoldcf.core.interfaces.Configuration;
+import org.apache.manifoldcf.core.interfaces.ILockManager;
+import org.apache.manifoldcf.core.interfaces.IThreadContext;
+import org.apache.manifoldcf.core.interfaces.LockManagerFactory;
+import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
+import org.apache.manifoldcf.core.interfaces.ThreadContextFactory;
+import org.apache.manifoldcf.crawler.interfaces.IJobDescription;
+import org.apache.manifoldcf.crawler.interfaces.IJobManager;
+import org.apache.manifoldcf.crawler.interfaces.JobManagerFactory;
+import org.apache.manifoldcf.crawler.interfaces.JobStatus;
+import org.apache.manifoldcf.crawler.system.ManifoldCF;
+import org.junit.After;
+import org.junit.Before;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.webapp.WebAppContext;
+
+/** Tests that run the "agents daemon" should be derived from this 
+ * 
+ *  @author Piergiorgio Lucidi
+ * 
+ * */
+public class Base extends org.apache.manifoldcf.crawler.tests.ConnectorBase
+{
+  public static final String agentShutdownSignal = "agent-process";
+  public static final int testPort = 8346;
+  
+  protected DaemonThread daemonThread = null;
+  protected Server server = null;
+  protected Server cmisServer = null;
+
+  
+  protected String[] getConnectorNames()
+  {
+    return new String[]{"CMIS"};
+  }
+  
+  protected String[] getConnectorClasses()
+  {
+    return new String[]{"org.apache.manifoldcf.crawler.connectors.cmis.CmisRepositoryConnector"};
+  }
+  
+  protected String[] getOutputNames()
+  {
+    return new String[]{"Null Output"};
+  }
+  
+  protected String[] getOutputClasses()
+  {
+    return new String[]{"org.apache.manifoldcf.agents.output.nullconnector.NullConnector"};
+  }
+  
+  // API support
+  
+  // These methods allow communication with the ManifoldCF api webapp, via the locally-instantiated jetty
+  
+  /** Construct a command url.
+  */
+  protected String makeAPIURL(String command)
+  {
+    return "http://localhost:"+Integer.toString(testPort)+"/mcf-api-service/json/"+command;
+  }
+  
+  /** Perform an json API GET operation.
+  *@param apiURL is the operation.
+  *@param expectedResponse is the expected response code.
+  *@return the json response.
+  */
+  protected String performAPIGetOperation(String apiURL, int expectedResponse)
+    throws Exception
+  {
+    HttpClient client = new HttpClient();
+    GetMethod method = new GetMethod(apiURL);
+    int response = client.executeMethod(method);
+    byte[] responseData = method.getResponseBody();
+    String responseString = new String(responseData,"utf-8");
+    if (response != expectedResponse)
+      throw new Exception("API http error; expected "+Integer.toString(expectedResponse)+", saw "+Integer.toString(response)+": "+responseString);
+    // We presume that the data is utf-8, since that's what the API uses throughout.
+    return responseString;
+  }
+
+  /** Perform an json API DELETE operation.
+  *@param apiURL is the operation.
+  *@param expectedResponse is the expected response code.
+  *@return the json response.
+  */
+  protected String performAPIDeleteOperation(String apiURL, int expectedResponse)
+    throws Exception
+  {
+    HttpClient client = new HttpClient();
+    DeleteMethod method = new DeleteMethod(apiURL);
+    int response = client.executeMethod(method);
+    byte[] responseData = method.getResponseBody();
+    String responseString = new String(responseData,"utf-8");
+    if (response != expectedResponse)
+      throw new Exception("API http error; expected "+Integer.toString(expectedResponse)+", saw "+Integer.toString(response)+": "+responseString);
+    // We presume that the data is utf-8, since that's what the API uses throughout.
+    return responseString;
+  }
+
+  /** Perform an json API PUT operation.
+  *@param apiURL is the operation.
+  *@param input is the input JSON.
+  *@param expectedResponse is the expected response code.
+  *@return the json response.
+  */
+  protected String performAPIPutOperation(String apiURL, int expectedResponse, String input)
+    throws Exception
+  {
+    HttpClient client = new HttpClient();
+    PutMethod method = new PutMethod(apiURL);
+    method.setRequestHeader("Content-type", "text/plain; charset=UTF-8");
+    method.setRequestBody(input);
+    int response = client.executeMethod(method);
+    byte[] responseData = method.getResponseBody();
+    String responseString = new String(responseData,"utf-8");
+    if (response != expectedResponse)
+      throw new Exception("API http error; expected "+Integer.toString(expectedResponse)+", saw "+Integer.toString(response)+": "+responseString);
+    // We presume that the data is utf-8, since that's what the API uses throughout.
+    return responseString;
+  }
+
+  /** Perform an json API POST operation.
+  *@param apiURL is the operation.
+  *@param input is the input JSON.
+  *@param expectedResponse is the expected response code.
+  *@return the json response.
+  */
+  protected String performAPIPostOperation(String apiURL, int expectedResponse, String input)
+    throws Exception
+  {
+    HttpClient client = new HttpClient();
+    PostMethod method = new PostMethod(apiURL);
+    method.setRequestHeader("Content-type", "text/plain; charset=UTF-8");
+    method.setRequestBody(input);
+    int response = client.executeMethod(method);
+    byte[] responseData = method.getResponseBody();
+    String responseString = new String(responseData,"utf-8");
+    if (response != expectedResponse)
+      throw new Exception("API http error; expected "+Integer.toString(expectedResponse)+", saw "+Integer.toString(response)+": "+responseString);
+    // We presume that the data is utf-8, since that's what the API uses throughout.
+    return responseString;
+  }
+
+  /** Perform a json GET API operation, using Configuration structures to represent the json.  This is for testing convenience,
+  * mostly.
+  */
+  protected Configuration performAPIGetOperationViaNodes(String command, int expectedResponse)
+    throws Exception
+  {
+    String result = performAPIGetOperation(makeAPIURL(command),expectedResponse);
+    Configuration cfg = new Configuration();
+    cfg.fromJSON(result);
+    return cfg;
+  }
+
+  /** Perform a json DELETE API operation, using Configuration structures to represent the json.  This is for testing convenience,
+  * mostly.
+  */
+  protected Configuration performAPIDeleteOperationViaNodes(String command, int expectedResponse)
+    throws Exception
+  {
+    String result = performAPIDeleteOperation(makeAPIURL(command),expectedResponse);
+    Configuration cfg = new Configuration();
+    cfg.fromJSON(result);
+    return cfg;
+  }
+
+  /** Perform a json PUT API operation, using Configuration structures to represent the json.  This is for testing convenience,
+  * mostly.
+  */
+  protected Configuration performAPIPutOperationViaNodes(String command, int expectedResponse, Configuration argument)
+    throws Exception
+  {
+    String argumentJson;
+    if (argument != null)
+      argumentJson = argument.toJSON();
+    else
+      argumentJson = null;
+    
+    String result = performAPIPutOperation(makeAPIURL(command),expectedResponse,argumentJson);
+    Configuration cfg = new Configuration();
+    cfg.fromJSON(result);
+    return cfg;
+  }
+
+  /** Perform a json POST API operation, using Configuration structures to represent the json.  This is for testing convenience,
+  * mostly.
+  */
+  protected Configuration performAPIPostOperationViaNodes(String command, int expectedResponse, Configuration argument)
+    throws Exception
+  {
+    String argumentJson;
+    if (argument != null)
+      argumentJson = argument.toJSON();
+    else
+      argumentJson = null;
+    
+    String result = performAPIPostOperation(makeAPIURL(command),expectedResponse,argumentJson);
+    Configuration cfg = new Configuration();
+    cfg.fromJSON(result);
+    return cfg;
+  }
+
+  // Setup/teardown
+  
+  @Before
+  public void setUp()
+    throws Exception
+  {
+    super.setUp();
+    // Start jetty
+    server = new Server( testPort );    
+    server.setStopAtShutdown( true );
+    
+    cmisServer = new Server(9090);
+    server.setStopAtShutdown(true);
+    
+    String crawlerWarPath = "/Users/piergiorgiolucidi/Documents/workspaces/manifold/mcf-trunk/tests/cmis/target/dependency/mcf-crawler-ui-0.3.0-SNAPSHOT.war";
+    String authorityserviceWarPath = "/Users/piergiorgiolucidi/Documents/workspaces/manifold/mcf-trunk/tests/cmis/target/dependency/mcf-authority-service-0.3.0-SNAPSHOT.war";
+    String apiWarPath = "/Users/piergiorgiolucidi/Documents/workspaces/manifold/mcf-trunk/tests/cmis/target/dependency/mcf-api-service-0.3.0-SNAPSHOT.war";
+    String openCmisServerWarPath = "/Users/piergiorgiolucidi/Documents/workspaces/manifold/mcf-trunk/tests/cmis/war/chemistry-opencmis-server-inmemory-war-0.5.0-SNAPSHOT.war";
+
+    if (System.getProperty("crawlerWarPath") != null)
+    	crawlerWarPath = System.getProperty("crawlerWarPath");
+    if (System.getProperty("authorityserviceWarPath") != null)
+    	authorityserviceWarPath = System.getProperty("authorityserviceWarPath");
+    if (System.getProperty("apiWarPath") != null)
+    	apiWarPath = System.getProperty("apiWarPath");
+    if (System.getProperty("openCmisServerWarPath") != null)
+      openCmisServerWarPath = System.getProperty("openCmisServerWarPath");
+    
+    // Initialize the servlets
+    WebAppContext lcfCrawlerUI = new WebAppContext(crawlerWarPath,"/mcf-crawler-ui");
+    // This will cause jetty to ignore all of the framework and jdbc jars in the war, which is what we want.
+    lcfCrawlerUI.setParentLoaderPriority(true);
+    server.addHandler(lcfCrawlerUI);
+    WebAppContext lcfAuthorityService = new WebAppContext(authorityserviceWarPath,"/mcf-authority-service");
+    // This will cause jetty to ignore all of the framework and jdbc jars in the war, which is what we want.
+    lcfAuthorityService.setParentLoaderPriority(true);
+    server.addHandler(lcfAuthorityService);
+    WebAppContext lcfApi = new WebAppContext(apiWarPath,"/mcf-api-service");
+    lcfApi.setParentLoaderPriority(true);
+    server.addHandler(lcfApi);
+    
+    //Initialize OpenCMIS Server bindings
+    WebAppContext openCmisServerApi = new WebAppContext(openCmisServerWarPath,"/chemistry-opencmis-server-inmemory");
+    lcfApi.setParentLoaderPriority(true);
+    cmisServer.addHandler(openCmisServerApi);
+    
+    cmisServer.start();
+    server.start();
+    
+
+    // If all worked, then we can start the daemon.
+    // Clear the agents shutdown signal.
+    IThreadContext tc = ThreadContextFactory.make();
+    ILockManager lockManager = LockManagerFactory.make(tc);
+    lockManager.clearGlobalFlag(agentShutdownSignal);
+
+    daemonThread = new DaemonThread();
+    daemonThread.start();
+  }
+  
+  @After
+  public void cleanUp()
+    throws Exception
+  {
+    initialize();
+    if (isInitialized())
+    {
+      Exception currentException = null;
+      IThreadContext tc = ThreadContextFactory.make();
+
+      // Delete all jobs (and wait for them to go away)
+      if (daemonThread != null)
+      {
+        IJobManager jobManager = JobManagerFactory.make(tc);
+        
+        // Get a list of the current active jobs
+        IJobDescription[] jobs = jobManager.getAllJobs();
+        int i = 0;
+        while (i < jobs.length)
+        {
+          IJobDescription desc = jobs[i++];
+          // Abort this job, if it is running
+          try
+          {
+            jobManager.manualAbort(desc.getID());
+          }
+          catch (ManifoldCFException e)
+          {
+            // This generally means that the job was not running
+          }
+        }
+        i = 0;
+        while (i < jobs.length)
+        {
+          IJobDescription desc = jobs[i++];
+          // Wait for this job to stop
+          while (true)
+          {
+            JobStatus status = jobManager.getStatus(desc.getID());
+            if (status != null)
+            {
+              int statusValue = status.getStatus();
+              switch (statusValue)
+              {
+              case JobStatus.JOBSTATUS_NOTYETRUN:
+              case JobStatus.JOBSTATUS_COMPLETED:
+              case JobStatus.JOBSTATUS_ERROR:
+                break;
+              default:
+                ManifoldCF.sleep(10000);
+                continue;
+              }
+            }
+            break;
+          }
+        }
+
+        // Now, delete them all
+        i = 0;
+        while (i < jobs.length)
+        {
+          IJobDescription desc = jobs[i++];
+          try
+          {
+            jobManager.deleteJob(desc.getID());
+          }
+          catch (ManifoldCFException e)
+          {
+            // This usually means that the job is already being deleted
+          }
+        }
+
+        i = 0;
+        while (i < jobs.length)
+        {
+          IJobDescription desc = jobs[i++];
+          // Wait for this job to disappear
+          while (true)
+          {
+            JobStatus status = jobManager.getStatus(desc.getID());
+            if (status != null)
+            {
+              ManifoldCF.sleep(10000);
+              continue;
+            }
+            break;
+          }
+        }
+
+        // Shut down daemon
+        ILockManager lockManager = LockManagerFactory.make(tc);
+        lockManager.setGlobalFlag(agentShutdownSignal);
+      
+        // Wait for daemon thread to exit.
+        while (true)
+        {
+          if (daemonThread.isAlive())
+          {
+            Thread.sleep(1000L);
+            continue;
+          }
+          break;
+        }
+
+        Exception e = daemonThread.getDaemonException();
+        if (e != null)
+          currentException = e;
+      }
+      
+      if (server != null)
+      {
+        server.stop();
+        server.join();
+        server = null;
+      }
+      
+      // Clean up everything else
+      try
+      {
+        super.cleanUp();
+      }
+      catch (Exception e)
+      {
+        if (currentException == null)
+          currentException = e;
+      }
+      if (currentException != null)
+        throw currentException;
+    }
+  }
+  
+  protected static class DaemonThread extends Thread
+  {
+    protected Exception daemonException = null;
+    
+    public DaemonThread()
+    {
+      setName("Daemon thread");
+    }
+    
+    public void run()
+    {
+      IThreadContext tc = ThreadContextFactory.make();
+      // Now, start the server, and then wait for the shutdown signal.  On shutdown, we have to actually do the cleanup,
+      // because the JVM isn't going away.
+      try
+      {
+        ILockManager lockManager = LockManagerFactory.make(tc);
+        while (true)
+        {
+          // Any shutdown signal yet?
+          if (lockManager.checkGlobalFlag(agentShutdownSignal))
+            break;
+            
+          // Start whatever agents need to be started
+          ManifoldCF.startAgents(tc);
+
+          try
+          {
+            ManifoldCF.sleep(5000);
+          }
+          catch (InterruptedException e)
+          {
+            break;
+          }
+        }
+      }
+      catch (ManifoldCFException e)
+      {
+        daemonException = e;
+      }
+      finally
+      {
+        try
+        {
+          ManifoldCF.stopAgents(tc);
+        }
+        catch (ManifoldCFException e)
+        {
+          daemonException = e;
+        }
+      }
+    }
+    
+    public Exception getDaemonException()
+    {
+      return daemonException;
+    }
+    
+  }
+
+}

Modified: incubator/lcf/branches/CONNECTORS-236/tests/pom.xml
URL: http://svn.apache.org/viewvc/incubator/lcf/branches/CONNECTORS-236/tests/pom.xml?rev=1153921&r1=1153920&r2=1153921&view=diff
==============================================================================
--- incubator/lcf/branches/CONNECTORS-236/tests/pom.xml (original)
+++ incubator/lcf/branches/CONNECTORS-236/tests/pom.xml Thu Aug  4 16:32:41 2011
@@ -33,6 +33,7 @@
   <packaging>pom</packaging>
 
   <modules>
+  	<module>cmis</module>
     <module>filesystem</module>
     <module>sharepoint</module>
   </modules>