mirror of https://github.com/apache/jclouds.git
createContainer, deleteContainer, updates to container to parse metadata and accompany testcases.
Added handling of null ObjectName.
This commit is contained in:
parent
227dbf777a
commit
3d1a2dd7fa
|
@ -29,7 +29,7 @@ import com.google.common.base.Objects.ToStringHelper;
|
|||
/**
|
||||
* The base type for all objects in the CDMI model.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @author Kenneth Nagin
|
||||
*/
|
||||
public class CDMIObject {
|
||||
|
||||
|
@ -83,7 +83,8 @@ public class CDMIObject {
|
|||
}
|
||||
|
||||
protected B fromCDMIObject(CDMIObject in) {
|
||||
return objectID(in.getObjectID()).objectType(in.getObjectType()).objectName(in.getObjectName());
|
||||
return objectID(in.getObjectID()).objectType(in.getObjectType())
|
||||
.objectName(in.getObjectName());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,13 +100,18 @@ public class CDMIObject {
|
|||
|
||||
/**
|
||||
* Object ID of the object <br/>
|
||||
* Every object stored within a CDMI-compliant system shall have a globally unique object
|
||||
* identifier (ID) assigned at creation time. The CDMI object ID is a string with requirements
|
||||
* for how it is generated and how it obtains its uniqueness. Each offering that implements CDMI
|
||||
* is able to produce these identifiers without conflicting with other offerings.
|
||||
* Every object stored within a CDMI-compliant system shall have a globally
|
||||
* unique object identifier (ID) assigned at creation time. The CDMI object
|
||||
* ID is a string with requirements for how it is generated and how it
|
||||
* obtains its uniqueness. Each offering that implements CDMI is able to
|
||||
* produce these identifiers without conflicting with other offerings.
|
||||
*
|
||||
* note: CDMI Servers do not always support ObjectID tags, however
|
||||
* downstream jclouds code does not handle null so we return a empty String
|
||||
* instead.
|
||||
*/
|
||||
public String getObjectID() {
|
||||
return objectID;
|
||||
return (objectID == null) ? "" : objectID;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,15 +123,15 @@ public class CDMIObject {
|
|||
}
|
||||
|
||||
/**
|
||||
* For objects in a container, the objectName field shall be returned. For objects not in a
|
||||
* container (objects that are only accessible by ID), the objectName field shall not be
|
||||
* returned.
|
||||
* For objects in a container, the objectName field shall be returned. For
|
||||
* objects not in a container (objects that are only accessible by ID), the
|
||||
* objectName field shall not be returned.
|
||||
*
|
||||
* Name of the object
|
||||
*/
|
||||
@Nullable
|
||||
public String getObjectName() {
|
||||
return objectName;
|
||||
return (objectName == null) ? "" : objectName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -135,7 +141,8 @@ public class CDMIObject {
|
|||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
CDMIObject that = CDMIObject.class.cast(o);
|
||||
return equal(this.objectID, that.objectID) && equal(this.objectName, that.objectName)
|
||||
return equal(this.objectID, that.objectID)
|
||||
&& equal(this.objectName, that.objectName)
|
||||
&& equal(this.objectType, that.objectType);
|
||||
}
|
||||
|
||||
|
@ -159,7 +166,7 @@ public class CDMIObject {
|
|||
}
|
||||
|
||||
protected ToStringHelper string() {
|
||||
return Objects.toStringHelper("").add("objectID", objectID).add("objectName", objectName).add("objectType",
|
||||
objectType);
|
||||
return Objects.toStringHelper("").add("objectID", objectID)
|
||||
.add("objectName", objectName).add("objectType", objectType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,15 @@ package org.jclouds.snia.cdmi.v1.domain;
|
|||
import static com.google.common.base.Objects.equal;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.domain.JsonBall;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
@ -32,7 +38,7 @@ import com.google.common.collect.Maps;
|
|||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @author Kenneth Nagin
|
||||
*/
|
||||
public class Container extends CDMIObject {
|
||||
|
||||
|
@ -45,31 +51,35 @@ public class Container extends CDMIObject {
|
|||
return builder().fromContainer(this);
|
||||
}
|
||||
|
||||
public static class Builder<B extends Builder<B>> extends CDMIObject.Builder<B> {
|
||||
public static class Builder<B extends Builder<B>> extends
|
||||
CDMIObject.Builder<B> {
|
||||
|
||||
private Set<String> children = ImmutableSet.of();
|
||||
private Map<String, String> metadata = Maps.newHashMap();
|
||||
private Map<String, JsonBall> metadata = Maps.newHashMap();
|
||||
|
||||
/**
|
||||
* @see Container#getChildren()
|
||||
*/
|
||||
public B children(String... children) {
|
||||
return children(ImmutableSet.copyOf(checkNotNull(children, "children")));
|
||||
return children(ImmutableSet.copyOf(checkNotNull(children,
|
||||
"children")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Container#getChildren()
|
||||
*/
|
||||
public B children(Set<String> children) {
|
||||
this.children = ImmutableSet.copyOf(checkNotNull(children, "children"));
|
||||
this.children = ImmutableSet.copyOf(checkNotNull(children,
|
||||
"children"));
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Container#getMetadata()
|
||||
*/
|
||||
public B metadata(Map<String, String> metadata) {
|
||||
this.metadata = ImmutableMap.copyOf(checkNotNull(metadata, "metadata"));
|
||||
public B metadata(Map<String, JsonBall> metadata) {
|
||||
this.metadata = ImmutableMap.copyOf(checkNotNull(metadata,
|
||||
"metadata"));
|
||||
return self();
|
||||
}
|
||||
|
||||
|
@ -79,7 +89,8 @@ public class Container extends CDMIObject {
|
|||
}
|
||||
|
||||
public B fromContainer(Container in) {
|
||||
return fromCDMIObject(in).children(in.getChildren()).metadata(in.getMetadata());
|
||||
return fromCDMIObject(in).children(in.getChildren()).metadata(
|
||||
in.getMetadata());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,30 +98,116 @@ public class Container extends CDMIObject {
|
|||
}
|
||||
|
||||
private final Set<String> children;
|
||||
private final Map<String, String> metadata;
|
||||
private final Map<String, JsonBall> metadata;
|
||||
|
||||
private Map<String, String> userMetaDataIn;
|
||||
private Map<String, String> systemMetaDataIn;
|
||||
private List<Map<String, String>> aclMetaDataIn;
|
||||
|
||||
protected Container(Builder<?> builder) {
|
||||
super(builder);
|
||||
this.children = ImmutableSet.copyOf(checkNotNull(builder.children, "children"));
|
||||
this.metadata = ImmutableMap.copyOf(checkNotNull(builder.metadata, "metadata"));
|
||||
this.children = ImmutableSet.copyOf(checkNotNull(builder.children,
|
||||
"children"));
|
||||
this.metadata = ImmutableMap.copyOf(checkNotNull(builder.metadata,
|
||||
"metadata"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Names of the children objects in the container object. Child container objects end with "/".
|
||||
* Names of the children objects in the container object. Child container
|
||||
* objects end with "/".
|
||||
*/
|
||||
public Set<String> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata for the container object. This field includes any user and data system metadata
|
||||
* specified in the request body metadata field, along with storage system metadata generated by
|
||||
* the cloud storage system.
|
||||
* Metadata for the container object. This field includes any user and
|
||||
* system metadata specified in the request body metadata field, along with
|
||||
* storage system metadata generated by the cloud storage system.
|
||||
*/
|
||||
public Map<String, String> getMetadata() {
|
||||
public Map<String, JsonBall> getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse Metadata for the container object from the original JsonBall.
|
||||
* System metadata data is prefixed with cdmi. System ACL metadata data is
|
||||
* prefixed with cdmi_acl
|
||||
*
|
||||
*/
|
||||
private void parseMetadata() {
|
||||
userMetaDataIn = new HashMap<String, String>();
|
||||
systemMetaDataIn = new HashMap<String, String>();
|
||||
aclMetaDataIn = new ArrayList<Map<String, String>>();
|
||||
Iterator<String> keys = metadata.keySet().iterator();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
JsonBall value = metadata.get(key);
|
||||
if (key.startsWith("cdmi")) {
|
||||
if (key.matches("cdmi_acl")) {
|
||||
String[] cdmi_acl_array = value.toString().split("[{}]");
|
||||
for (int i = 0; i < cdmi_acl_array.length; i++) {
|
||||
if (!(cdmi_acl_array[i].startsWith("[")
|
||||
|| cdmi_acl_array[i].startsWith("]") || cdmi_acl_array[i]
|
||||
.startsWith(","))) {
|
||||
HashMap<String, String> aclMap = new HashMap<String, String>();
|
||||
String[] cdmi_acl_member = cdmi_acl_array[i]
|
||||
.split(",");
|
||||
for (String s : cdmi_acl_member) {
|
||||
String cdmi_acl_key = s.substring(0,
|
||||
s.indexOf(":"));
|
||||
String cdmi_acl_value = s.substring(s
|
||||
.indexOf(":") + 1);
|
||||
cdmi_acl_value.replace('"', ' ').trim();
|
||||
aclMap.put(cdmi_acl_key, cdmi_acl_value);
|
||||
}
|
||||
aclMetaDataIn.add(aclMap);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
systemMetaDataIn.put(key, value.toString()
|
||||
.replace('"', ' ').trim());
|
||||
}
|
||||
} else {
|
||||
userMetaDataIn.put(key, value.toString().replace('"', ' ')
|
||||
.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get User Metadata for the container object. This field includes any user
|
||||
* metadata
|
||||
*/
|
||||
public Map<String, String> getUserMetadata() {
|
||||
if (userMetaDataIn == null) {
|
||||
parseMetadata();
|
||||
}
|
||||
return userMetaDataIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get System Metadata for the container object excluding ACL related
|
||||
* metadata
|
||||
*/
|
||||
public Map<String, String> getSystemMetadata() {
|
||||
if (systemMetaDataIn == null) {
|
||||
parseMetadata();
|
||||
}
|
||||
return systemMetaDataIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get System Metadata for the container object excluding ACL related
|
||||
* metadata
|
||||
*/
|
||||
public List<Map<String, String>> getACLMetadata() {
|
||||
if (aclMetaDataIn == null) {
|
||||
parseMetadata();
|
||||
}
|
||||
return aclMetaDataIn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
|
@ -118,7 +215,8 @@ public class Container extends CDMIObject {
|
|||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
Container that = Container.class.cast(o);
|
||||
return super.equals(that) && equal(this.children, that.children) && equal(this.metadata, that.metadata);
|
||||
return super.equals(that) && equal(this.children, that.children)
|
||||
&& equal(this.metadata, that.metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -128,7 +226,8 @@ public class Container extends CDMIObject {
|
|||
|
||||
@Override
|
||||
public ToStringHelper string() {
|
||||
return super.string().add("children", children).add("metadata", metadata);
|
||||
return super.string().add("children", children)
|
||||
.add("metadata", metadata);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
package org.jclouds.snia.cdmi.v1.features;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
|
@ -40,7 +43,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
* Container Object Resource Operations
|
||||
*
|
||||
* @see ContainerClient
|
||||
* @author Adrian Cole
|
||||
* @author Kenneth Nagin
|
||||
* @see <a href="http://www.snia.org/cdmi">api doc</a>
|
||||
*/
|
||||
@SkipEncoding( { '/', '=' })
|
||||
|
@ -57,4 +60,24 @@ public interface ContainerAsyncClient {
|
|||
@Path("/{containerName}/")
|
||||
ListenableFuture<Container> getContainer(@PathParam("containerName") String containerName);
|
||||
|
||||
/**
|
||||
* @see ContainerClient#createContainer
|
||||
*/
|
||||
@PUT
|
||||
@Consumes( { ObjectTypes.CONTAINER, MediaType.APPLICATION_JSON })
|
||||
@Produces( { ObjectTypes.CONTAINER})
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
@Path("/{containerName}/")
|
||||
ListenableFuture<Container> createContainer(@PathParam("containerName") String containerName);
|
||||
|
||||
/**
|
||||
* @see ContainerClient#createContainer()
|
||||
*/
|
||||
@DELETE
|
||||
// @Consumes( { ObjectTypes.CONTAINER, MediaType.APPLICATION_JSON })
|
||||
@Consumes( MediaType.APPLICATION_JSON )
|
||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
@Path("/{containerName}/")
|
||||
ListenableFuture<Void> deleteContainer(@PathParam("containerName") String containerName);
|
||||
|
||||
}
|
||||
|
|
|
@ -27,12 +27,15 @@ import org.jclouds.snia.cdmi.v1.domain.Container;
|
|||
* Container Object Resource Operations
|
||||
*
|
||||
* @see ContainerAsyncClient
|
||||
* @author Adrian Cole
|
||||
* @author Kenneth Nagin
|
||||
* @see <a href="http://www.snia.org/cdmi">api doc</a>
|
||||
*/
|
||||
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
|
||||
public interface ContainerClient {
|
||||
Container createContainer(String containerName);
|
||||
|
||||
Container getContainer(String containerName);
|
||||
|
||||
void deleteContainer(String containerName);
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ package org.jclouds.snia.cdmi.v1.features;
|
|||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jclouds.snia.cdmi.v1.ObjectTypes;
|
||||
import org.jclouds.snia.cdmi.v1.domain.Container;
|
||||
import org.jclouds.snia.cdmi.v1.internal.BaseCDMIClientLiveTest;
|
||||
|
@ -28,21 +32,49 @@ import org.testng.annotations.Test;
|
|||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @author Kenneth Nagin
|
||||
*/
|
||||
@Test(groups = "live", testName = "ContainerClientLiveTest")
|
||||
public class ContainerClientLiveTest extends BaseCDMIClientLiveTest {
|
||||
|
||||
@Test
|
||||
public void testGetContainer() throws Exception {
|
||||
public void testCreateContainer() throws Exception {
|
||||
String pContainerName = "MyContainer" + System.currentTimeMillis();
|
||||
ContainerClient client = cdmiContext.getApi().getContainerClient();
|
||||
Container container = client.getContainer("TODO: figure out how to list containers");
|
||||
Logger.getAnonymousLogger().info("createContainer: " + pContainerName);
|
||||
Container container = client.createContainer(pContainerName);
|
||||
assertNotNull(container);
|
||||
System.out.println(container);
|
||||
Logger.getAnonymousLogger().info("getContainer: " + pContainerName);
|
||||
container = client.getContainer(pContainerName);
|
||||
assertNotNull(container);
|
||||
System.out.println(container);
|
||||
assertEquals(container.getObjectType(), ObjectTypes.CONTAINER);
|
||||
assertNotNull(container.getObjectID());
|
||||
assertNotNull(container.getObjectName());
|
||||
assertEquals(container.getObjectName(), pContainerName + "/");
|
||||
assertNotNull(container.getChildren());
|
||||
assertEquals(container.getChildren().isEmpty(), true);
|
||||
System.out.println("Children: " + container.getChildren());
|
||||
assertNotNull(container.getMetadata());
|
||||
assertNotNull(container.getUserMetadata());
|
||||
System.out.println("UserMetaData: " + container.getUserMetadata());
|
||||
assertNotNull(container.getSystemMetadata());
|
||||
System.out.println("SystemMetaData: " + container.getSystemMetadata());
|
||||
assertNotNull(container.getACLMetadata());
|
||||
List<Map<String, String>> aclMetadataOut = container.getACLMetadata();
|
||||
System.out.println("ACLMetaData: ");
|
||||
for (Map<String, String> aclMap : aclMetadataOut) {
|
||||
System.out.println(aclMap);
|
||||
}
|
||||
container = client.getContainer("/");
|
||||
System.out.println("root container: " + container);
|
||||
assertEquals(container.getChildren().contains(pContainerName + "/"), true);
|
||||
Logger.getAnonymousLogger().info("deleteContainer: " + pContainerName);
|
||||
client.deleteContainer(pContainerName);
|
||||
container = client.getContainer("/");
|
||||
System.out.println("root container: " + container);
|
||||
assertEquals(container.getChildren().contains(pContainerName + "/"), false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.snia.cdmi.v1.parse;
|
|||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.domain.JsonBall;
|
||||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.jclouds.snia.cdmi.v1.domain.Container;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -30,7 +31,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
* @author Kenneth Nagin
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ParseContainerTest")
|
||||
public class ParseContainerTest extends BaseItemParserTest<Container> {
|
||||
|
@ -47,8 +48,8 @@ public class ParseContainerTest extends BaseItemParserTest<Container> {
|
|||
.objectType("application/cdmi-container")
|
||||
.objectID("00007E7F00102E230ED82694DAA975D2")
|
||||
.objectName("MyContainer/")
|
||||
.metadata(ImmutableMap.<String, String>builder()
|
||||
.put("cdmi_size", "83")
|
||||
.metadata(ImmutableMap.<String, JsonBall>builder()
|
||||
.put("cdmi_size", new JsonBall("\"83\""))
|
||||
.build())
|
||||
.children(ImmutableSet.<String>builder()
|
||||
.add("MyDataObject.txt")
|
||||
|
|
Loading…
Reference in New Issue