View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.tck.tests.crud;
20  
21  import static org.apache.chemistry.opencmis.tck.CmisTestResultStatus.FAILURE;
22  import static org.apache.chemistry.opencmis.tck.CmisTestResultStatus.UNEXPECTED_EXCEPTION;
23  import static org.apache.chemistry.opencmis.tck.CmisTestResultStatus.WARNING;
24  
25  import java.io.ByteArrayInputStream;
26  import java.io.ByteArrayOutputStream;
27  import java.math.BigInteger;
28  import java.util.ArrayList;
29  import java.util.HashMap;
30  import java.util.List;
31  import java.util.Locale;
32  import java.util.Map;
33  import java.util.concurrent.Future;
34  
35  import org.apache.chemistry.opencmis.client.api.AsyncSession;
36  import org.apache.chemistry.opencmis.client.api.CmisObject;
37  import org.apache.chemistry.opencmis.client.api.Document;
38  import org.apache.chemistry.opencmis.client.api.Folder;
39  import org.apache.chemistry.opencmis.client.api.ItemIterable;
40  import org.apache.chemistry.opencmis.client.api.ObjectId;
41  import org.apache.chemistry.opencmis.client.api.Session;
42  import org.apache.chemistry.opencmis.client.runtime.async.AbstractExecutorServiceAsyncSession;
43  import org.apache.chemistry.opencmis.client.runtime.async.AsyncSessionFactoryImpl;
44  import org.apache.chemistry.opencmis.commons.PropertyIds;
45  import org.apache.chemistry.opencmis.commons.data.ContentStream;
46  import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
47  import org.apache.chemistry.opencmis.tck.CmisTestResult;
48  import org.apache.chemistry.opencmis.tck.impl.AbstractSessionTest;
49  
50  /**
51   * Simple document test.
52   */
53  public class AsyncCreateAndDeleteDocumentTest extends AbstractSessionTest {
54  
55      @Override
56      public void init(Map<String, String> parameters) {
57          super.init(parameters);
58          setName("Asynchronous Create and Delete Document Test");
59          setDescription("Creates documents in parallel, checks the newly created documents and finally deletes the created documents in parallel.");
60      }
61  
62      @Override
63      public void run(Session session) {
64          CmisTestResult f;
65  
66          int numOfDocuments = 100;
67          String mimeType = "text/plain";
68  
69          byte[] contentBytes = new byte[64 * 1024];
70          for (int i = 0; i < contentBytes.length; i++) {
71              contentBytes[i] = (byte) ('0' + i % 10);
72          }
73  
74          // create an async session
75          AsyncSession asyncSession = AsyncSessionFactoryImpl.newInstance().createAsyncSession(session, 10);
76  
77          // create a test folder
78          Folder testFolder = createTestFolder(session);
79  
80          try {
81              // create documents
82              List<Future<ObjectId>> docFutures = new ArrayList<Future<ObjectId>>();
83              for (int i = 0; i < numOfDocuments; i++) {
84                  String name = "asyncdoc" + i + ".txt";
85  
86                  Map<String, Object> properties = new HashMap<String, Object>();
87                  properties.put(PropertyIds.NAME, name);
88                  properties.put(PropertyIds.OBJECT_TYPE_ID, getDocumentTestTypeId());
89  
90                  ContentStream contentStream = new ContentStreamImpl(name, BigInteger.valueOf(contentBytes.length),
91                          mimeType, new ByteArrayInputStream(contentBytes));
92  
93                  Future<ObjectId> newDocument = asyncSession.createDocument(properties, testFolder, contentStream, null);
94  
95                  docFutures.add(newDocument);
96              }
97  
98              // wait for all document being created
99              List<ObjectId> docIds = new ArrayList<ObjectId>();
100             try {
101                 for (Future<ObjectId> docFuture : docFutures) {
102                     ObjectId id = docFuture.get();
103                     docIds.add(id);
104                 }
105             } catch (Exception e) {
106                 addResult(createResult(UNEXPECTED_EXCEPTION,
107                         "Documents could not been created! Exception: " + e.getMessage(), e, true));
108             }
109 
110             // check children of the test folder
111             int count = countChildren(testFolder);
112             f = createResult(FAILURE, "Test folder should have " + numOfDocuments + " children but has " + count + "!");
113             addResult(assertEquals(count, numOfDocuments, null, f));
114 
115             // simple children test
116             addResult(checkChildren(session, testFolder, "Test folder children check"));
117 
118             // get documents
119             Map<String, Future<CmisObject>> getObjectFutures = new HashMap<String, Future<CmisObject>>();
120             Map<String, Future<ContentStream>> contentStreamFutures = new HashMap<String, Future<ContentStream>>();
121             Map<String, ByteArrayOutputStream> content = new HashMap<String, ByteArrayOutputStream>();
122 
123             for (ObjectId docId : docIds) {
124                 Future<CmisObject> getObjectFuture = asyncSession.getObject(docId, SELECT_ALL_NO_CACHE_OC);
125                 getObjectFutures.put(docId.getId(), getObjectFuture);
126 
127                 ByteArrayOutputStream out = new ByteArrayOutputStream(contentBytes.length);
128                 content.put(docId.getId(), out);
129 
130                 Future<ContentStream> contentStreamFuture = asyncSession.storeContentStream(docId, out);
131                 contentStreamFutures.put(docId.getId(), contentStreamFuture);
132             }
133 
134             // wait for all document being fetched
135             try {
136                 for (Map.Entry<String, Future<CmisObject>> getObjectFuture : getObjectFutures.entrySet()) {
137                     CmisObject object = getObjectFuture.getValue().get();
138 
139                     f = createResult(FAILURE, "Fetching document failed!");
140                     addResult(assertIsTrue(object instanceof Document, null, f));
141 
142                     if (object != null) {
143                         f = createResult(FAILURE, "Fetched wrong document!");
144                         addResult(assertEquals(getObjectFuture.getKey(), object.getId(), null, f));
145                     }
146                 }
147             } catch (Exception e) {
148                 addResult(createResult(UNEXPECTED_EXCEPTION,
149                         "Documents could not been fetched! Exception: " + e.getMessage(), e, true));
150             }
151 
152             // wait for all document content being fetched
153             try {
154                 for (Map.Entry<String, Future<ContentStream>> contentStreamFuture : contentStreamFutures.entrySet()) {
155                     ContentStream contentStream = contentStreamFuture.getValue().get();
156 
157                     f = createResult(FAILURE, "Fetching document content failed!");
158                     addResult(assertNotNull(contentStream, null, f));
159 
160                     if (contentStream != null) {
161                         if (contentStream.getMimeType() == null) {
162                             addResult(createResult(FAILURE, "Content MIME type is null!"));
163                         } else {
164                             f = createResult(WARNING, "Content MIME types don't match!");
165                             addResult(assertIsTrue(contentStream.getMimeType().trim().toLowerCase(Locale.ENGLISH)
166                                     .startsWith(mimeType.toLowerCase(Locale.ENGLISH)), null, f));
167                         }
168                     }
169 
170                     ByteArrayOutputStream out = content.get(contentStreamFuture.getKey());
171                     byte[] readBytes = out.toByteArray();
172 
173                     f = createResult(FAILURE, "Read content length doesn't match document content length!");
174                     addResult(assertEquals(contentBytes.length, readBytes.length, null, f));
175 
176                     f = createResult(FAILURE, "Read content doesn't match document content!");
177                     addResult(assertEqualArray(contentBytes, readBytes, null, f));
178                 }
179             } catch (Exception e) {
180                 addResult(createResult(UNEXPECTED_EXCEPTION,
181                         "Document content could not been fetched! Exception: " + e.getMessage(), e, true));
182             }
183 
184             // delete documents
185             List<Future<?>> delFutures = new ArrayList<Future<?>>();
186             for (ObjectId docId : docIds) {
187                 Future<?> delFuture = asyncSession.delete(docId);
188                 delFutures.add(delFuture);
189             }
190 
191             // wait for all document being deleted
192             try {
193                 for (Future<?> delFuture : delFutures) {
194                     delFuture.get();
195                 }
196             } catch (Exception e) {
197                 addResult(createResult(UNEXPECTED_EXCEPTION,
198                         "Documents could not been deleted! Exception: " + e.getMessage(), e, true));
199             }
200 
201             // check children of the test folder
202             count = countChildren(testFolder);
203             f = createResult(FAILURE, "Test folder should be empty but has " + count + " children!");
204             addResult(assertEquals(count, 0, null, f));
205         } finally {
206             // delete the test folder
207             deleteTestFolder();
208 
209             if (asyncSession instanceof AbstractExecutorServiceAsyncSession<?>) {
210                 ((AbstractExecutorServiceAsyncSession<?>) asyncSession).shutdown();
211             }
212         }
213 
214         addResult(createInfoResult("Tested the parallel creation and deletion of " + numOfDocuments + " documents."));
215     }
216 
217     private int countChildren(Folder folder) {
218         int count = 0;
219         ItemIterable<CmisObject> children = folder.getChildren(SELECT_ALL_NO_CACHE_OC);
220         for (CmisObject child : children) {
221             if (child instanceof Document) {
222                 count++;
223             }
224         }
225 
226         return count;
227     }
228 }