Skip to content

Commit

Permalink
- added deleteSubtenant call (only on ECS and only when subtenant is …
Browse files Browse the repository at this point in the history
…completely empty

- added create object with custom object ID (ECS)
- added create subtenant with custom subtenant ID (ECS)
  • Loading branch information
arnett, stu committed Oct 4, 2016
1 parent 8aee11a commit 2e7f043
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 31 deletions.
8 changes: 4 additions & 4 deletions readme.tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

Configuration
-------------
Before running the testcases, a file named vipr.properties must be either put on the
Before running the testcases, a file named test.properties must be either put on the
classpath (e.g. src/test/resources) or present in your home directory. The file should
contain the following configuration keys:

Atmos:
vipr.atmos.uid - Atmos full token uid (e.g. 123daba33425413251/user1)
vipr.atmos.secret_key - Shared secret key for the uid
vipr.atmos.endpoints - Comma separated list of endpoint URIs (more than one is optional)
atmos.uid - Atmos full token uid (e.g. 123daba33425413251/user1)
atmos.secret - Shared secret key for the uid
atmos.endpoints - Comma separated list of endpoint URIs (more than one is optional)

ACDP:
acdp.admin.endpoint - ACDP admin endpoint, usually http://admin_node:8080/
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/com/emc/atmos/api/AtmosApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -505,11 +505,17 @@ <T> GenericResponse<T> execute( PreSignedRequest request, Class<T> resultType, O
throws URISyntaxException;

/**
* Creates a new Atmos Subtenant in EMC ViPR. This operation is not supported on
* Creates a new Atmos Subtenant in ECS. This operation is not supported on
* pure Atmos systems.
* @param request The {@link CreateSubtenantRequest} containing the parameters for
* the new subtenant.
* @return The ID of the new subtenant, e.g. "75077194912140aaa95911c237103695"
*/
String createSubtenant(CreateSubtenantRequest request);

/**
* Deletes an Atmos Subtenant in ECS. This operation is not supported on pure Atmos systems.
* Note: the subtenant must be completely empty before deleting.
*/
void deleteSubtenant(String subtenantId);
}
3 changes: 2 additions & 1 deletion src/main/java/com/emc/atmos/api/RestUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@ public final class RestUtil {
public static final String XHEADER_LISTABLE_META = "x-emc-listable-meta";
public static final String XHEADER_LISTABLE_TAGS = "x-emc-listable-tags";
public static final String XHEADER_META = "x-emc-meta";
public static final String XHEADER_OBJECT_ID = "x-emc-object-id";
public static final String XHEADER_OBJECTID = "x-emc-objectid";
public static final String XHEADER_PATH = "x-emc-path";
public static final String XHEADER_POOL = "x-emc-pool";
public static final String XHEADER_RETENTION_PERIOD = "x-emc-retention-period";
public static final String XHEADER_RETENTION_POLICY = "x-emc-retention-policy";
public static final String XHEADER_SIGNATURE = "x-emc-signature";
public static final String XHEADER_SUBTENANT_ID = "x-emc-subtenant-id";
public static final String XHEADER_SUPPORT_UTF8 = "x-emc-support-utf8";
public static final String XHEADER_SYSTEM_TAGS = "x-emc-system-tags";
public static final String XHEADER_TAGS = "x-emc-tags";
Expand All @@ -73,7 +75,6 @@ public final class RestUtil {
public static final String XHEADER_UTF8 = "x-emc-utf8";
public static final String XHEADER_VERSION_OID = "x-emc-version-oid";
public static final String XHEADER_WSCHECKSUM = "x-emc-wschecksum";
public static final String XHEADER_PROJECT = "x-emc-project-id";
public static final String XHEADER_OBJECT_VPOOL = "x-emc-vpool";

public static final String TYPE_MULTIPART = "multipart";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1133,14 +1133,22 @@ public <T> GenericResponse<T> execute(PreSignedRequest request,
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}

/*
/**
* @see com.emc.atmos.api.AtmosApi#createSubtenant(com.emc.atmos.api.request.CreateSubtenantRequest)
*/
@Override
public String createSubtenant(CreateSubtenantRequest request) {
return delegate.createSubtenant(request);
}

/**
* @see com.emc.atmos.api.AtmosApi#deleteSubtenant(String)
*/
@Override
public void deleteSubtenant( String subtenantId ) {
delegate.deleteSubtenant( subtenantId );
}

/**
* @return the bufferSize
*/
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/emc/atmos/api/jersey/AtmosApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -729,4 +729,8 @@ public String createSubtenant(CreateSubtenantRequest request) {
return response.getHeaders().get("subtenantID").get(0);
}

@Override
public void deleteSubtenant( String subtenantId ) {
client.resource( config.resolvePath( "subtenant/" + subtenantId, null ) ).delete();
}
}
33 changes: 33 additions & 0 deletions src/main/java/com/emc/atmos/api/request/CreateObjectRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,33 @@
*/
package com.emc.atmos.api.request;

import com.emc.atmos.api.RestUtil;

import java.util.List;
import java.util.Map;

/**
* Represents a create object request.
*/
public class CreateObjectRequest extends PutObjectRequest<CreateObjectRequest> {
private String customObjectId;

@Override
public String getServiceRelativePath() {
if ( identifier == null ) return "objects";
else return identifier.getRelativeResourcePath();
}

@Override
public Map<String, List<Object>> generateHeaders() {
Map<String, List<Object>> headers = super.generateHeaders();

// custom object ID
if ( getCustomObjectId() != null ) RestUtil.addValue( headers, RestUtil.XHEADER_OBJECT_ID, customObjectId );

return headers;
}

@Override
public String getMethod() {
return "POST";
Expand All @@ -45,4 +62,20 @@ public String getMethod() {
protected CreateObjectRequest me() {
return this;
}

public String getCustomObjectId() {
return customObjectId;
}

public void setCustomObjectId(String customObjectId) {
this.customObjectId = customObjectId;
}

/**
* Builder method for {@link #setCustomObjectId(String)}
*/
public CreateObjectRequest customObjectId( String customObjectId ) {
setCustomObjectId( customObjectId );
return this;
}
}
45 changes: 21 additions & 24 deletions src/main/java/com/emc/atmos/api/request/CreateSubtenantRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
import com.emc.atmos.api.RestUtil;

/**
* Represents a request to create a new Atmos Subtenant in EMC ViPR.
* Represents a request to create a new Atmos Subtenant in EMC ECS.
*/
public class CreateSubtenantRequest extends Request {
private String projectId;
private String objectVirtualPoolId;
private String customSubtenantId;

public CreateSubtenantRequest() {
}
Expand All @@ -56,34 +56,17 @@ public String getMethod() {
@Override
public Map<String, List<Object>> generateHeaders() {
Map<String, List<Object>> headers = new HashMap<String, List<Object>>();
if(projectId != null) {
headers.put(RestUtil.XHEADER_PROJECT, Arrays.asList(new Object[]{ projectId }));
}
if(objectVirtualPoolId != null) {
headers.put(RestUtil.XHEADER_OBJECT_VPOOL,
Arrays.asList(new Object[]{ objectVirtualPoolId }));

}
if(customSubtenantId != null) {
headers.put(RestUtil.XHEADER_SUBTENANT_ID, Arrays.asList(new Object[]{ customSubtenantId }));
}
return headers;
}

/**
* Gets the ViPR Project ID for this request. May be null.
*/
public String getProjectId() {
return projectId;
}

/**
* Sets the ViPR Project ID for the new subtenant. If null, the default project
* for the current tenant's namespace will be used. If null and the namespace does
* not have a default project the request will fail.
* @param project the ID (a URN) of the project for the new subtenant.
*/
public void setProjectId(String project) {
this.projectId = project;
}

/**
* Gets the virtual pool ID for this request. May be null.
*/
Expand All @@ -92,13 +75,27 @@ public String getObjectVirtualPoolId() {
}

/**
* Sets the ViPR Object Virtual Pool ID for the new namespace. If null, the default
* object virtual pool for the current tenant's namespace will be used.
* Sets the ECS Object Virtual Pool ID for the new subtenant. If null, the default
* object virtual pool for the user's namespace will be used.
* @param objectVirtualPoolId the ID (a URN) of the Object Virtual Pool for the new
* subtenant.
*/
public void setObjectVirtualPoolId(String objectVirtualPoolId) {
this.objectVirtualPoolId = objectVirtualPoolId;
}

/**
* Gets the custom subtenant ID for this request. May be null.
*/
public String getCustomSubtenantId() {
return customSubtenantId;
}

/**
* Sets a custom subtenant ID for the new subtenant. Used to migrate legacy Atmos subtenants from an existing
* installation. Do not use unless migrating from a legacy subtenant!
*/
public void setCustomSubtenantId(String customSubtenantId) {
this.customSubtenantId = customSubtenantId;
}
}
36 changes: 36 additions & 0 deletions src/test/java/com/emc/atmos/api/test/AtmosApiClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,31 @@ public void testUtf8JavaEncoding() throws Exception {
oneByteCharacters + twoByteEscaped + fourByteEscaped );
}

@Test
public void testCreateSubtenant() throws Exception {
Assume.assumeTrue(isEcs);

String subtenantId = this.api.createSubtenant(new CreateSubtenantRequest());
l4j.warn("Subtenant ID: " + subtenantId);
Assert.assertNotNull(subtenantId);

this.api.deleteSubtenant(subtenantId);
}

@Test
public void testCreateSubtenantWithCustomId() throws Exception {
Assume.assumeTrue(isEcs);

String customId = "15f570b8be2942c0b400a6b7cbfa03b5";
CreateSubtenantRequest request = new CreateSubtenantRequest();
request.setCustomSubtenantId(customId);

String subtenantId = this.api.createSubtenant(request);
this.api.deleteSubtenant(subtenantId);

Assert.assertEquals(customId, subtenantId);
}

/**
* Test creating one empty object. No metadata, no content.
*/
Expand Down Expand Up @@ -208,6 +233,17 @@ public void testCreateEmptyObjectOnPath() throws Exception {
Assert.assertEquals( "object content wrong when reading by id", "", content );
}

@Test
public void testCreateEmptyObjectWithCustomId() throws Exception {
Assume.assumeTrue(isEcs);

String oid = "574e49dea38dc7990574e55963a183057e59f370da57";
CreateObjectResponse response = this.api.createObject(new CreateObjectRequest().customObjectId(oid).content(""));
cleanup.add(response.getObjectId());
Assert.assertEquals(oid, response.getObjectId().getId());

this.api.getObjectMetadata(new ObjectId(oid)); // will throw an error if the ID doesn't exist
}

/**
* Tests using some extended characters when creating on a path. This particular test
Expand Down
5 changes: 5 additions & 0 deletions src/test/resources/log4j.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
<logger name="org.apache">
<level value="WARN"></level>
</logger>
<!--
<logger name="org.apache.http.wire">
<level value="DEBUG"></level>
</logger>
-->

<root>
<priority value="WARN" />
Expand Down

0 comments on commit 2e7f043

Please sign in to comment.