| /* |
| * |
| * 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.chemistry.opencmis.inmemory; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.chemistry.opencmis.client.bindings.CmisBindingFactory; |
| import org.apache.chemistry.opencmis.commons.PropertyIds; |
| import org.apache.chemistry.opencmis.commons.SessionParameter; |
| import org.apache.chemistry.opencmis.commons.data.Acl; |
| import org.apache.chemistry.opencmis.commons.data.ContentStream; |
| import org.apache.chemistry.opencmis.commons.data.ExtensionsData; |
| import org.apache.chemistry.opencmis.commons.data.ObjectData; |
| import org.apache.chemistry.opencmis.commons.data.ObjectParentData; |
| import org.apache.chemistry.opencmis.commons.data.Properties; |
| import org.apache.chemistry.opencmis.commons.data.PropertyData; |
| import org.apache.chemistry.opencmis.commons.data.RepositoryInfo; |
| import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships; |
| import org.apache.chemistry.opencmis.commons.enums.VersioningState; |
| import org.apache.chemistry.opencmis.commons.impl.dataobjects.BindingsObjectFactoryImpl; |
| import org.apache.chemistry.opencmis.commons.server.CallContext; |
| import org.apache.chemistry.opencmis.commons.spi.AclService; |
| import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory; |
| import org.apache.chemistry.opencmis.commons.spi.CmisBinding; |
| import org.apache.chemistry.opencmis.commons.spi.DiscoveryService; |
| import org.apache.chemistry.opencmis.commons.spi.MultiFilingService; |
| import org.apache.chemistry.opencmis.commons.spi.NavigationService; |
| import org.apache.chemistry.opencmis.commons.spi.ObjectService; |
| import org.apache.chemistry.opencmis.commons.spi.PolicyService; |
| import org.apache.chemistry.opencmis.commons.spi.RelationshipService; |
| import org.apache.chemistry.opencmis.commons.spi.RepositoryService; |
| import org.apache.chemistry.opencmis.commons.spi.VersioningService; |
| import org.apache.chemistry.opencmis.inmemory.server.InMemoryServiceFactoryImpl; |
| import org.apache.chemistry.opencmis.inmemory.storedobj.impl.ContentStreamDataImpl; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| public class AbstractServiceTest { |
| |
| private static final Logger LOG = LoggerFactory.getLogger(AbstractServiceTest.class); |
| |
| protected static final String REPOSITORY_ID = "UnitTestRepository"; |
| protected BindingsObjectFactory fFactory = new BindingsObjectFactoryImpl(); |
| protected String fRootFolderId; |
| protected String fRepositoryId; |
| protected ObjectService fObjSvc; |
| protected NavigationService fNavSvc; |
| protected RepositoryService fRepSvc; |
| protected VersioningService fVerSvc; |
| protected MultiFilingService fMultiSvc; |
| protected DiscoveryService fDiscSvc; |
| protected AclService fAclSvc; |
| protected RelationshipService fRelSvc; |
| protected PolicyService fPolSvc; |
| |
| protected CallContext fTestCallContext; |
| private String fTypeCreatorClassName; |
| private CmisBinding binding; |
| |
| public AbstractServiceTest() { |
| // The in-memory server unit tests can either be run directly against |
| // the |
| // service implementation or against a clocal binding interface. The |
| // local |
| // binding interfaces offers some benefits like type system caching etc. |
| // The default is using the direct implementation. Subclasses may |
| // override this behavior. |
| |
| // Init with default types, can be overridden by subclasses: |
| fTypeCreatorClassName = UnitTestTypeSystemCreator.class.getName(); |
| } |
| |
| // Subclasses may want to use their own types |
| protected void setTypeCreatorClass(String typeCreatorClassName) { |
| fTypeCreatorClassName = typeCreatorClassName; |
| } |
| |
| protected String getTypeCreatorClass() { |
| return fTypeCreatorClassName; |
| } |
| |
| protected void setUp() { |
| LOG.debug("Initializing InMemory Test with type creator class: " + fTypeCreatorClassName); |
| Map<String, String> parameters = new HashMap<String, String>(); |
| |
| // attach repository info to the session: |
| parameters.put(ConfigConstants.TYPE_CREATOR_CLASS, fTypeCreatorClassName); |
| parameters.put(ConfigConstants.REPOSITORY_ID, REPOSITORY_ID); |
| |
| // give subclasses a chance to provide additional parameters for special |
| // tests |
| addParameters(parameters); |
| |
| fTestCallContext = new DummyCallContext(); |
| // Attach a standard CallContext to a thread before the services are |
| // initialized. |
| // RuntimeContext.attachCfg(fTestCallContext); |
| |
| initializeUsingLocalBinding(parameters); |
| |
| assertNotNull(fRepSvc); |
| assertNotNull(fObjSvc); |
| assertNotNull(fNavSvc); |
| |
| RepositoryInfo rep = fRepSvc.getRepositoryInfo(REPOSITORY_ID, null); |
| fRootFolderId = rep.getRootFolderId(); |
| fRepositoryId = rep.getId(); |
| |
| assertNotNull(fRepositoryId); |
| assertNotNull(fRootFolderId); |
| } |
| |
| // Override this method in subclasses if you want to provide additional |
| // configuration |
| // parameters. Default implementation is empty |
| protected void addParameters(Map<String, String> parameters) { |
| } |
| |
| protected void tearDown() { |
| LOG.debug("Close local binding."); |
| binding.close(); |
| LOG.debug("Local binding closed."); |
| } |
| |
| public void testDummy() { |
| // dummy test to make tools happy that complain if there are no tests |
| // available in a test class |
| } |
| |
| protected String createFolder(String folderName, String parentFolderId, String typeId) { |
| String id = null; |
| try { |
| id = createFolderNoCatch(folderName, parentFolderId, typeId); |
| if (null == id) { |
| fail("createFolder failed."); |
| } |
| } catch (Exception e) { |
| fail("createFolder() failed with exception: " + e); |
| } |
| return id; |
| } |
| |
| protected String createFolderNoCatch(String folderName, String parentFolderId, String typeId) { |
| return createFolderNoCatch(folderName, parentFolderId, typeId, null, null); |
| } |
| |
| protected String createFolderNoCatch(String folderName, String parentFolderId, String typeId, Acl addACEs, |
| Acl removeACEs) { |
| Properties props = createFolderProperties(folderName, typeId); |
| String id = fObjSvc.createFolder(fRepositoryId, props, parentFolderId, null, addACEs, removeACEs, null); |
| return id; |
| } |
| |
| protected String createDocumentNoCatch(String name, String folderId, String typeId, |
| VersioningState versioningState, boolean withContent) { |
| return createDocumentNoCatch(name, folderId, typeId, versioningState, withContent, null, null); |
| } |
| |
| protected String createDocumentNoCatch(String name, String folderId, String typeId, |
| VersioningState versioningState, boolean withContent, Acl addACEs, Acl removeACEs) { |
| ContentStream contentStream = null; |
| List<String> policies = null; |
| ExtensionsData extension = null; |
| |
| Properties props = createDocumentProperties(name, typeId); |
| |
| if (withContent) { |
| contentStream = createContent(); |
| } |
| |
| String id = fObjSvc.createDocument(fRepositoryId, props, folderId, contentStream, versioningState, policies, |
| addACEs, removeACEs, extension); |
| return id; |
| } |
| |
| protected String createDocument(String name, String folderId, String typeId, VersioningState versioningState, |
| boolean withContent) { |
| String id = null; |
| try { |
| id = createDocumentNoCatch(name, folderId, typeId, versioningState, withContent); |
| if (null == id) { |
| fail("createDocument failed."); |
| } |
| } catch (Exception e) { |
| fail("createDocument() failed with exception: " + e); |
| } |
| return id; |
| } |
| |
| protected String createDocument(String name, String folderId, String typeId, boolean withContent) { |
| VersioningState versioningState = VersioningState.NONE; |
| return createDocument(name, folderId, typeId, versioningState, withContent); |
| } |
| |
| protected Properties createDocumentProperties(String name, String typeId) { |
| List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>(); |
| properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, name)); |
| properties.add(fFactory.createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, typeId)); |
| Properties props = fFactory.createPropertiesData(properties); |
| return props; |
| } |
| |
| protected Properties createFolderProperties(String folderName, String typeId) { |
| List<PropertyData<?>> properties = new ArrayList<PropertyData<?>>(); |
| properties.add(fFactory.createPropertyIdData(PropertyIds.NAME, folderName)); |
| properties.add(fFactory.createPropertyIdData(PropertyIds.OBJECT_TYPE_ID, typeId)); |
| Properties props = fFactory.createPropertiesData(properties); |
| return props; |
| } |
| |
| protected ContentStream createContent() { |
| return createContent(32); |
| } |
| |
| protected ContentStream createContent(int sizeInKB) { |
| return createContent(sizeInKB, 0, null); |
| } |
| |
| protected ContentStream createContent(int sizeInKB, long maxSizeInKB, String mimeType) { |
| ContentStreamDataImpl content = new ContentStreamDataImpl(maxSizeInKB); |
| content.setFileName("data.txt"); |
| |
| if (null == mimeType) { |
| content.setMimeType("text/plain"); |
| } else { |
| content.setMimeType(mimeType); |
| } |
| int len = sizeInKB * 1024; |
| byte[] b = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x0c, 0x0a, |
| 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x0c, 0x0a }; // 32 |
| int noBlocks = len / b.length; |
| |
| ByteArrayOutputStream ba = new ByteArrayOutputStream(len); |
| try { |
| for (int i = 0; i < noBlocks; i++) { |
| ba.write(b); |
| } |
| content.setContent(new ByteArrayInputStream(ba.toByteArray())); |
| } catch (IOException e) { |
| throw new RuntimeException("Failed to fill content stream with data", e); |
| } |
| return content; |
| } |
| |
| protected ContentStream createContent(char ch) { |
| ContentStreamDataImpl content = new ContentStreamDataImpl(0); |
| content.setFileName("data.txt"); |
| content.setMimeType("text/plain"); |
| int len = 32 * 1024; |
| byte[] b = new byte[32]; |
| for (int i = 0; i < 32; i++) { |
| b[i] = (byte) Character.getNumericValue(ch); |
| } |
| ByteArrayOutputStream ba = new ByteArrayOutputStream(len); |
| try { |
| for (int i = 0; i < 1024; i++) { |
| ba.write(b); |
| } |
| content.setContent(new ByteArrayInputStream(ba.toByteArray())); |
| } catch (IOException e) { |
| throw new RuntimeException("Failed to fill content stream with data", e); |
| } |
| return content; |
| } |
| |
| protected void verifyContentResult(ContentStream sd) { |
| verifyContentResult(sd, 32); |
| } |
| |
| protected void verifyContentResult(ContentStream sd, int sizeInK) { |
| assertEquals("text/plain", sd.getMimeType()); |
| assertEquals("data.txt", sd.getFileName()); |
| assertEquals(sizeInK * 1024, sd.getBigLength().longValue()); |
| byte[] ba = new byte[32]; |
| InputStream is = sd.getStream(); |
| int counter = 0; |
| try { |
| while (is.read(ba) == ba.length) { |
| ++counter; |
| assertEquals(0x61, ba[0]); |
| assertEquals(0x6e, ba[29]); |
| assertEquals(0x0c, ba[30]); |
| assertEquals(0x0a, ba[31]); |
| } |
| } catch (IOException e) { |
| fail("reading from content stream failed"); |
| } |
| assertEquals(sizeInK * 1024 / 32, counter); |
| } |
| |
| protected String getByPath(String id, String path) { |
| ObjectData res = null; |
| try { |
| res = fObjSvc.getObjectByPath(fRepositoryId, path, "*", false, IncludeRelationships.NONE, null, false, |
| false, null); |
| assertNotNull(res); |
| assertEquals(id, res.getId()); |
| } catch (Exception e) { |
| fail("getObject() failed with exception: " + e); |
| } |
| return res.getId(); |
| } |
| |
| @SuppressWarnings("unchecked") |
| protected String getPathOfFolder(String id) { |
| String path = null; |
| try { |
| String filter = PropertyIds.PATH; |
| Properties res = fObjSvc.getProperties(fRepositoryId, id, filter, null); |
| assertNotNull(res); |
| PropertyData<String> pd = (PropertyData<String>) res.getProperties().get(PropertyIds.PATH); |
| assertNotNull(pd); |
| path = pd.getFirstValue(); |
| assertNotNull(path); |
| } catch (Exception e) { |
| fail("getProperties() failed with exception: " + e); |
| } |
| return path; |
| } |
| |
| @SuppressWarnings("unchecked") |
| protected String getPathOfDocument(String id) { |
| String path = null; |
| String filter = "*"; |
| List<ObjectParentData> parentData = fNavSvc.getObjectParents(fRepositoryId, id, filter, false, |
| IncludeRelationships.NONE, null, true, null); |
| String name = parentData.get(0).getRelativePathSegment(); |
| PropertyData<String> pd = (PropertyData<String>) parentData.get(0).getObject().getProperties().getProperties() |
| .get(PropertyIds.PATH); |
| assertNotNull(pd); |
| path = pd.getFirstValue() + "/" + name; |
| return path; |
| } |
| |
| protected ObjectData getDocumentObjectData(String id) { |
| ObjectData res = null; |
| try { |
| String returnedId = null; |
| res = fObjSvc.getObject(fRepositoryId, id, "*", false, IncludeRelationships.NONE, null, false, false, null); |
| assertNotNull(res); |
| returnedId = res.getId(); |
| testReturnedProperties(returnedId, res.getProperties().getProperties()); |
| assertEquals(id, returnedId); |
| } catch (Exception e) { |
| fail("getObject() failed with exception: " + e); |
| } |
| return res; |
| } |
| |
| protected String getDocument(String id) { |
| ObjectData res = getDocumentObjectData(id); |
| assertNotNull(res); |
| return res.getId(); |
| } |
| |
| protected void testReturnedProperties(String objectId, Map<String, PropertyData<?>> props) { |
| for (PropertyData<?> pd : props.values()) { |
| LOG.debug("return property id: " + pd.getId() + ", value: " + pd.getValues()); |
| } |
| |
| PropertyData<?> pd = props.get(PropertyIds.OBJECT_ID); |
| assertNotNull(pd); |
| assertEquals(objectId, pd.getFirstValue()); |
| } |
| |
| /** |
| * Instantiates the services by using the client provider interface. |
| * |
| * @param parameters |
| * configuration parameters for client provider interface and |
| * in-memory provider |
| */ |
| protected void initializeUsingLocalBinding(Map<String, String> parameters) { |
| |
| LOG.info("Initialize unit test using the local binding interface."); |
| |
| // add parameters for local binding: |
| parameters.put(SessionParameter.BINDING_SPI_CLASS, SessionParameter.LOCAL_FACTORY); |
| parameters.put(SessionParameter.LOCAL_FACTORY, InMemoryServiceFactoryImpl.class.getName()); |
| parameters.put(ConfigConstants.OVERRIDE_CALL_CONTEXT, "true"); |
| InMemoryServiceFactoryImpl.setOverrideCallContext(fTestCallContext); |
| |
| // get factory and create binding |
| CmisBindingFactory factory = CmisBindingFactory.newInstance(); |
| binding = factory.createCmisLocalBinding(parameters); |
| assertNotNull(binding); |
| fFactory = binding.getObjectFactory(); |
| fRepSvc = binding.getRepositoryService(); |
| fObjSvc = binding.getObjectService(); |
| fNavSvc = binding.getNavigationService(); |
| fVerSvc = binding.getVersioningService(); |
| fMultiSvc = binding.getMultiFilingService(); |
| fDiscSvc = binding.getDiscoveryService(); |
| fAclSvc = binding.getAclService(); |
| fRelSvc = binding.getRelationshipService(); |
| fPolSvc = binding.getPolicyService(); |
| } |
| |
| protected String getStringProperty(ObjectData objData, String propertyKey) { |
| PropertyData<? extends Object> pd = objData.getProperties().getProperties().get(PropertyIds.PATH); |
| assertNotNull(pd.getFirstValue()); |
| assertTrue(pd.getFirstValue() instanceof String); |
| return (String) pd.getFirstValue(); |
| } |
| |
| protected void deleteDocument(String docId) { |
| fObjSvc.deleteObject(fRepositoryId, docId, true, null); |
| } |
| |
| } |