This project has retired. For details please refer to its Attic page.
AbstractServiceTest xref

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   *
20   */
21  package org.apache.chemistry.opencmis.inmemory;
22  
23  import static org.junit.Assert.assertEquals;
24  import static org.junit.Assert.assertNotNull;
25  import static org.junit.Assert.assertTrue;
26  import static org.junit.Assert.fail;
27  
28  import java.io.ByteArrayInputStream;
29  import java.io.ByteArrayOutputStream;
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.util.ArrayList;
33  import java.util.HashMap;
34  import java.util.List;
35  import java.util.Map;
36  
37  import org.apache.chemistry.opencmis.client.bindings.CmisBindingFactory;
38  import org.apache.chemistry.opencmis.commons.PropertyIds;
39  import org.apache.chemistry.opencmis.commons.SessionParameter;
40  import org.apache.chemistry.opencmis.commons.data.Acl;
41  import org.apache.chemistry.opencmis.commons.data.ContentStream;
42  import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
43  import org.apache.chemistry.opencmis.commons.data.ObjectData;
44  import org.apache.chemistry.opencmis.commons.data.ObjectParentData;
45  import org.apache.chemistry.opencmis.commons.data.Properties;
46  import org.apache.chemistry.opencmis.commons.data.PropertyData;
47  import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
48  import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
49  import org.apache.chemistry.opencmis.commons.enums.VersioningState;
50  import org.apache.chemistry.opencmis.commons.impl.dataobjects.BindingsObjectFactoryImpl;
51  import org.apache.chemistry.opencmis.commons.server.CallContext;
52  import org.apache.chemistry.opencmis.commons.spi.AclService;
53  import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory;
54  import org.apache.chemistry.opencmis.commons.spi.CmisBinding;
55  import org.apache.chemistry.opencmis.commons.spi.DiscoveryService;
56  import org.apache.chemistry.opencmis.commons.spi.MultiFilingService;
57  import org.apache.chemistry.opencmis.commons.spi.NavigationService;
58  import org.apache.chemistry.opencmis.commons.spi.ObjectService;
59  import org.apache.chemistry.opencmis.commons.spi.RepositoryService;
60  import org.apache.chemistry.opencmis.commons.spi.VersioningService;
61  import org.apache.chemistry.opencmis.inmemory.server.InMemoryServiceFactoryImpl;
62  import org.apache.chemistry.opencmis.inmemory.storedobj.impl.ContentStreamDataImpl;
63  import org.apache.commons.logging.Log;
64  import org.apache.commons.logging.LogFactory;
65  
66  public class AbstractServiceTest {
67  
68      private static final Log LOG = LogFactory.getLog(AbstractServiceTest.class);
69  
70      protected static final String REPOSITORY_ID = "UnitTestRepository";
71      protected BindingsObjectFactory fFactory = new BindingsObjectFactoryImpl();
72      protected String fRootFolderId;
73      protected String fRepositoryId;
74      protected ObjectService fObjSvc;
75      protected NavigationService fNavSvc;
76      protected RepositoryService fRepSvc;
77      protected VersioningService fVerSvc;
78      protected MultiFilingService fMultiSvc;
79      protected DiscoveryService fDiscSvc;
80      protected AclService fAclSvc;
81      protected CallContext fTestCallContext;
82      private String fTypeCreatorClassName;
83  
84      public AbstractServiceTest() {
85          // The in-memory server unit tests can either be run directly against
86          // the
87          // service implementation or against a clocal binding interface. The
88          // local
89          // binding interfaces offers some benefits like type system caching etc.
90          // The default is using the direct implementation. Subclasses may
91          // override this behavior.
92  
93          // Init with default types, can be overridden by subclasses:
94          fTypeCreatorClassName = UnitTestTypeSystemCreator.class.getName();
95      }
96  
97      // Subclasses may want to use their own types
98      protected void setTypeCreatorClass(String typeCreatorClassName) {
99          fTypeCreatorClassName = typeCreatorClassName;
100     }
101 
102     protected String getTypeCreatorClass() {
103         return fTypeCreatorClassName;
104     }
105 
106     protected void setUp() {
107         // super.setUp();
108         LOG.debug("Initializing InMemory Test with type creator class: " + fTypeCreatorClassName);
109         Map<String, String> parameters = new HashMap<String, String>();
110 
111         // attach repository info to the session:
112         parameters.put(ConfigConstants.TYPE_CREATOR_CLASS, fTypeCreatorClassName);
113         parameters.put(ConfigConstants.REPOSITORY_ID, REPOSITORY_ID);
114 
115         // give subclasses a chance to provide additional parameters for special
116         // tests
117         addParameters(parameters);
118 
119         fTestCallContext = new DummyCallContext();
120         // Attach a standard CallContext to a thread before the services are
121         // initialized.
122         // RuntimeContext.attachCfg(fTestCallContext);
123 
124         initializeUsingLocalBinding(parameters);
125 
126         assertNotNull(fRepSvc);
127         assertNotNull(fObjSvc);
128         assertNotNull(fNavSvc);
129 
130         RepositoryInfo rep = fRepSvc.getRepositoryInfo(REPOSITORY_ID, null);
131         fRootFolderId = rep.getRootFolderId();
132         fRepositoryId = rep.getId();
133 
134         assertNotNull(fRepositoryId);
135         assertNotNull(fRootFolderId);
136     }
137 
138     // Override this method in subclasses if you want to provide additional
139     // configuration
140     // parameters. Default implementation is empty
141     protected void addParameters(Map<String, String> parameters) {
142     }
143 
144     protected void tearDown() {
145         // super.tearDown();
146     }
147 
148     public void testDummy() {
149         // dummy test to make tools happy that complain if there are no tests
150         // available in a test class
151     }
152 
153     protected String createFolder(String folderName, String parentFolderId, String typeId) {
154         String id = null;
155         try {
156             id = createFolderNoCatch(folderName, parentFolderId, typeId);
157             if (null == id) {
158                 fail("createFolder failed.");
159             }
160         } catch (Exception e) {
161             fail("createFolder() failed with exception: " + e);
162         }
163         return id;
164     }
165 
166     protected String createFolderNoCatch(String folderName, String parentFolderId, String typeId) {
167         return createFolderNoCatch(folderName, parentFolderId, typeId, null, null);
168     }
169 
170     protected String createFolderNoCatch(String folderName, String parentFolderId, String typeId, Acl addACEs,
171             Acl removeACEs) {
172         Properties props = createFolderProperties(folderName, typeId);
173         String id = fObjSvc.createFolder(fRepositoryId, props, parentFolderId, null, addACEs, removeACEs, null);
174         return id;
175     }
176 
177     protected String createDocumentNoCatch(String name, String folderId, String typeId,
178             VersioningState versioningState, boolean withContent) {
179         return createDocumentNoCatch(name, folderId, typeId, versioningState, withContent, null, null);
180     }
181 
182     protected String createDocumentNoCatch(String name, String folderId, String typeId,
183             VersioningState versioningState, boolean withContent, Acl addACEs, Acl removeACEs) {
184         ContentStream contentStream = null;
185         List<String> policies = null;
186         ExtensionsData extension = null;
187 
188         Properties props = createDocumentProperties(name, typeId);
189 
190         if (withContent) {
191             contentStream = createContent();
192         }
193 
194         String id = fObjSvc.createDocument(fRepositoryId, props, folderId, contentStream, versioningState, policies,
195                 addACEs, removeACEs, extension);
196         return id;
197     }
198 
199     protected String createDocument(String name, String folderId, String typeId, VersioningState versioningState,
200             boolean withContent) {
201         String id = null;
202         try {
203             id = createDocumentNoCatch(name , folderId, typeId, versioningState, withContent);
204             if (null == id) {
205                 fail("createDocument failed.");
206             }
207         } catch (Exception e) {
208             fail("createDocument() failed with exception: " + e);
209         }
210         return id;
211     }
212 
213     protected String createDocument(String name, String folderId, String typeId, boolean withContent) {
214         VersioningState versioningState = VersioningState.NONE;
215         return createDocument(name, folderId, typeId, versioningState, withContent);
216     }
217 
218     protected Properties createDocumentProperties(String name, String typeId) {
219         List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
220         properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, name));
221         properties.add(fFactory.createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, typeId));
222         Properties props = fFactory.createPropertiesData(properties);
223         return props;
224     }
225 
226     protected Properties createFolderProperties(String folderName, String typeId) {
227         List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>();
228         properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, folderName));
229         properties.add(fFactory.createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, typeId));
230         Properties props = fFactory.createPropertiesData(properties);
231         return props;
232     }
233 
234     protected ContentStream createContent() {
235         return createContent(32);
236     }
237 
238     protected ContentStream createContent(int sizeInKB) {
239         return createContent(sizeInKB, 0);
240     }
241 
242     protected ContentStream createContent(int sizeInKB, long maxSizeInKB) {
243         ContentStreamDataImpl content = new ContentStreamDataImpl(maxSizeInKB);
244         content.setFileName("data.txt");
245         content.setMimeType("text/plain");
246         int len = sizeInKB * 1024;
247         byte[] b = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x0c, 0x0a,
248                 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x0c, 0x0a }; // 32
249         int noBlocks = len / b.length;
250 
251         ByteArrayOutputStream ba = new ByteArrayOutputStream(len);
252         try {
253             for (int i = 0; i < noBlocks; i++) {
254                 ba.write(b);
255             }
256             content.setContent(new ByteArrayInputStream(ba.toByteArray()));
257         } catch (IOException e) {
258             throw new RuntimeException("Failed to fill content stream with data", e);
259         }
260         return content;
261     }
262 
263     protected ContentStream createContent(char ch) {
264         ContentStreamDataImpl content = new ContentStreamDataImpl(0);
265         content.setFileName("data.txt");
266         content.setMimeType("text/plain");
267         int len = 32 * 1024;
268         byte[] b = new byte[32];
269         for (int i = 0; i < 32; i++) {
270             b[i] = (byte) Character.getNumericValue(ch);
271         }
272         ByteArrayOutputStream ba = new ByteArrayOutputStream(len);
273         try {
274             for (int i = 0; i < 1024; i++) {
275                 ba.write(b);
276             }
277             content.setContent(new ByteArrayInputStream(ba.toByteArray()));
278         } catch (IOException e) {
279             throw new RuntimeException("Failed to fill content stream with data", e);
280         }
281         return content;
282     }
283 
284     protected void verifyContentResult(ContentStream sd) {
285         assertEquals("text/plain", sd.getMimeType());
286         assertEquals("data.txt", sd.getFileName());
287         assertEquals(32 * 1024, sd.getBigLength().longValue());
288         byte[] ba = new byte[32];
289         InputStream is = sd.getStream();
290         int counter = 0;
291         try {
292             while (is.read(ba) == ba.length) {
293                 ++counter;
294                 assertEquals(0x61, ba[0]);
295                 assertEquals(0x6e, ba[29]);
296                 assertEquals(0x0c, ba[30]);
297                 assertEquals(0x0a, ba[31]);
298             }
299         } catch (IOException e) {
300             fail("reading from content stream failed");
301         }
302         assertEquals(1024, counter);
303     }
304 
305     protected String getByPath(String id, String path) {
306         ObjectData res = null;
307         try {
308             res = fObjSvc.getObjectByPath(fRepositoryId, path, "*", false, IncludeRelationships.NONE, null, false,
309                     false, null);
310             assertNotNull(res);
311             assertEquals(id, res.getId());
312         } catch (Exception e) {
313             fail("getObject() failed with exception: " + e);
314         }
315         return res.getId();
316     }
317 
318     @SuppressWarnings("unchecked")
319     protected String getPathOfFolder(String id) {
320         String path = null;
321         try {
322             String filter = PropertyIds.PATH;
323             Properties res = fObjSvc.getProperties(fRepositoryId, id, filter, null);
324             assertNotNull(res);
325             PropertyData<String> pd = (PropertyData<String>) res.getProperties().get(PropertyIds.PATH);
326             assertNotNull(pd);
327             path = pd.getFirstValue();
328             assertNotNull(path);
329         } catch (Exception e) {
330             fail("getProperties() failed with exception: " + e);
331         }
332         return path;
333     }
334 
335     @SuppressWarnings("unchecked")
336     protected String getPathOfDocument(String id) {
337         String path = null;
338         String filter = "*";
339         List<ObjectParentData> parentData = fNavSvc.getObjectParents(fRepositoryId, id, filter, false,
340                 IncludeRelationships.NONE, null, true, null);
341         String name = parentData.get(0).getRelativePathSegment();
342         PropertyData<String> pd = (PropertyData<String>) parentData.get(0).getObject().getProperties().getProperties()
343                 .get(PropertyIds.PATH);
344         assertNotNull(pd);
345         path = pd.getFirstValue() + "/" + name;
346         return path;
347     }
348 
349     protected ObjectData getDocumentObjectData(String id) {
350         ObjectData res = null;
351         try {
352             String returnedId = null;
353             res = fObjSvc.getObject(fRepositoryId, id, "*", false, IncludeRelationships.NONE, null, false, false, null);
354             assertNotNull(res);
355             returnedId = res.getId();
356             testReturnedProperties(returnedId, res.getProperties().getProperties());
357             assertEquals(id, returnedId);
358         } catch (Exception e) {
359             fail("getObject() failed with exception: " + e);
360         }
361         return res;
362     }
363 
364     protected String getDocument(String id) {
365         ObjectData res = getDocumentObjectData(id);
366         assertNotNull(res);
367         return res.getId();
368     }
369 
370     protected void testReturnedProperties(String objectId, Map<String, PropertyData<?>> props) {
371         for (PropertyData<?> pd : props.values()) {
372             LOG.debug("return property id: " + pd.getId() + ", value: " + pd.getValues());
373         }
374 
375         PropertyData<?> pd = props.get(PropertyIds.OBJECT_ID);
376         assertNotNull(pd);
377         assertEquals(objectId, pd.getFirstValue());
378     }
379 
380      /**
381      * Instantiates the services by using the client provider interface.
382      *
383      * @param parameters
384      *            configuration parameters for client provider interface and
385      *            in-memory provider
386      */
387     protected void initializeUsingLocalBinding(Map<String, String> parameters) {
388 
389         LOG.info("Initialize unit test using the local binding interface.");
390 
391         // add parameters for local binding:
392         parameters.put(SessionParameter.BINDING_SPI_CLASS, SessionParameter.LOCAL_FACTORY);
393         parameters.put(SessionParameter.LOCAL_FACTORY, InMemoryServiceFactoryImpl.class.getName());
394         parameters.put(ConfigConstants.OVERRIDE_CALL_CONTEXT, "true");
395         InMemoryServiceFactoryImpl.setOverrideCallContext(fTestCallContext);
396 
397         // get factory and create binding
398         CmisBindingFactory factory = CmisBindingFactory.newInstance();
399         CmisBinding binding = factory.createCmisLocalBinding(parameters);
400         assertNotNull(binding);
401         fFactory = binding.getObjectFactory();
402         fRepSvc = binding.getRepositoryService();
403         fObjSvc = binding.getObjectService();
404         fNavSvc = binding.getNavigationService();
405         fVerSvc = binding.getVersioningService();
406         fMultiSvc = binding.getMultiFilingService();
407         fDiscSvc = binding.getDiscoveryService();
408         fAclSvc = binding.getAclService();
409     }
410 
411     protected String getStringProperty(ObjectData objData, String propertyKey) {
412         PropertyData<? extends Object> pd = (PropertyData<? extends Object>) objData.getProperties().getProperties()
413                 .get(PropertyIds.PATH);
414         assertNotNull(pd.getFirstValue());
415         assertTrue(pd.getFirstValue() instanceof String);
416         return (String) pd.getFirstValue();
417     }
418     
419     protected void deleteDocument(String docId) {
420         fObjSvc.deleteObject(fRepositoryId, docId, true, null);
421     }
422 
423 }