Java tutorial
/* * Copyright 2014 EMC Corporation. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://www.apache.org/licenses/LICENSE-2.0.txt * * or in the "license" file accompanying this file. This file 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 com.emc.esu.test; import com.emc.atmos.util.RandomInputStream; import com.emc.esu.api.*; import com.emc.esu.api.Checksum.Algorithm; import com.emc.esu.api.rest.DownloadHelper; import com.emc.esu.api.rest.UploadHelper; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.junit.After; import org.junit.Assert; import org.junit.Assume; import org.junit.Ignore; import org.junit.Test; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.net.URL; import java.net.URLEncoder; import java.util.*; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * Implements testcases that are independent of the protocol (REST vs. SOAP). * Note that this class does not implement TestCase; it is called by the * REST and SOAP testcases. */ @SuppressWarnings("deprecation") public abstract class EsuApiTest { public static Logger l4j = Logger.getLogger(EsuApiTest.class); /** * Use this as a prefix for namespace object paths and you won't have to clean up after yourself. * This also keeps all test objects under one folder, which is easy to delete should something go awry. */ protected static final String TEST_DIR_PREFIX = "/test_" + EsuApiTest.class.getSimpleName(); protected EsuApi esu; protected String uid; protected List<Identifier> cleanup = Collections.synchronizedList(new ArrayList<Identifier>()); protected List<ObjectPath> cleanupDirs = Collections.synchronizedList(new ArrayList<ObjectPath>()); protected boolean isVipr; /** * Tear down after a test is run. Cleans up objects that were created * during the test. Set cleanUp=false to disable this behavior. */ @After public void tearDown() { for (Identifier cleanItem : cleanup) { try { this.esu.deleteObject(cleanItem); } catch (Exception e) { System.out.println("Failed to delete " + cleanItem + ": " + e.getMessage()); } } try { // if test directories exists, recursively delete them for (ObjectPath testDir : cleanupDirs) { deleteRecursively(testDir); } } catch (EsuException e) { if (e.getHttpCode() != 404) { l4j.warn("Could not delete test dir: ", e); } } } protected void deleteRecursively(ObjectPath path) { if (path.isDirectory()) { for (DirectoryEntry entry : this.esu.listDirectory(path, null)) { deleteRecursively(entry.getPath()); } } this.esu.deleteObject(path); } protected ObjectPath createTestDir(String name) { if (!name.endsWith("/")) name = name + "/"; ObjectPath path = new ObjectPath(TEST_DIR_PREFIX + "_" + name); this.esu.createObjectOnPath(path, null, null, null, null); cleanupDirs.add(path); return path; } // // TESTS START HERE // @Test public void testUtf8JavaEncoding() throws Exception { String oneByteCharacters = "Hello"; String twoByteCharacters = "\u0410\u0411\u0412\u0413"; // Cyrillic letters String twoByteEscaped = "%D0%90%D0%91%D0%92%D0%93"; String fourByteCharacters = "\ud841\udf0e\ud841\udf31\ud841\udf79\ud843\udc53"; // Chinese symbols String fourByteEscaped = "%F0%A0%9C%8E%F0%A0%9C%B1%F0%A0%9D%B9%F0%A0%B1%93"; Assert.assertEquals("2-byte characters failed", URLEncoder.encode(twoByteCharacters, "UTF-8"), twoByteEscaped); Assert.assertEquals("4-byte characters failed", URLEncoder.encode(fourByteCharacters, "UTF-8"), fourByteEscaped); Assert.assertEquals("2-byte/4-byte mix failed", URLEncoder.encode(twoByteCharacters + fourByteCharacters, "UTF-8"), twoByteEscaped + fourByteEscaped); Assert.assertEquals("1-byte/2-byte mix failed", URLEncoder.encode(oneByteCharacters + twoByteCharacters, "UTF-8"), oneByteCharacters + twoByteEscaped); Assert.assertEquals("1-4 byte mix failed", URLEncoder.encode(oneByteCharacters + twoByteCharacters + fourByteCharacters, "UTF-8"), oneByteCharacters + twoByteEscaped + fourByteEscaped); } /** * Test creating one empty object. No metadata, no content. */ @Test public void testCreateEmptyObject() throws Exception { ObjectId id = this.esu.createObject(null, null, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read back the content String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "", content); } /** * Test creating one empty object on a path. No metadata, no content. */ @Test public void testCreateEmptyObjectOnPath() throws Exception { ObjectPath op = new ObjectPath("/" + rand8char()); ObjectId id = this.esu.createObjectOnPath(op, null, null, null, null); cleanup.add(op); l4j.debug("Path: " + op + " ID: " + id); Assert.assertNotNull(id); // Read back the content String content = new String(this.esu.readObject(op, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "", content); content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong when reading by id", "", content); } /** * Tests using some extended characters when creating on a path. This particular test * uses one cryllic, one accented, and one japanese character. */ @Test public void testUnicodePath() throws Exception { String dirName = rand8char(); ObjectPath path = new ObjectPath("/" + dirName + "/.txt"); ObjectId id = this.esu.createObjectOnPath(path, null, null, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); ObjectPath parent = new ObjectPath("/" + dirName + "/"); List<DirectoryEntry> ents = this.esu.listDirectory(parent, null); boolean found = false; for (DirectoryEntry ent : ents) { if (ent.getPath().equals(path)) { found = true; } } Assert.assertTrue("Did not find unicode file in dir", found); // Check read this.esu.readObject(path, null, null); } /** * Tests using some extra characters that might break URIs */ @Test public void testExtraPath() throws Exception { ObjectPath path = new ObjectPath("/" + rand8char() + "/a+=- _!#$%^&*(),.z.txt"); //ObjectPath path = new ObjectPath("/zimbramailbox/c8b4/511a-63c4-4ac9-8ff7+1c578de044be/stage/3r0sFrgUgL2ApCSkl3pobSX9D+k-1"); byte[] data = "Hello World".getBytes("UTF-8"); InputStream in = new ByteArrayInputStream(data); ObjectId id = this.esu.createObjectFromStreamOnPath(path, null, null, in, data.length, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); } @Test public void testUtf8Path() throws Exception { String oneByteCharacters = "Hello! ,"; String twoByteCharacters = "\u0410\u0411\u0412\u0413"; // Cyrillic letters String fourByteCharacters = "\ud841\udf0e\ud841\udf31\ud841\udf79\ud843\udc53"; // Chinese symbols String crazyName = oneByteCharacters + twoByteCharacters + fourByteCharacters; byte[] content = "Crazy name creation test.".getBytes("UTF-8"); ObjectPath parentDir = createTestDir("Utf8Path"); ObjectPath path = new ObjectPath(parentDir + crazyName); // create crazy-name object this.esu.createObjectOnPath(path, null, null, content, "text/plain"); cleanup.add(path); // verify name in directory list boolean found = false; for (DirectoryEntry entry : this.esu.listDirectory(parentDir, null)) { if (entry.getPath().toString().equals(path.toString())) { found = true; break; } } Assert.assertTrue("crazyName not found in directory listing", found); // verify content Assert.assertTrue("content does not match", Arrays.equals(content, this.esu.readObject(path, null, null))); } @Test public void testUtf8Content() throws Exception { String oneByteCharacters = "Hello! ,"; String twoByteCharacters = "\u0410\u0411\u0412\u0413"; // Cyrillic letters String fourByteCharacters = "\ud841\udf0e\ud841\udf31\ud841\udf79\ud843\udc53"; // Chinese symbols byte[] content = (oneByteCharacters + twoByteCharacters + fourByteCharacters).getBytes("UTF-8"); ObjectPath parentDir = createTestDir("Utf8Content"); ObjectPath path = new ObjectPath(parentDir.getName() + "/" + "utf8Content.txt"); // create object with multi-byte UTF-8 content this.esu.createObjectOnPath(path, null, null, content, "text/plain"); // verify content Assert.assertTrue("content does not match", Arrays.equals(content, this.esu.readObject(path, null, null))); } protected String rand8char() { Random r = new Random(); StringBuffer sb = new StringBuffer(8); for (int i = 0; i < 8; i++) { sb.append((char) ('a' + r.nextInt(26))); } return sb.toString(); } /** * Test creating an object with content but without metadata */ @Test public void testCreateObjectWithContent() throws Exception { ObjectId id = this.esu.createObject(null, null, "hello".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read back the content String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); } @Test public void testCreateObjectWithContentStream() throws Exception { InputStream in = new ByteArrayInputStream("hello".getBytes("UTF-8")); ObjectId id = this.esu.createObjectFromStream(null, null, in, 5, "text/plain"); in.close(); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read back the content String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); } @Test public void testCreateObjectWithContentStreamOnPath() throws Exception { ObjectPath op = new ObjectPath("/" + rand8char() + ".tmp"); InputStream in = new ByteArrayInputStream("hello".getBytes("UTF-8")); ObjectId id = this.esu.createObjectFromStreamOnPath(op, null, null, in, 5, "text/plain"); in.close(); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read back the content String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); } /** * Test creating an object with metadata but no content. */ @Test public void testCreateObjectWithMetadataOnPath() { ObjectPath op = new ObjectPath("/" + rand8char() + ".tmp"); MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObjectOnPath(op, null, mlist, null, null); //this.esu.updateObject( op, null, mlist, null, null, null ); Assert.assertNotNull("null ID returned", id); cleanup.add(op); // Read and validate the metadata MetadataList meta = this.esu.getUserMetadata(op, null); Assert.assertNotNull("value of 'listable' missing", meta.getMetadata("listable")); Assert.assertNotNull("value of 'listable2' missing", meta.getMetadata("listable2")); Assert.assertNotNull("value of 'unlistable' missing", meta.getMetadata("unlistable")); Assert.assertNotNull("value of 'unlistable2' missing", meta.getMetadata("unlistable2")); Assert.assertEquals("value of 'listable' wrong", "foo", meta.getMetadata("listable").getValue()); Assert.assertEquals("value of 'listable2' wrong", "foo2 foo2", meta.getMetadata("listable2").getValue()); Assert.assertEquals("value of 'unlistable' wrong", "bar", meta.getMetadata("unlistable").getValue()); Assert.assertEquals("value of 'unlistable2' wrong", "bar2 bar2", meta.getMetadata("unlistable2").getValue()); // Check listable flags Assert.assertEquals("'listable' is not listable", true, meta.getMetadata("listable").isListable()); Assert.assertEquals("'listable2' is not listable", true, meta.getMetadata("listable2").isListable()); Assert.assertEquals("'unlistable' is listable", false, meta.getMetadata("unlistable").isListable()); Assert.assertEquals("'unlistable2' is listable", false, meta.getMetadata("unlistable2").isListable()); } /** * Test creating an object with metadata but no content. */ @Test public void testCreateObjectWithMetadata() { MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); Metadata listable3 = new Metadata("listable3", null, true); Metadata quotes = new Metadata("ST_modalities", "\\US\\", false); //Metadata withCommas = new Metadata( "withcommas", "I, Robot", false ); //Metadata withEquals = new Metadata( "withequals", "name=value", false ); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); mlist.addMetadata(listable3); mlist.addMetadata(quotes); //mlist.addMetadata( withCommas ); //mlist.addMetadata( withEquals ); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read and validate the metadata MetadataList meta = this.esu.getUserMetadata(id, null); Assert.assertEquals("value of 'listable' wrong", "foo", meta.getMetadata("listable").getValue()); Assert.assertEquals("value of 'listable2' wrong", "foo2 foo2", meta.getMetadata("listable2").getValue()); Assert.assertEquals("value of 'unlistable' wrong", "bar", meta.getMetadata("unlistable").getValue()); Assert.assertEquals("value of 'unlistable2' wrong", "bar2 bar2", meta.getMetadata("unlistable2").getValue()); Assert.assertNotNull("listable3 missing", meta.getMetadata("listable3")); Assert.assertTrue("Value of listable3 should be empty", meta.getMetadata("listable3").getValue() == null || meta.getMetadata("listable3").getValue().length() == 0); //Assert.assertEquals( "Value of withcommas wrong", "I, Robot", meta.getMetadata( "withcommas" ).getValue() ); //Assert.assertEquals( "Value of withequals wrong", "name=value", meta.getMetadata( "withequals" ).getValue() ); // Check listable flags Assert.assertEquals("'listable' is not listable", true, meta.getMetadata("listable").isListable()); Assert.assertEquals("'listable2' is not listable", true, meta.getMetadata("listable2").isListable()); Assert.assertEquals("'listable3' is not listable", true, meta.getMetadata("listable3").isListable()); Assert.assertEquals("'unlistable' is listable", false, meta.getMetadata("unlistable").isListable()); Assert.assertEquals("'unlistable2' is listable", false, meta.getMetadata("unlistable2").isListable()); } /** * Test creating an object with metadata but no content. */ @Test public void testMetadataNormalizeSpace() { MetadataList mlist = new MetadataList(); Metadata unlistable = new Metadata("unlistable", "bar bar bar bar", false); Metadata leadingSpacesOdd = new Metadata("leadingodd", " spaces", false); Metadata trailingSpacesOdd = new Metadata("trailingodd", "spaces ", false); Metadata leadingSpacesEven = new Metadata("leadingeven", " SPACES", false); Metadata trailingSpacesEven = new Metadata("trailingeven", "spaces ", false); mlist.addMetadata(unlistable); mlist.addMetadata(leadingSpacesOdd); mlist.addMetadata(trailingSpacesOdd); mlist.addMetadata(leadingSpacesEven); mlist.addMetadata(trailingSpacesEven); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read and validate the metadata MetadataList meta = this.esu.getUserMetadata(id, null); Assert.assertEquals("value of 'unlistable' wrong", "bar bar bar bar", meta.getMetadata("unlistable").getValue()); // Check listable flags Assert.assertEquals("'unlistable' is listable", false, meta.getMetadata("unlistable").isListable()); } /** * Test reading an object's content */ @Test public void testReadObject() throws Exception { ObjectId id = this.esu.createObject(null, null, "hello".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read back the content String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); // Read back only 2 bytes Extent extent = new Extent(1, 2); content = new String(this.esu.readObject(id, extent, null), "UTF-8"); Assert.assertEquals("partial object content wrong", "el", content); } /** * Test reading an ACL back */ @Test public void testReadAcl() { // Create an object with an ACL Acl acl = new Acl(); acl.addGrant(new Grant(new Grantee(stripUid(uid), Grantee.GRANT_TYPE.USER), Permission.FULL_CONTROL)); acl.addGrant(new Grant(Grantee.OTHER, Permission.READ)); ObjectId id = this.esu.createObject(acl, null, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read back the ACL and make sure it matches Acl newacl = this.esu.getAcl(id); l4j.info("Comparing " + newacl + " with " + acl); Assert.assertEquals("ACLs don't match", acl, newacl); } /** * Inside an ACL, you use the UID only, not SubtenantID/UID * * @param uid * @return */ private String stripUid(String uid) { int slash = uid.indexOf('/'); if (slash != -1) { return uid.substring(slash + 1); } else { return uid; } } @Test public void testReadAclByPath() { ObjectPath op = new ObjectPath("/" + rand8char() + ".tmp"); // Create an object with an ACL Acl acl = new Acl(); acl.addGrant(new Grant(new Grantee(stripUid(uid), Grantee.GRANT_TYPE.USER), Permission.FULL_CONTROL)); acl.addGrant(new Grant(Grantee.OTHER, Permission.READ)); ObjectId id = this.esu.createObjectOnPath(op, acl, null, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(op); // Read back the ACL and make sure it matches Acl newacl = this.esu.getAcl(op); l4j.info("Comparing " + newacl + " with " + acl); Assert.assertEquals("ACLs don't match", acl, newacl); } /** * Test reading back user metadata */ @Test public void testGetUserMetadata() { // Create an object with user metadata MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read only part of the metadata MetadataTags mtags = new MetadataTags(); mtags.addTag(new MetadataTag("listable", true)); mtags.addTag(new MetadataTag("unlistable", false)); MetadataList meta = this.esu.getUserMetadata(id, mtags); Assert.assertEquals("value of 'listable' wrong", "foo", meta.getMetadata("listable").getValue()); Assert.assertNull("value of 'listable2' should not have been returned", meta.getMetadata("listable2")); Assert.assertEquals("value of 'unlistable' wrong", "bar", meta.getMetadata("unlistable").getValue()); Assert.assertNull("value of 'unlistable2' should not have been returned", meta.getMetadata("unlistable2")); } /** * Test deleting user metadata */ @Test public void testDeleteUserMetadata() { // Create an object with metadata MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Delete a couple of the metadata entries MetadataTags mtags = new MetadataTags(); mtags.addTag(new MetadataTag("listable2", true)); mtags.addTag(new MetadataTag("unlistable2", false)); this.esu.deleteUserMetadata(id, mtags); // Read back the metadata for the object and ensure the deleted // entries don't exist MetadataList meta = this.esu.getUserMetadata(id, null); Assert.assertEquals("value of 'listable' wrong", "foo", meta.getMetadata("listable").getValue()); Assert.assertNull("value of 'listable2' should not have been returned", meta.getMetadata("listable2")); Assert.assertEquals("value of 'unlistable' wrong", "bar", meta.getMetadata("unlistable").getValue()); Assert.assertNull("value of 'unlistable2' should not have been returned", meta.getMetadata("unlistable2")); } /** * Test creating object versions */ @Test public void testVersionObject() { Assume.assumeFalse(isVipr); // Create an object MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Version the object ObjectId vid = this.esu.versionObject(id); cleanup.add(vid); Assert.assertNotNull("null version ID returned", vid); Assert.assertFalse("Version ID shoudn't be same as original ID", id.equals(vid)); // Fetch the version and read its data MetadataList meta = this.esu.getUserMetadata(vid, null); Assert.assertEquals("value of 'listable' wrong", "foo", meta.getMetadata("listable").getValue()); Assert.assertEquals("value of 'listable2' wrong", "foo2 foo2", meta.getMetadata("listable2").getValue()); Assert.assertEquals("value of 'unlistable' wrong", "bar", meta.getMetadata("unlistable").getValue()); Assert.assertEquals("value of 'unlistable2' wrong", "bar2 bar2", meta.getMetadata("unlistable2").getValue()); } /** * Test listing the versions of an object */ @Test public void testListVersions() { Assume.assumeFalse(isVipr); // Create an object MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); // Version the object ObjectId vid1 = this.esu.versionObject(id); Assert.assertNotNull("null version ID returned", vid1); ObjectId vid2 = this.esu.versionObject(id); Assert.assertNotNull("null version ID returned", vid2); cleanup.add(id); // List the versions and ensure their IDs are correct List<Identifier> versions = this.esu.listVersions(id); Assert.assertEquals("Wrong number of versions returned", 2, versions.size()); Assert.assertTrue("version 1 not found in version list", versions.contains(vid1)); Assert.assertTrue("version 2 not found in version list", versions.contains(vid2)); } /** * Test listing the versions of an object */ @Test public void testListVersionsLong() { Assume.assumeFalse(isVipr); // Create an object MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); // Version the object ObjectId vid1 = this.esu.versionObject(id); Version v1 = new Version(vid1, 0, null); Assert.assertNotNull("null version ID returned", vid1); ObjectId vid2 = this.esu.versionObject(id); Version v2 = new Version(vid2, 1, null); Assert.assertNotNull("null version ID returned", vid2); cleanup.add(id); // List the versions and ensure their IDs are correct ListOptions options = new ListOptions(); options.setLimit(1); List<Version> versions = new ArrayList<Version>(); do { versions.addAll(this.esu.listVersions(id, options)); } while (options.getToken() != null); Assert.assertEquals("Wrong number of versions returned", 2, versions.size()); Assert.assertTrue("version 1 not found in version list", versions.contains(v1)); Assert.assertTrue("version 2 not found in version list", versions.contains(v2)); for (Version v : versions) { Assert.assertNotNull("oid null in version", v.getId()); Assert.assertTrue("Invalid version number in version", v.getVersionNumber() > -1); Assert.assertNotNull("itime null in version", v.getItime()); } } /** * Test listing the versions of an object */ @Test public void testDeleteVersion() { Assume.assumeFalse(isVipr); // Create an object MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); // Version the object ObjectId vid1 = this.esu.versionObject(id); Assert.assertNotNull("null version ID returned", vid1); ObjectId vid2 = this.esu.versionObject(id); Assert.assertNotNull("null version ID returned", vid2); cleanup.add(id); // List the versions and ensure their IDs are correct List<Identifier> versions = this.esu.listVersions(id); Assert.assertEquals("Wrong number of versions returned", 2, versions.size()); Assert.assertTrue("version 1 not found in version list", versions.contains(vid1)); Assert.assertTrue("version 2 not found in version list", versions.contains(vid2)); // Delete a version this.esu.deleteVersion(vid1); versions = this.esu.listVersions(id); Assert.assertEquals("Wrong number of versions returned", 1, versions.size()); Assert.assertFalse("version 1 found in version list", versions.contains(vid1)); Assert.assertTrue("version 2 not found in version list", versions.contains(vid2)); } @Test public void testRestoreVersion() throws UnsupportedEncodingException { Assume.assumeFalse(isVipr); ObjectId id = this.esu.createObject(null, null, "Base Version Content".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Version the object ObjectId vId = this.esu.versionObject(id); // Update the object content this.esu.updateObject(id, null, null, null, "Child Version Content -- You should never see me".getBytes("UTF-8"), "text/plain"); // Restore the original version this.esu.restoreVersion(id, vId); // Read back the content String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "Base Version Content", content); } /** * Test listing the system metadata on an object */ @Test public void testGetSystemMetadata() { // Create an object MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read only part of the metadata MetadataTags mtags = new MetadataTags(); mtags.addTag(new MetadataTag("atime", false)); mtags.addTag(new MetadataTag("ctime", false)); MetadataList meta = this.esu.getSystemMetadata(id, mtags); Assert.assertNotNull("value of 'atime' missing", meta.getMetadata("atime")); Assert.assertNull("value of 'mtime' should not have been returned", meta.getMetadata("mtime")); Assert.assertNotNull("value of 'ctime' missing", meta.getMetadata("ctime")); Assert.assertNull("value of 'gid' should not have been returned", meta.getMetadata("gid")); Assert.assertNull("value of 'listable' should not have been returned", meta.getMetadata("listable")); } /** * Test listing objects by a tag that doesn't exist */ @Test public void testListObjectsNoExist() { ListOptions options = new ListOptions(); List<ObjectResult> objects = this.esu.listObjects("this_tag_should_not_exist", options); Assert.assertNotNull("object list should be not null", objects); Assert.assertEquals("No objects should be returned", 0, objects.size()); } /** * Test listing objects by a tag */ @Test public void testListObjects() { // Create an object MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("list/able/2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("list/able/not", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // List the objects. Make sure the one we created is in the list List<ObjectResult> objects = this.esu.listObjects("listable", null); Assert.assertTrue("No objects returned", objects.size() > 0); Assert.assertTrue("object not found in list", objects.contains(id)); } /** * Test listing objects by a tag */ @Test public void testListObjectsWithMetadata() { // Create an object MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("list/able/2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("list/able/not", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // List the objects. Make sure the one we created is in the list ListOptions options = new ListOptions(); options.setIncludeMetadata(true); List<ObjectResult> objects = this.esu.listObjects("listable", options); Assert.assertTrue("No objects returned", objects.size() > 0); // Find the item. boolean found = false; for (Iterator<ObjectResult> i = objects.iterator(); i.hasNext();) { ObjectResult or = i.next(); if (or.getId().equals(id)) { found = true; // check metadata Assert.assertEquals("Wrong value on metadata", or.getMetadata().getMetadata("listable").getValue(), "foo"); } } Assert.assertTrue("object not found in list", found); } /** * Test listing objects by a tag, with only some of the metadata */ @Test public void testListObjectsWithSomeMetadata() { // Create an object MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("list/able/2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("list/able/not", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // List the objects. Make sure the one we created is in the list ListOptions options = new ListOptions(); options.setIncludeMetadata(true); options.setUserMetadata(Arrays.asList(new String[] { "listable" })); List<ObjectResult> objects = this.esu.listObjects("listable", options); Assert.assertTrue("No objects returned", objects.size() > 0); // Find the item. boolean found = false; for (Iterator<ObjectResult> i = objects.iterator(); i.hasNext();) { ObjectResult or = i.next(); if (or.getId().equals(id)) { found = true; // check metadata Assert.assertEquals("Wrong value on metadata", or.getMetadata().getMetadata("listable").getValue(), "foo"); // Other metadata should not be present Assert.assertNull("unlistable should be missing", or.getMetadata().getMetadata("unlistable")); } } Assert.assertTrue("object not found in list", found); } /** * Test listing objects by a tag, paging the results */ @Test public void testListObjectsPaged() { // Create two objects. MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); mlist.addMetadata(listable); ObjectId id1 = this.esu.createObject(null, mlist, null, null); ObjectId id2 = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id1); Assert.assertNotNull("null ID returned", id2); cleanup.add(id1); cleanup.add(id2); // List the objects. Make sure the one we created is in the list ListOptions options = new ListOptions(); options.setIncludeMetadata(true); options.setLimit(1); List<ObjectResult> objects = this.esu.listObjects("listable", options); Assert.assertTrue("No objects returned", objects.size() > 0); Assert.assertNotNull("Token should be present", options.getToken()); l4j.debug("listObjectsPaged, Token: " + options.getToken()); while (options.getToken() != null) { // Subsequent pages objects.addAll(this.esu.listObjects("listable", options)); l4j.debug("listObjectsPaged, Token: " + options.getToken()); } // Ensure our IDs exist Assert.assertTrue("First object not found", objects.contains(id1)); Assert.assertTrue("Second object not found", objects.contains(id2)); } /** * Test fetching listable tags */ @Test public void testGetListableTags() { // Create an object ObjectId id = this.esu.createObject(null, null, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("list/able/2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("list/able/not", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); this.esu.updateObject(id, null, mlist, null, null, null); // List tags. Ensure our object's tags are in the list. MetadataTags tags = this.esu.getListableTags((String) null); Assert.assertTrue("listable tag not returned", tags.contains("listable")); Assert.assertTrue("list/able/2 root tag not returned", tags.contains("list")); Assert.assertFalse("list/able/not tag returned", tags.contains("list/able/not")); // List child tags tags = this.esu.getListableTags("list/able"); Assert.assertFalse("non-child returned", tags.contains("listable")); Assert.assertTrue("list/able/2 tag not returned", tags.contains("2")); Assert.assertFalse("list/able/not tag returned", tags.contains("not")); } /** * Test listing the user metadata tags on an object */ @Test public void testListUserMetadataTags() { // Create an object MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("list/able/2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("list/able/not", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // List tags MetadataTags tags = this.esu.listUserMetadataTags(id); Assert.assertTrue("listable tag not returned", tags.contains("listable")); Assert.assertTrue("list/able/2 tag not returned", tags.contains("list/able/2")); Assert.assertTrue("unlistable tag not returned", tags.contains("unlistable")); Assert.assertTrue("list/able/not tag not returned", tags.contains("list/able/not")); Assert.assertFalse("unknown tag returned", tags.contains("unknowntag")); // Check listable flag Assert.assertEquals("'listable' is not listable", true, tags.getTag("listable").isListable()); Assert.assertEquals("'list/able/2' is not listable", true, tags.getTag("list/able/2").isListable()); Assert.assertEquals("'unlistable' is listable", false, tags.getTag("unlistable").isListable()); Assert.assertEquals("'list/able/not' is listable", false, tags.getTag("list/able/not").isListable()); } // /** // * Test executing a query. // */ // @Test // public void testQueryObjects() { // // Create an object // MetadataList mlist = new MetadataList(); // Metadata listable = new Metadata( "listable", "foo", true ); // Metadata unlistable = new Metadata( "unlistable", "bar", false ); // Metadata listable2 = new Metadata( "list/able/2", "foo2 foo2", true ); // Metadata unlistable2 = new Metadata( "list/able/not", "bar2 bar2", false ); // mlist.addMetadata( listable ); // mlist.addMetadata( unlistable ); // mlist.addMetadata( listable2 ); // mlist.addMetadata( unlistable2 ); // ObjectId id = this.esu.createObject( null, mlist, null, null ); // Assert.assertNotNull( "null ID returned", id ); // cleanup.add( id ); // // // Query for all objects for the current UID // String query = "for $h in collection() where $h/maui:MauiObject[uid=\"" + // uid + "\"] return $h"; // l4j.info( "Query: " + query ); // List<Identifier> objects = this.esu.queryObjects( query ); // // // Ensure the search results contains the object we just created // Assert.assertTrue( "object not found in list", objects.contains( id ) ); // // } /** * Tests updating an object's metadata */ @Test public void testUpdateObjectMetadata() throws Exception { // Create an object MetadataList mlist = new MetadataList(); Metadata unlistable = new Metadata("unlistable", "foo", false); mlist.addMetadata(unlistable); ObjectId id = this.esu.createObject(null, mlist, "hello".getBytes("UTF-8"), null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Update the metadata unlistable.setValue("bar"); this.esu.setUserMetadata(id, mlist); // Re-read the metadata MetadataList meta = this.esu.getUserMetadata(id, null); Assert.assertEquals("value of 'unlistable' wrong", "bar", meta.getMetadata("unlistable").getValue()); // Check that content was not modified String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); } @Test public void testUpdateObjectAcl() throws Exception { // Create an object with an ACL Acl acl = new Acl(); acl.addGrant(new Grant(new Grantee(stripUid(uid), Grantee.GRANT_TYPE.USER), Permission.FULL_CONTROL)); Grant other = new Grant(Grantee.OTHER, Permission.READ); acl.addGrant(other); ObjectId id = this.esu.createObject(acl, null, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read back the ACL and make sure it matches Acl newacl = this.esu.getAcl(id); l4j.info("Comparing " + newacl + " with " + acl); Assert.assertEquals("ACLs don't match", acl, newacl); // Change the ACL and update the object. acl.removeGrant(other); Grant o2 = new Grant(Grantee.OTHER, Permission.NONE); acl.addGrant(o2); this.esu.setAcl(id, acl); // Read the ACL back and check it newacl = this.esu.getAcl(id); l4j.info("Comparing " + newacl + " with " + acl); Assert.assertEquals("ACLs don't match", acl, newacl); } /** * Tests updating an object's contents */ @Test public void testUpdateObjectContent() throws Exception { // Create an object ObjectId id = this.esu.createObject(null, null, "hello".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Update part of the content Extent extent = new Extent(1, 1); this.esu.updateObject(id, null, null, extent, "u".getBytes("UTF-8"), null); // Read back the content and check it String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hullo", content); } @Test public void testUpdateObjectContentStream() throws Exception { // Create an object ObjectId id = this.esu.createObject(null, null, "hello".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Update part of the content Extent extent = new Extent(1, 1); InputStream in = new ByteArrayInputStream("u".getBytes("UTF-8")); this.esu.updateObjectFromStream(id, null, null, extent, in, 1, null); in.close(); // Read back the content and check it String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hullo", content); } /** * Test replacing an object's entire contents */ @Test public void testReplaceObjectContent() throws Exception { // Create an object ObjectId id = this.esu.createObject(null, null, "hello".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Update all of the content this.esu.updateObject(id, null, null, null, "bonjour".getBytes("UTF-8"), null); // Read back the content and check it String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "bonjour", content); } /** * Test the UploadHelper's create method */ @Test public void testCreateHelper() throws Exception { // use a blocksize of 1 to test multiple transfers. UploadHelper uploadHelper = new UploadHelper(this.esu, new byte[1]); ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write("hello".getBytes("UTF-8")); // Create an object from our file stream ObjectId id = uploadHelper.createObject(new ByteArrayInputStream(baos.toByteArray()), null, null, true); cleanup.add(id); // Read contents back and check them String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); } /** * Test the UploadHelper's update method */ @Test public void testUpdateHelper() throws Exception { // use a blocksize of 1 to test multiple transfers. UploadHelper uploadHelper = new UploadHelper(this.esu, new byte[1]); uploadHelper.setMimeType("text/plain"); // Create an object with content. ObjectId id = this.esu.createObject(null, null, "Four score and twenty years ago".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // update the object contents ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write("hello".getBytes("UTF-8")); uploadHelper.updateObject(id, new ByteArrayInputStream(baos.toByteArray()), null, null, true); // Read contents back and check them String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); } /** * Tests the download helper. Tests both single and multiple requests. */ @Test public void testDownloadHelper() throws Exception { // Create an object with content. ObjectId id = this.esu.createObject(null, null, "Four score and twenty years ago".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Download the content DownloadHelper downloadHelper = new DownloadHelper(this.esu, null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); downloadHelper.readObject(id, baos, false); // Check the download String data = new String(baos.toByteArray(), "UTF-8"); Assert.assertEquals("object content wrong", "Four score and twenty years ago", data); // Download again 1 byte in a request downloadHelper = new DownloadHelper(this.esu, new byte[1]); baos = new ByteArrayOutputStream(); downloadHelper.readObject(id, baos, false); // Check the download data = new String(baos.toByteArray(), "UTF-8"); Assert.assertEquals("object content wrong", "Four score and twenty years ago", data); } // @Test // public void testUploadDownload() throws Exception { // // Create a byte array to test // int size=10*1024*1024; // byte[] testData = new byte[size]; // for( int i=0; i<size; i++ ) { // testData[i] = (byte)(i%0x93); // } // UploadHelper uh = new UploadHelper( this.esu, null ); // // ObjectId id = uh.createObject( new ByteArrayInputStream( testData ), null, null, true ); // cleanup.add( id ); // // ByteArrayOutputStream baos = new ByteArrayOutputStream( size ); // // DownloadHelper dl = new DownloadHelper( this.esu, new byte[4*1024*1024] ); // dl.readObject( id, baos, true ); // // Assert.assertFalse( "Download should have been OK", dl.isFailed() ); // Assert.assertNull( "Error should have been null", dl.getError() ); // // byte[] outData = baos.toByteArray(); // // // Check the files // Assert.assertEquals( "File lengths differ", testData.length, outData.length ); // // Assert.assertArrayEquals( "Data contents differ", testData, outData ); // // } @Test public void testListDirectory() throws Exception { String dir = rand8char(); String file = rand8char(); String dir2 = rand8char(); ObjectPath dirPath = new ObjectPath("/" + dir + "/"); ObjectPath op = new ObjectPath("/" + dir + "/" + file); ObjectPath dirPath2 = new ObjectPath("/" + dir + "/" + dir2 + "/"); ObjectId dirId = this.esu.createObjectOnPath(dirPath, null, null, null, null); ObjectId id = this.esu.createObjectOnPath(op, null, null, null, null); this.esu.createObjectOnPath(dirPath2, null, null, null, null); cleanup.add(op); cleanup.add(dirPath2); cleanup.add(dirPath); l4j.debug("Path: " + op + " ID: " + id); Assert.assertNotNull(id); Assert.assertNotNull(dirId); // Read back the content String content = new String(this.esu.readObject(op, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "", content); content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong when reading by id", "", content); // List the parent path List<DirectoryEntry> dirList = esu.listDirectory(dirPath, null); l4j.debug("Dir content: " + content); Assert.assertTrue("File not found in directory", directoryContains(dirList, op)); Assert.assertTrue("subdirectory not found in directory", directoryContains(dirList, dirPath2)); } @Test public void testListDirectoryPaged() throws Exception { String dir = rand8char(); String file = rand8char(); String dir2 = rand8char(); ObjectPath dirPath = new ObjectPath("/" + dir + "/"); ObjectPath op = new ObjectPath("/" + dir + "/" + file); ObjectPath dirPath2 = new ObjectPath("/" + dir + "/" + dir2 + "/"); ObjectId dirId = this.esu.createObjectOnPath(dirPath, null, null, null, null); ObjectId id = this.esu.createObjectOnPath(op, null, null, null, null); this.esu.createObjectOnPath(dirPath2, null, null, null, null); cleanup.add(op); cleanup.add(dirPath2); cleanup.add(dirPath); l4j.debug("Path: " + op + " ID: " + id); Assert.assertNotNull(id); Assert.assertNotNull(dirId); // List the parent path ListOptions options = new ListOptions(); options.setLimit(1); List<DirectoryEntry> dirList = esu.listDirectory(dirPath, options); Assert.assertNotNull("Token should have been returned", options.getToken()); l4j.debug("listDirectoryPaged, token: " + options.getToken()); while (options.getToken() != null) { dirList.addAll(esu.listDirectory(dirPath, options)); } Assert.assertTrue("File not found in directory", directoryContains(dirList, op)); Assert.assertTrue("subdirectory not found in directory", directoryContains(dirList, dirPath2)); } @Test public void testListDirectoryWithMetadata() throws Exception { String dir = rand8char(); String file = rand8char(); String dir2 = rand8char(); ObjectPath dirPath = new ObjectPath("/" + dir + "/"); ObjectPath op = new ObjectPath("/" + dir + "/" + file); ObjectPath dirPath2 = new ObjectPath("/" + dir + "/" + dir2 + "/"); MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("list/able/2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("list/able/not", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId dirId = this.esu.createObjectOnPath(dirPath, null, null, null, null); ObjectId id = this.esu.createObjectOnPath(op, null, mlist, null, null); this.esu.createObjectOnPath(dirPath2, null, null, null, null); cleanup.add(op); cleanup.add(dirPath2); cleanup.add(dirPath); l4j.debug("Path: " + op + " ID: " + id); Assert.assertNotNull(id); Assert.assertNotNull(dirId); // List the parent path ListOptions options = new ListOptions(); options.setIncludeMetadata(true); List<DirectoryEntry> dirList = esu.listDirectory(dirPath, options); Assert.assertTrue("File not found in directory", directoryContains(dirList, op)); Assert.assertTrue("subdirectory not found in directory", directoryContains(dirList, dirPath2)); for (Iterator<DirectoryEntry> i = dirList.iterator(); i.hasNext();) { DirectoryEntry de = i.next(); if (de.getPath().equals(op)) { // Check the metadata Assert.assertEquals("Wrong value on metadata", de.getUserMetadata().getMetadata("listable").getValue(), "foo"); } } Assert.assertTrue("File not found in directory", directoryContains(dirList, op)); Assert.assertTrue("subdirectory not found in directory", directoryContains(dirList, dirPath2)); } @Test public void testListDirectoryWithSomeMetadata() throws Exception { String dir = rand8char(); String file = rand8char(); String dir2 = rand8char(); ObjectPath dirPath = new ObjectPath("/" + dir + "/"); ObjectPath op = new ObjectPath("/" + dir + "/" + file); ObjectPath dirPath2 = new ObjectPath("/" + dir + "/" + dir2 + "/"); MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("list/able/2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("list/able/not", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); ObjectId dirId = this.esu.createObjectOnPath(dirPath, null, null, null, null); ObjectId id = this.esu.createObjectOnPath(op, null, mlist, null, null); this.esu.createObjectOnPath(dirPath2, null, null, null, null); cleanup.add(op); cleanup.add(dirPath2); cleanup.add(dirPath); l4j.debug("Path: " + op + " ID: " + id); Assert.assertNotNull(id); Assert.assertNotNull(dirId); // List the parent path ListOptions options = new ListOptions(); options.setIncludeMetadata(true); options.setUserMetadata(Arrays.asList(new String[] { "listable" })); List<DirectoryEntry> dirList = esu.listDirectory(dirPath, options); Assert.assertTrue("File not found in directory", directoryContains(dirList, op)); Assert.assertTrue("subdirectory not found in directory", directoryContains(dirList, dirPath2)); for (Iterator<DirectoryEntry> i = dirList.iterator(); i.hasNext();) { DirectoryEntry de = i.next(); if (de.getPath().equals(op)) { // Check the metadata Assert.assertEquals("Wrong value on metadata", de.getUserMetadata().getMetadata("listable").getValue(), "foo"); // Other metadata should not be present Assert.assertNull("unlistable should be missing", de.getUserMetadata().getMetadata("unlistable")); } } Assert.assertTrue("File not found in directory", directoryContains(dirList, op)); Assert.assertTrue("subdirectory not found in directory", directoryContains(dirList, dirPath2)); } private boolean directoryContains(List<DirectoryEntry> dir, ObjectPath path) { for (Iterator<DirectoryEntry> i = dir.iterator(); i.hasNext();) { DirectoryEntry de = i.next(); if (de.getPath().equals(path)) { return true; } } return false; } /** * This method tests various legal and illegal pathnames * * @throws Exception */ @Test public void testPathNaming() throws Exception { ObjectPath path = new ObjectPath("/some/file"); Assert.assertFalse("File should not be directory", path.isDirectory()); path = new ObjectPath("/some/file.txt"); Assert.assertFalse("File should not be directory", path.isDirectory()); ObjectPath path2 = new ObjectPath("/some/file.txt"); Assert.assertEquals("Equal paths should be equal", path, path2); path = new ObjectPath("/some/file/with/long.path/extra.stuff.here.zip"); Assert.assertFalse("File should not be directory", path.isDirectory()); path = new ObjectPath("/"); Assert.assertTrue("Directory should be directory", path.isDirectory()); path = new ObjectPath("/long/path/with/lots/of/elements/"); Assert.assertTrue("Directory should be directory", path.isDirectory()); } /** * Tests dot directories (you should be able to create them even though they break the URL specification.) * * @throws Exception */ @Test public void testDotDirectories() throws Exception { String parentPath = "/dottest/"; String dotPath = parentPath + "./"; String dotdotPath = parentPath + "../"; String filename = "test.txt"; byte[] content = "Hello World!".getBytes("UTF-8"); // isolate this test in the namespace ObjectId parentId = null; try { parentId = this.esu.createObjectOnPath(new ObjectPath(parentPath), null, null, null, null); } catch (EsuException e) { if (e.getAtmosCode() == 1016) { deleteRecursively(new ObjectPath(parentPath)); parentId = this.esu.createObjectOnPath(new ObjectPath(parentPath), null, null, null, null); } else { throw e; } } // test single dot path (./) ObjectId fileId = this.esu.createObjectOnPath(new ObjectPath(parentPath + "hidden.txt"), null, null, content, "text/plain"); cleanup.add(fileId); ObjectId dirId = this.esu.createObjectOnPath(new ObjectPath(dotPath), null, null, null, null); Assert.assertNotNull("null ID returned on dot path creation", dirId); fileId = this.esu.createObjectOnPath(new ObjectPath(dotPath + filename), null, null, content, "text/plain"); // make sure we only see one file (the "." path is its own directory and not a synonym for the current directory) List<DirectoryEntry> entries = this.esu.listDirectory(new ObjectPath(dotPath), null); Assert.assertEquals("dot path listing was not 1", entries.size(), 1); Assert.assertTrue("dot path listing did not contain a dot in the path", entries.get(0).getPath().toString().contains(dotPath)); Assert.assertEquals("dot path listing did not contain test file", entries.get(0).getPath().getName(), filename); cleanup.add(fileId); cleanup.add(dirId); // test double dot path (../) dirId = this.esu.createObjectOnPath(new ObjectPath(dotdotPath), null, null, null, null); Assert.assertNotNull("null ID returned on dotdot path creation", dirId); fileId = this.esu.createObjectOnPath(new ObjectPath(dotdotPath + filename), null, null, content, "text/plain"); // make sure we only see one file (the ".." path is its own directory and not a synonym for the parent directory) entries = this.esu.listDirectory(new ObjectPath(dotdotPath), null); Assert.assertEquals("dotdot path listing was not 1", entries.size(), 1); Assert.assertTrue("dotdot path listing did not contain a dotdot in the path", entries.get(0).getPath().toString().contains(dotdotPath)); Assert.assertEquals("dotdot path listing did not contain test file", entries.get(0).getPath().getName(), filename); cleanup.add(fileId); cleanup.add(dirId); cleanup.add(parentId); } /** * Tests the 'get all metadata' call using a path * * @throws Exception */ @Test public void testGetAllMetadataByPath() throws Exception { ObjectPath op = new ObjectPath("/" + rand8char() + ".tmp"); // Create an object with an ACL Acl acl = new Acl(); acl.addGrant(new Grant(new Grantee(uid, Grantee.GRANT_TYPE.USER), Permission.FULL_CONTROL)); acl.addGrant(new Grant(Grantee.OTHER, Permission.READ)); MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); String mimeType = "test/mimetype"; String content = "test"; ObjectId id = this.esu.createObjectOnPath(op, acl, null, content.getBytes("UTF-8"), mimeType); this.esu.updateObject(op, null, mlist, null, null, mimeType); Assert.assertNotNull("null ID returned", id); cleanup.add(op); // Read it back with HEAD call ObjectMetadata om = this.esu.getAllMetadata(op); Assert.assertNotNull("value of 'listable' missing", om.getMetadata().getMetadata("listable")); Assert.assertNotNull("value of 'unlistable' missing", om.getMetadata().getMetadata("unlistable")); Assert.assertNotNull("value of 'atime' missing", om.getMetadata().getMetadata("atime")); Assert.assertNotNull("value of 'ctime' missing", om.getMetadata().getMetadata("ctime")); Assert.assertEquals("value of 'listable' wrong", "foo", om.getMetadata().getMetadata("listable").getValue()); Assert.assertEquals("value of 'unlistable' wrong", "bar", om.getMetadata().getMetadata("unlistable").getValue()); Assert.assertEquals("Mimetype incorrect", mimeType, om.getMimeType()); // Check the ACL // not checking this by path because an extra groupid is added // during the create calls by path. //Assert.assertEquals( "ACLs don't match", acl, om.getAcl() ); } @Test public void testGetAllMetadataById() throws Exception { // Create an object with an ACL Acl acl = new Acl(); acl.addGrant(new Grant(new Grantee(uid, Grantee.GRANT_TYPE.USER), Permission.FULL_CONTROL)); acl.addGrant(new Grant(Grantee.OTHER, Permission.READ)); MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); String mimeType = "test/mimetype"; String content = "test"; ObjectId id = this.esu.createObject(acl, mlist, content.getBytes("UTF-8"), mimeType); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read it back with HEAD call ObjectMetadata om = this.esu.getAllMetadata(id); Assert.assertNotNull("value of 'listable' missing", om.getMetadata().getMetadata("listable")); Assert.assertNotNull("value of 'unlistable' missing", om.getMetadata().getMetadata("unlistable")); Assert.assertNotNull("value of 'atime' missing", om.getMetadata().getMetadata("atime")); Assert.assertNotNull("value of 'ctime' missing", om.getMetadata().getMetadata("ctime")); Assert.assertEquals("value of 'listable' wrong", "foo", om.getMetadata().getMetadata("listable").getValue()); Assert.assertEquals("value of 'unlistable' wrong", "bar", om.getMetadata().getMetadata("unlistable").getValue()); Assert.assertEquals("Mimetype incorrect", mimeType, om.getMimeType()); // Check the ACL //Assert.assertEquals( "ACLs don't match", acl, om.getAcl() ); } /** * Tests getting object replica information. */ @Test public void testGetObjectReplicaInfo() throws Exception { ObjectId id = this.esu.createObject(null, null, "hello".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); MetadataTags mt = new MetadataTags(); mt.addTag(new MetadataTag("user.maui.lso", false)); MetadataList meta = this.esu.getUserMetadata(id, mt); Assert.assertNotNull(meta.getMetadata("user.maui.lso")); l4j.debug("Replica info: " + meta.getMetadata("user.maui.lso")); } @Test public void testCreateHelperWithPath() throws Exception { String dir = rand8char(); String file = rand8char(); ObjectPath op = new ObjectPath("/" + dir + "/" + file); // use a blocksize of 1 to test multiple transfers. UploadHelper uploadHelper = new UploadHelper(this.esu, new byte[1]); ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write("hello".getBytes("UTF-8")); // Create an object from our file stream ObjectId id = uploadHelper.createObjectOnPath(op, new ByteArrayInputStream(baos.toByteArray()), null, null, true); cleanup.add(op); // Read contents back and check them String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); } @Test public void testUpdateHelperWithPath() throws Exception { String dir = rand8char(); String file = rand8char(); ObjectPath op = new ObjectPath("/" + dir + "/" + file); // use a blocksize of 1 to test multiple transfers. UploadHelper uploadHelper = new UploadHelper(this.esu, new byte[1]); uploadHelper.setMimeType("text/plain"); // Create an object with content. ObjectId id = this.esu.createObjectOnPath(op, null, null, "Four score and twenty years ago".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(op); // update the object contents ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.write("hello".getBytes("UTF-8")); uploadHelper.updateObject(op, new ByteArrayInputStream(baos.toByteArray()), null, null, true); // Read contents back and check them String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); } @Test public void testGetShareableUrl() throws Exception { Assume.assumeFalse(isVipr); // Create an object with content. String str = "Four score and twenty years ago"; ObjectId id = this.esu.createObject(null, null, str.getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); Calendar c = Calendar.getInstance(); c.add(Calendar.HOUR, 4); Date expiration = c.getTime(); URL u = esu.getShareableUrl(id, expiration); l4j.debug("Sharable URL: " + u); InputStream stream = (InputStream) u.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(stream)); String content = br.readLine(); l4j.debug("Content: " + content); Assert.assertEquals("URL does not contain proper content", str, content.toString()); } @Test public void testGetShareableUrlWithPath() throws Exception { Assume.assumeFalse(isVipr); // Create an object with content. String str = "Four score and twenty years ago"; ObjectPath op = new ObjectPath("/" + rand8char() + ".txt"); ObjectId id = this.esu.createObjectOnPath(op, null, null, str.getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(op); Calendar c = Calendar.getInstance(); c.add(Calendar.HOUR, 4); Date expiration = c.getTime(); URL u = esu.getShareableUrl(op, expiration); l4j.debug("Sharable URL: " + u); InputStream stream = (InputStream) u.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(stream)); String content = br.readLine(); l4j.debug("Content: " + content); Assert.assertEquals("URL does not contain proper content", str, content.toString()); } @Test public void testExpiredSharableUrl() throws Exception { Assume.assumeFalse(isVipr); // Create an object with content. String str = "Four score and twenty years ago"; ObjectId id = this.esu.createObject(null, null, str.getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); Calendar c = Calendar.getInstance(); c.add(Calendar.HOUR, -4); Date expiration = c.getTime(); URL u = esu.getShareableUrl(id, expiration); l4j.debug("Sharable URL: " + u); try { InputStream stream = (InputStream) u.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(stream)); String content = br.readLine(); l4j.debug("Content: " + content); Assert.fail("Request should have failed"); } catch (Exception e) { l4j.debug("Error (expected): " + e); } } @Test public void testReadObjectStream() throws Exception { ObjectId id = this.esu.createObject(null, null, "hello".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read back the content InputStream in = this.esu.readObjectStream(id, null); BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8")); String content = br.readLine(); br.close(); Assert.assertEquals("object content wrong", "hello", content); // Read back only 2 bytes Extent extent = new Extent(1, 2); in = this.esu.readObjectStream(id, extent); br = new BufferedReader(new InputStreamReader(in, "UTF-8")); content = br.readLine(); br.close(); Assert.assertEquals("partial object content wrong", "el", content); } @Test public void testCreateChecksum() throws Exception { Checksum ck = new Checksum(Algorithm.SHA0); ObjectId id = this.esu.createObject(null, null, "hello".getBytes("UTF-8"), "text/plain", ck); l4j.debug("Checksum: " + ck); cleanup.add(id); } /** * Note, to test read checksums, see comment in testReadChecksum * * @throws Exception */ @Test public void testUploadDownloadChecksum() throws Exception { // Create a byte array to test int size = 10 * 1024 * 1024; byte[] testData = new byte[size]; for (int i = 0; i < size; i++) { testData[i] = (byte) (i % 0x93); } MetadataList mlist = new MetadataList(); Metadata policy = new Metadata("policy", "erasure", false); mlist.addMetadata(policy); UploadHelper uh = new UploadHelper(this.esu, null); uh.setChecksumming(true); ObjectId id = uh.createObject(new ByteArrayInputStream(testData), null, mlist, true); cleanup.add(id); ByteArrayOutputStream baos = new ByteArrayOutputStream(size); DownloadHelper dl = new DownloadHelper(this.esu, new byte[4 * 1024 * 1024]); dl.setChecksumming(true); dl.readObject(id, baos, true); Assert.assertFalse("Download should have been OK", dl.isFailed()); Assert.assertNull("Error should have been null", dl.getError()); byte[] outData = baos.toByteArray(); // Check the files Assert.assertEquals("File lengths differ", testData.length, outData.length); Assert.assertArrayEquals("Data contents differ", testData, outData); } @Test public void testUnicodeMetadata() throws Exception { MetadataList mlist = new MetadataList(); Metadata nbspValue = new Metadata("nbspvalue", "Nobreak\u00A0Value", false); Metadata nbspName = new Metadata("Nobreak\u00A0Name", "regular text here", false); Metadata cryllic = new Metadata("cryllic", "??", false); l4j.debug("NBSP Value: " + nbspValue); l4j.debug("NBSP Name: " + nbspName); mlist.addMetadata(nbspValue); mlist.addMetadata(nbspName); mlist.addMetadata(cryllic); ObjectId id = this.esu.createObject(null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read and validate the metadata MetadataList meta = this.esu.getUserMetadata(id, null); l4j.debug("Read Back:"); l4j.debug("NBSP Value: " + meta.getMetadata("nbspvalue")); l4j.debug("NBSP Name: " + meta.getMetadata("Nobreak\u00A0Name")); Assert.assertEquals("value of 'nobreakvalue' wrong", "Nobreak\u00A0Value", meta.getMetadata("nbspvalue").getValue()); Assert.assertEquals("Value of cryllic wrong", "??", meta.getMetadata("cryllic").getValue()); } @Test public void testUtf8Metadata() throws Exception { String oneByteCharacters = "Hello! "; String twoByteCharacters = "\u0410\u0411\u0412\u0413"; // Cyrillic letters String fourByteCharacters = "\ud841\udf0e\ud841\udf31\ud841\udf79\ud843\udc53"; // Chinese symbols String utf8String = oneByteCharacters + twoByteCharacters + fourByteCharacters; MetadataList metaList = new MetadataList(); metaList.addMetadata(new Metadata("utf8Key", utf8String, false)); metaList.addMetadata(new Metadata(utf8String, "utf8Value", false)); ObjectId id = this.esu.createObject(null, metaList, null, null); cleanup.add(id); // list all tags and make sure the UTF8 tag is in the list MetadataTags tags = this.esu.listUserMetadataTags(id); Assert.assertTrue("UTF8 key not found in tag list", tags.contains(utf8String)); // get the user metadata and make sure all UTF8 characters are accurate metaList = this.esu.getUserMetadata(id, null); Metadata meta = metaList.getMetadata(utf8String); Assert.assertEquals("UTF8 key does not match", meta.getName(), utf8String); Assert.assertEquals("UTF8 key value does not match", meta.getValue(), "utf8Value"); Assert.assertEquals("UTF8 value does not match", metaList.getMetadata("utf8Key").getValue(), utf8String); // test set metadata with UTF8 metaList = new MetadataList(); metaList.addMetadata(new Metadata("newKey", utf8String + "2", false)); metaList.addMetadata(new Metadata(utf8String + "2", "newValue", false)); this.esu.setUserMetadata(id, metaList); // verify set metadata call (also testing getAllMetadata) ObjectMetadata objMeta = this.esu.getAllMetadata(id); metaList = objMeta.getMetadata(); meta = metaList.getMetadata(utf8String + "2"); Assert.assertEquals("UTF8 key does not match", meta.getName(), utf8String + "2"); Assert.assertEquals("UTF8 key value does not match", meta.getValue(), "newValue"); Assert.assertEquals("UTF8 value does not match", metaList.getMetadata("newKey").getValue(), utf8String + "2"); } @Test public void testUtf8MetadataFilter() throws Exception { String oneByteCharacters = "Hello! "; String twoByteCharacters = "\u0410\u0411\u0412\u0413"; // Cyrillic letters String fourByteCharacters = "\ud841\udf0e\ud841\udf31\ud841\udf79\ud843\udc53"; // Chinese symbols String utf8String = oneByteCharacters + twoByteCharacters + fourByteCharacters; MetadataList metaList = new MetadataList(); metaList.addMetadata(new Metadata("utf8Key", utf8String, false)); metaList.addMetadata(new Metadata(utf8String, "utf8Value", false)); ObjectId id = this.esu.createObject(null, metaList, null, null); cleanup.add(id); // apply a filter that includes the UTF8 tag MetadataTags tags = new MetadataTags(); tags.addTag(new MetadataTag(utf8String, false)); metaList = this.esu.getUserMetadata(id, tags); Assert.assertEquals("UTF8 filter was not honored", metaList.count(), 1); Assert.assertNotNull("UTF8 key was not found in filtered results", metaList.getMetadata(utf8String)); } @Test public void testUtf8DeleteMetadata() throws Exception { String oneByteCharacters = "Hello! "; String twoByteCharacters = "\u0410\u0411\u0412\u0413"; // Cyrillic letters String fourByteCharacters = "\ud841\udf0e\ud841\udf31\ud841\udf79\ud843\udc53"; // Chinese symbols String utf8String = oneByteCharacters + twoByteCharacters + fourByteCharacters; MetadataList metaList = new MetadataList(); metaList.addMetadata(new Metadata("utf8Key", utf8String, false)); metaList.addMetadata(new Metadata(utf8String, "utf8Value", false)); ObjectId id = this.esu.createObject(null, metaList, null, null); cleanup.add(id); // delete the UTF8 tag MetadataTags tags = new MetadataTags(); tags.addTag(new MetadataTag(utf8String, false)); this.esu.deleteUserMetadata(id, tags); // verify delete was successful tags = this.esu.listUserMetadataTags(id); Assert.assertFalse("UTF8 key was not deleted", tags.contains(utf8String)); } @Test public void testUtf8ListableMetadata() throws Exception { String oneByteCharacters = "Hello! "; String twoByteCharacters = "\u0410\u0411\u0412\u0413"; // Cyrillic letters String fourByteCharacters = "\ud841\udf0e\ud841\udf31\ud841\udf79\ud843\udc53"; // Chinese symbols String utf8String = oneByteCharacters + twoByteCharacters + fourByteCharacters; MetadataList metaList = new MetadataList(); metaList.addMetadata(new Metadata(utf8String, "utf8Value", true)); ObjectId id = this.esu.createObject(null, metaList, null, null); cleanup.add(id); metaList = this.esu.getUserMetadata(id, null); Metadata meta = metaList.getMetadata(utf8String); Assert.assertEquals("UTF8 key does not match", meta.getName(), utf8String); Assert.assertEquals("UTF8 key value does not match", meta.getValue(), "utf8Value"); Assert.assertTrue("UTF8 metadata is not listable", meta.isListable()); // verify we can list the tag and see our object boolean found = false; for (ObjectResult result : this.esu.listObjects(utf8String, null)) { if (result.getId().equals(id)) { found = true; break; } } Assert.assertTrue("UTF8 tag listing did not contain the correct object ID", found); // verify we can list child tags of the UTF8 tag MetadataTags tags = this.esu.getListableTags(new MetadataTag(utf8String, true)); Assert.assertNotNull("UTF8 child tag listing was null", tags); } //@Test public void testUtf8ListableTagWithComma() { String stringWithComma = "Hello, you!"; MetadataList metaList = new MetadataList(); metaList.addMetadata(new Metadata(stringWithComma, "value", true)); ObjectId id = this.esu.createObject(null, metaList, null, null); cleanup.add(id); metaList = this.esu.getUserMetadata(id, null); Metadata meta = metaList.getMetadata(stringWithComma); Assert.assertEquals("key does not match", meta.getName(), stringWithComma); Assert.assertTrue("metadata is not listable", meta.isListable()); boolean found = false; for (ObjectResult result : this.esu.listObjects(stringWithComma, null)) { if (result.getId().equals(id)) { found = true; break; } } Assert.assertTrue("listing did not contain the correct object ID", found); } @Test public void testRename() throws Exception { ObjectPath op1 = new ObjectPath("/" + rand8char() + ".tmp"); ObjectPath op2 = new ObjectPath("/" + rand8char() + ".tmp"); ObjectId id = this.esu.createObjectOnPath(op1, null, null, "Four score and seven years ago".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Rename this.esu.rename(op1, op2, false); // Read back the content String content = new String(this.esu.readObject(op2, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "Four score and seven years ago", content); } @Test public void testRenameOverwrite() throws Exception { ObjectPath op1 = new ObjectPath("/" + rand8char() + ".tmp"); ObjectPath op2 = new ObjectPath("/" + rand8char() + ".tmp"); ObjectId id = this.esu.createObjectOnPath(op1, null, null, "Four score and seven years ago".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); ObjectId id2 = this.esu.createObjectOnPath(op2, null, null, "You should not see this".getBytes("UTF-8"), "text/plain"); cleanup.add(id2); // Rename this.esu.rename(op1, op2, true); // Wait for overwrite to complete Thread.sleep(5000); // Read back the content String content = new String(this.esu.readObject(op2, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "Four score and seven years ago", content); } /** * Tests renaming a path to UTF-8 multi-byte characters. This is a separate test from create as the characters are * passed in the headers instead of the URL itself. * * @throws Exception */ @Test public void testUtf8Rename() throws Exception { String oneByteCharacters = "Hello! ,"; String twoByteCharacters = "\u0410\u0411\u0412\u0413"; // Cyrillic letters String fourByteCharacters = "\ud841\udf0e\ud841\udf31\ud841\udf79\ud843\udc53"; // Chinese symbols ObjectPath parentDir = createTestDir("Utf8Rename"); String normalName = parentDir + rand8char() + ".tmp"; String crazyName = parentDir + oneByteCharacters + twoByteCharacters + fourByteCharacters; byte[] content = "This is a really crazy name.".getBytes("UTF-8"); // normal name this.esu.createObjectOnPath(new ObjectPath(normalName), null, null, content, "text/plain"); // crazy multi-byte character name this.esu.rename(new ObjectPath(normalName), new ObjectPath(crazyName), true); // Wait for overwrite to complete Thread.sleep(5000); // verify name in directory list boolean found = false; for (DirectoryEntry entry : this.esu.listDirectory(parentDir, null)) { if (entry.getPath().toString().equals(crazyName)) { found = true; break; } } Assert.assertTrue("crazyName not found in directory listing", found); // Read back the content Assert.assertTrue("object content wrong", Arrays.equals(content, this.esu.readObject(new ObjectPath(crazyName), null, null))); } /** * Tests readback with checksum verification. In order to test this, create a policy * with erasure coding and then set a policy selector with "policy=erasure" to invoke * the erasure coding policy. * * @throws Exception */ @Test public void testReadChecksum() throws Exception { MetadataList mlist = new MetadataList(); Metadata policy = new Metadata("policy", "erasure", false); mlist.addMetadata(policy); Checksum createChecksum = new Checksum(Algorithm.SHA0); ObjectId id = this.esu.createObject(null, mlist, "hello".getBytes("UTF-8"), "text/plain", createChecksum); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read back the content Checksum readChecksum = new Checksum(Algorithm.SHA0); String content = new String(this.esu.readObject(id, null, null, readChecksum), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); } /** * Tests getting the service information */ @Test public void testGetServiceInformation() throws Exception { ServiceInformation si = this.esu.getServiceInformation(); Assert.assertNotNull("Atmos version is null", si.getAtmosVersion()); } /** * Test getting object info. Note to fully run this testcase, you should * create a policy named 'retaindelete' that keys off of the metadata * policy=retaindelete that includes a retention and deletion criteria. */ @Test public void testGetObjectInfo() throws Exception { MetadataList mlist = new MetadataList(); Metadata policy = new Metadata("policy", "retaindelete", false); mlist.addMetadata(policy); ObjectId id = this.esu.createObject(null, mlist, "hello".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read back the content String content = new String(this.esu.readObject(id, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "hello", content); // Get the object info ObjectInfo oi = this.esu.getObjectInfo(id); Assert.assertNotNull("ObjectInfo null", oi); Assert.assertNotNull("ObjectInfo expiration null", oi.getExpiration()); Assert.assertNotNull("ObjectInfo objectid null", oi.getObjectId()); Assert.assertNotNull("ObjectInfo raw xml null", oi.getRawXml()); Assert.assertNotNull("ObjectInfo replicas null", oi.getReplicas()); Assert.assertNotNull("ObjectInfo retention null", oi.getRetention()); Assert.assertNotNull("ObjectInfo selection null", oi.getSelection()); Assert.assertTrue("ObjectInfo should have at least one replica", oi.getReplicas().size() > 0); } @Test public void testHmac() throws Exception { // Compute the signature hash String input = "Hello World"; byte[] secret = Base64.decodeBase64("D7qsp4j16PBHWSiUbc/bt3lbPBY=".getBytes("UTF-8")); Mac mac = Mac.getInstance("HmacSHA1"); SecretKeySpec key = new SecretKeySpec(secret, "HmacSHA1"); mac.init(key); l4j.debug("Hashing: \n" + input.toString()); byte[] hashData = mac.doFinal(input.toString().getBytes("ISO-8859-1")); // Encode the hash in Base64. String hashOut = new String(Base64.encodeBase64(hashData), "UTF-8"); l4j.debug("Hash: " + hashOut); } @Test public void testDirectoryMetadata() throws Exception { ObjectPath dir = new ObjectPath("/" + rand8char() + "/"); MetadataList mlist = new MetadataList(); Metadata listable = new Metadata("listable", "foo", true); Metadata unlistable = new Metadata("unlistable", "bar", false); Metadata listable2 = new Metadata("listable2", "foo2 foo2", true); Metadata unlistable2 = new Metadata("unlistable2", "bar2 bar2", false); Metadata listable3 = new Metadata("listable3", null, true); //Metadata withCommas = new Metadata( "withcommas", "I, Robot", false ); //Metadata withEquals = new Metadata( "withequals", "name=value", false ); mlist.addMetadata(listable); mlist.addMetadata(unlistable); mlist.addMetadata(listable2); mlist.addMetadata(unlistable2); mlist.addMetadata(listable3); //mlist.addMetadata( withCommas ); //mlist.addMetadata( withEquals ); ObjectId id = this.esu.createObjectOnPath(dir, null, mlist, null, null); Assert.assertNotNull("null ID returned", id); cleanup.add(id); // Read and validate the metadata MetadataList meta = this.esu.getAllMetadata(dir).getMetadata(); Assert.assertEquals("value of 'listable' wrong", "foo", meta.getMetadata("listable").getValue()); Assert.assertEquals("value of 'listable2' wrong", "foo2 foo2", meta.getMetadata("listable2").getValue()); Assert.assertEquals("value of 'unlistable' wrong", "bar", meta.getMetadata("unlistable").getValue()); Assert.assertEquals("value of 'unlistable2' wrong", "bar2 bar2", meta.getMetadata("unlistable2").getValue()); Assert.assertNotNull("listable3 missing", meta.getMetadata("listable3")); Assert.assertTrue("Value of listable3 should be empty", meta.getMetadata("listable3").getValue() == null || meta.getMetadata("listable3").getValue().length() == 0); //Assert.assertEquals( "Value of withcommas wrong", "I, Robot", meta.getMetadata( "withcommas" ).getValue() ); //Assert.assertEquals( "Value of withequals wrong", "name=value", meta.getMetadata( "withequals" ).getValue() ); // Check listable flags Assert.assertEquals("'listable' is not listable", true, meta.getMetadata("listable").isListable()); Assert.assertEquals("'listable2' is not listable", true, meta.getMetadata("listable2").isListable()); Assert.assertEquals("'listable3' is not listable", true, meta.getMetadata("listable3").isListable()); Assert.assertEquals("'unlistable' is listable", false, meta.getMetadata("unlistable").isListable()); Assert.assertEquals("'unlistable2' is listable", false, meta.getMetadata("unlistable2").isListable()); } /** * Tests fetching data with a MultiExtent. */ //@Test public void testMultiExtent() throws Exception { String input = "Four score and seven years ago"; ObjectId id = esu.createObject(null, null, input.getBytes("UTF-8"), "text/plain"); cleanup.add(id); Assert.assertNotNull("Object null", id); MultiExtent me = new MultiExtent(); me.add(new Extent(27, 2)); //ag me.add(new Extent(9, 1)); // e me.add(new Extent(5, 1)); // s me.add(new Extent(4, 1)); // ' ' me.add(new Extent(27, 3)); // ago Assert.assertEquals("Extent string wrong", "bytes=27-28,9-9,5-5,4-4,27-29", me.toString()); byte[] data = esu.readObject(id, me, null); String out = new String(data, "UTF-8"); Assert.assertEquals("Content incorrect", "ages ago", out); } //---------- Features supported by the Atmos 2.0 REST API. ----------\\ // TODO: If this is not supported, remove it @Ignore("Turned off by default.") @Test public void testHardLink() throws Exception { Assume.assumeFalse(isVipr); ObjectPath op1 = new ObjectPath("/" + rand8char() + ".tmp"); ObjectPath op2 = new ObjectPath("/" + rand8char() + ".tmp"); ObjectId id = this.esu.createObjectOnPath(op1, null, null, "Four score and seven years ago".getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); l4j.info("nlink after create: " + this.esu.getSystemMetadata(op1, null).getMetadata("nlink").getValue()); // Rename this.esu.hardLink(op1, op2); l4j.info("nlink after hardlink: " + this.esu.getSystemMetadata(op1, null).getMetadata("nlink").getValue()); // Read back the content String content = new String(this.esu.readObject(op2, null, null), "UTF-8"); Assert.assertEquals("object content wrong", "Four score and seven years ago", content); this.esu.deleteObject(op2); l4j.info("nlink after delete: " + this.esu.getSystemMetadata(op1, null).getMetadata("nlink").getValue()); } @Test public void testGetShareableUrlAndDisposition() throws Exception { Assume.assumeFalse(isVipr); // Create an object with content. String str = "Four score and twenty years ago"; ObjectId id = this.esu.createObject(null, null, str.getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); cleanup.add(id); String disposition = "attachment; filename=\"foo bar.txt\""; Calendar c = Calendar.getInstance(); c.add(Calendar.HOUR, 4); Date expiration = c.getTime(); URL u = this.esu.getShareableUrl(id, expiration, disposition); l4j.debug("Sharable URL: " + u); InputStream stream = (InputStream) u.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(stream)); String content = br.readLine(); l4j.debug("Content: " + content); Assert.assertEquals("URL does not contain proper content", str, content.toString()); } @Test public void testGetShareableUrlWithPathAndDisposition() throws Exception { Assume.assumeFalse(isVipr); // Create an object with content. String str = "Four score and twenty years ago"; ObjectPath op = new ObjectPath("/" + rand8char() + ".txt"); ObjectId id = this.esu.createObjectOnPath(op, null, null, str.getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); //cleanup.add( op ); String disposition = "attachment; filename=\"foo bar.txt\""; Calendar c = Calendar.getInstance(); c.add(Calendar.HOUR, 4); Date expiration = c.getTime(); URL u = this.esu.getShareableUrl(op, expiration, disposition); l4j.debug("Sharable URL: " + u); InputStream stream = (InputStream) u.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(stream)); String content = br.readLine(); l4j.debug("Content: " + content); Assert.assertEquals("URL does not contain proper content", str, content.toString()); } @Test public void testGetShareableUrlWithPathAndUTF8Disposition() throws Exception { Assume.assumeFalse(isVipr); // Create an object with content. String str = "Four score and twenty years ago"; ObjectPath op = new ObjectPath("/" + rand8char() + ".txt"); ObjectId id = this.esu.createObjectOnPath(op, null, null, str.getBytes("UTF-8"), "text/plain"); Assert.assertNotNull("null ID returned", id); //cleanup.add( op ); // One cryllic, one accented, and one japanese character // RFC5987 String disposition = "attachment; filename=\"no UTF support.txt\"; filename*=UTF-8''" + URLEncoder.encode(".txt", "UTF-8"); Calendar c = Calendar.getInstance(); c.add(Calendar.HOUR, 4); Date expiration = c.getTime(); URL u = this.esu.getShareableUrl(op, expiration, disposition); l4j.debug("Sharable URL: " + u); InputStream stream = (InputStream) u.getContent(); BufferedReader br = new BufferedReader(new InputStreamReader(stream)); String content = br.readLine(); l4j.debug("Content: " + content); Assert.assertEquals("URL does not contain proper content", str, content.toString()); } @Test public void testGetServiceInformationFeatures() throws Exception { ServiceInformation info = this.esu.getServiceInformation(); l4j.info("Supported features: " + info.getFeatures()); Assert.assertTrue("Expected at least one feature", info.getFeatures().size() > 0); } @Test public void testBug23750() throws Exception { byte[] data = new byte[1000]; Arrays.fill(data, (byte) 0); MetadataList mdList = new MetadataList(); mdList.addMetadata(new Metadata("test", null, true)); Checksum sha1 = new Checksum(Checksum.Algorithm.SHA1); ObjectId oid = this.esu.createObject(null, mdList, data, null, sha1); try { Extent extent = new Extent(1000, 1000); Checksum sha0 = new Checksum(Checksum.Algorithm.SHA0); sha0.update(data, 0, 1000); this.esu.updateObject(oid, null, mdList, extent, data, null, sha0); Assert.fail("Should have triggered an exception"); } catch (EsuException e) { // expected } } @Test public void testCrudKeys() throws Exception { Assume.assumeFalse(isVipr); String keyPool = "Test_key-pool#@!$%^.."; String key = "KEY_TEST"; String content = "Hello World!"; byte[] data = content.getBytes("UTF-8"); ObjectId oid = this.esu.createObjectWithKey(keyPool, key, null, null, data, data.length, "text/plain"); Assert.assertNotNull("Null object ID returned", oid); String readContent = new String(this.esu.readObjectWithKey(keyPool, key, null, null), "UTF-8"); Assert.assertEquals("content mismatch", content, readContent); content = "Hello Waldo!"; data = content.getBytes("UTF-8"); this.esu.updateObjectWithKey(keyPool, key, null, null, null, data, null); readContent = new String(this.esu.readObjectWithKey(keyPool, key, null, null), "UTF-8"); Assert.assertEquals("content mismatch", content, readContent); this.esu.deleteObjectWithKey(keyPool, key); try { this.esu.readObjectWithKey(keyPool, key, null, null); Assert.fail("Object still exists"); } catch (EsuException e) { if (e.getHttpCode() != 404) throw e; } } @Test public void testIssue9() throws Exception { int threadCount = 10; final int objectSize = 10 * 1000 * 1000; // size is not a power of 2. final MetadataList list = new MetadataList(); list.addMetadata(new Metadata("test-data", null, true)); final EsuApi api = esu; final List<Identifier> cleanupList = cleanup; ThreadPoolExecutor executor = new ThreadPoolExecutor(threadCount, threadCount, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); try { for (int i = 0; i < threadCount; i++) { executor.execute(new Thread() { public void run() { ObjectId oid = api.createObjectFromStream(null, list, new RandomInputStream(objectSize), objectSize, null); cleanupList.add(oid); } }); } while (true) { Thread.sleep(1000); if (executor.getActiveCount() < 1) break; } } finally { executor.shutdown(); } } }