/* * Copyright (C) 2009 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.services.jcr.webdav.command; import org.exoplatform.common.http.HTTPStatus; import org.exoplatform.services.jcr.webdav.BaseStandaloneTest; import org.exoplatform.services.jcr.webdav.WebDavConstants.WebDAVMethods; import org.exoplatform.services.jcr.webdav.command.LockCommand.LockResultResponseEntity; import org.exoplatform.services.jcr.webdav.util.TextUtil; import org.exoplatform.services.jcr.webdav.utils.TestUtils; import org.exoplatform.services.rest.ExtHttpHeaders; import org.exoplatform.services.rest.impl.ContainerResponse; import org.exoplatform.services.rest.impl.MultivaluedMapImpl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import javax.jcr.Node; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; /** * Created by The eXo Platform SAS. <br> * Date: 10 Dec 2008 * * @author <a href="dkatayev@gmail.com">Dmytro Katayev</a> * @version $Id: TestLock.java */ public class TestLock extends BaseStandaloneTest { private String path = TestUtils.getFileName(); private String fileContent = TestUtils.getFileContent(); private String lockRequestBody = "<D:lockinfo xmlns:D='DAV:'>" + "<D:lockscope>" + "<D:exclusive/>" + "</D:lockscope>" + "<D:locktype>" + "<D:write/>" + "</D:locktype>" + "<D:owner>" + "<D:href>testOwner</D:href>" + "</D:owner>" + "</D:lockinfo>"; @Override public void setUp() throws Exception { super.setUp(); session.getRootNode().addNode(TextUtil.relativizePath(path)); InputStream inputStream = new ByteArrayInputStream(fileContent.getBytes()); TestUtils.addContent(session, path, inputStream, defaultFileNodeType, ""); path = path + "[2]"; } /** * Testing Lock method. Firstly lock existing node via webdav LOCK method and check for correct response status. * Secondly check if the node is locked indeed via webdav DELETE method (no delete or any other operation cannot * be performed with locked node). The response status must be LOCKED. * @throws Exception */ public void testLock() throws Exception { testLock(getPathWS()); } /** * Same test as the previous one but with a path of the workspace containing * an incorrect repository name. The behavior should not change as we ignore it and use * the current repository. */ public void testLockWithFakePathWS() throws Exception { testLock(getFakePathWS()); } /** * Testing Lock method. Firstly lock existing node via webdav LOCK method and check for correct response status. * Secondly check if the node is locked indeed via webdav DELETE method (no delete or any other operation cannot * be performed with locked node). The response status must be LOCKED. * @param pathWs path of the workspace * @throws Exception */ private void testLock(String pathWs) throws Exception { MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(ExtHttpHeaders.CONTENTTYPE, MediaType.TEXT_PLAIN); ContainerResponse containerResponse = serviceWithEscape(WebDAVMethods.LOCK, pathWs + path, "", headers, lockRequestBody.getBytes()); assertEquals(HTTPStatus.OK, containerResponse.getStatus()); // some manipulation to serialize response entity ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); LockResultResponseEntity entity = (LockResultResponseEntity)containerResponse.getEntity(); entity.write(outputStream); containerResponse = serviceWithEscape("DELETE", pathWs + path, "", null, null); assertEquals(HTTPStatus.LOCKED, containerResponse.getStatus()); assertTrue(session.getRootNode().getNode(TextUtil.relativizePath(path)).isLocked()); // here we're unlocking a node, to use it in other tests // firstly get lock-token from response entity String lockToken = outputStream.toString(); lockToken = lockToken.substring(lockToken.indexOf(">opaquelocktoken:")); lockToken = lockToken.substring(lockToken.indexOf(":") + 1, lockToken.indexOf("<")); // secondly add lock-token to current session and unlock the node session.addLockToken(lockToken); ((Node)session.getItem(path)).unlock(); } /** * Testing lock refreshing. Firstly we lock the node. Secondly we refresh the lock * via webdav LOCK method with no body. In both cases OK webdav status must be returned. * @throws Exception */ public void testLockRefresh() throws Exception { MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add("Content-Type", MediaType.TEXT_PLAIN); ContainerResponse containerResponse = serviceWithEscape(WebDAVMethods.LOCK, getPathWS() + path, "", headers, lockRequestBody.getBytes()); assertEquals(HTTPStatus.OK, containerResponse.getStatus()); // get lock-token from response body // some manipulation to serialize response entity ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); LockResultResponseEntity entity = (LockResultResponseEntity)containerResponse.getEntity(); entity.write(outputStream); String lockToken = outputStream.toString(); lockToken = lockToken.substring(lockToken.indexOf(">opaquelocktoken:")); lockToken = lockToken.substring(lockToken.indexOf(":") + 1, lockToken.indexOf("<")); //prepare to send lock refresh request headers = new MultivaluedMapImpl(); headers.add(ExtHttpHeaders.CONTENTTYPE, MediaType.TEXT_PLAIN); headers.add(ExtHttpHeaders.LOCKTOKEN, lockToken); containerResponse = serviceWithEscape(WebDAVMethods.LOCK, getPathWS() + path, "", headers, null); assertEquals(HTTPStatus.OK, containerResponse.getStatus()); // some manipulation to serialize response entity outputStream = new ByteArrayOutputStream(); entity = (LockResultResponseEntity)containerResponse.getEntity(); entity.write(outputStream); // add lock-token to current session and unlock the node session.addLockToken(lockToken); ((Node)session.getItem(path)).unlock(); } /** * Testing trying to lock already locked node. Firstly we lock the node. Secondly we send webdav LOCK * request with request body (because in case the body is empty the LOCK request should refresh already * existing lock) to try to lock previously locked node. LOCKED webdav status must be returned. * @throws Exception */ public void testAlreadyLocked() throws Exception { MultivaluedMap<String, String> headers = new MultivaluedMapImpl(); headers.add(ExtHttpHeaders.CONTENTTYPE, MediaType.TEXT_PLAIN); ContainerResponse containerResponse = serviceWithEscape(WebDAVMethods.LOCK, getPathWS() + path, "", headers, lockRequestBody.getBytes()); assertEquals(HTTPStatus.OK, containerResponse.getStatus()); // some manipulation to serialize response entity ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); LockResultResponseEntity entity = (LockResultResponseEntity)containerResponse.getEntity(); entity.write(outputStream); String lockToken = outputStream.toString(); lockToken = lockToken.substring(lockToken.indexOf(">opaquelocktoken:")); lockToken = lockToken.substring(lockToken.indexOf(":") + 1, lockToken.indexOf("<")); // prepare to send lock request headers = new MultivaluedMapImpl(); headers.add(ExtHttpHeaders.CONTENTTYPE, MediaType.TEXT_PLAIN); containerResponse = serviceWithEscape(WebDAVMethods.LOCK, getPathWS() + path, "", headers, lockRequestBody.getBytes()); assertEquals(HTTPStatus.LOCKED, containerResponse.getStatus()); // add lock-token to current session and unlock the node session.addLockToken(lockToken); ((Node)session.getItem(path)).unlock(); } /** * Here we're testing the case when we are trying to lock a resource C at a path /A/B/C * and a A collection does not exist. According to the <a href=http://www.webdav.org/specs/rfc4918.html> * RFC 4918</a> section we are to receive 409(conflict) HTTP status. * @throws Exception */ public void testLockForNonExistingWorkspace() throws Exception { ContainerResponse response = serviceWithEscape(WebDAVMethods.LOCK, getPathWS() + "_" + path, "", null, lockRequestBody.getBytes()); assertEquals(HTTPStatus.CONFLICT, response.getStatus()); } @Override protected String getRepositoryName() { return null; } }