/*
* Copyright (c) 2013 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.api.service;
import com.emc.storageos.model.project.ProjectElement;
import com.emc.storageos.model.project.ProjectParam;
import com.emc.storageos.model.search.SearchResultResourceRep;
import com.emc.storageos.model.BulkIdParam;
import com.emc.storageos.model.TaskResourceRep;
import com.emc.storageos.api.service.impl.resource.utils.InternalFileServiceClient;
import com.emc.storageos.api.service.impl.resource.utils.InternalNetworkClient;
import com.emc.storageos.coordinator.client.service.impl.CoordinatorClientImpl;
import com.emc.storageos.model.file.FileShareBulkRep;
import com.emc.storageos.model.file.FileShareRestRep;
import com.emc.storageos.model.file.FileSystemDeleteParam;
import com.emc.storageos.model.file.FileSystemExportParam;
import com.emc.storageos.model.file.FileSystemParam;
import com.emc.storageos.model.tenant.TenantResponse;
import com.emc.storageos.model.varray.NetworkEndpointParam;
import com.emc.storageos.model.varray.NetworkRestRep;
import com.emc.storageos.model.auth.*;
import com.emc.storageos.security.authentication.StorageOSUser;
import com.emc.storageos.security.helpers.ClientRequestHelper;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.xml.bind.annotation.XmlRootElement;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Tests internal api - requires some manual configuration
* depends on device setup from sanity test
*/
@SuppressWarnings("deprecation")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:coordinatorclient-var.xml" })
public class InternalApiTest extends ApiTestBase {
private String _server = "localhost";
private String _apiServer = "https://" + _server + ":8443";
private URI _cosId;
private URI _nhId;
private URI _networkId;
private URI _rootTenantId;
private String _rootToken;
private InternalFileServiceClient _internalFileClient;
private InternalNetworkClient _internalNetworkClient;
private ClientRequestHelper _requestHelper;
private Client _client;
@Autowired
private CoordinatorClientImpl _coordinatorClient;
@XmlRootElement(name = "results")
public static class Resources {
public List<SearchResultResourceRep> resource;
}
@Before
public void setup() throws Exception {
_requestHelper = new ClientRequestHelper(_coordinatorClient);
_client = _requestHelper.createClient();
_internalFileClient = new InternalFileServiceClient();
_internalFileClient.setCoordinatorClient(_coordinatorClient);
_internalFileClient.setServer(_server);
_internalNetworkClient = new InternalNetworkClient();
_internalNetworkClient.setCoordinatorClient(_coordinatorClient);
_internalNetworkClient.setServer(_server);
List<String> urls = new ArrayList<String>();
urls.add(_apiServer);
rSys = createHttpsClient(SYSADMIN, SYSADMIN_PASS_WORD, urls);
TenantResponse tenantResp = rSys.path("/tenant")
.get(TenantResponse.class);
_rootTenantId = tenantResp.getTenant();
_rootToken = (String) _savedTokens.get("root");
// find a CoS to use
Resources results = rSys.path("/file/vpools/search").queryParam("name", "cosisi")
.get(Resources.class);
Assert.assertTrue(results.resource.iterator().hasNext());
_cosId = results.resource.iterator().next().getId();
String cosAclUrl = "/file/vpools/" + _cosId.toString() + "/acl";
ACLAssignmentChanges changes = new ACLAssignmentChanges();
ACLEntry entry1 = new ACLEntry();
entry1.setTenant(_rootTenantId.toString());
entry1.getAces().add("USE");
changes.getAdd().add(entry1);
ClientResponse resp = rSys.path(cosAclUrl)
.put(ClientResponse.class, changes);
Assert.assertEquals(200, resp.getStatus());
// find a nh to use
results = rSys.path("/vdc/varrays/search").queryParam("name", "nh")
.get(Resources.class);
Assert.assertTrue(results.resource.iterator().hasNext());
_nhId = results.resource.iterator().next().getId();
String nhAclUrl = "/vdc/varrays/" + _nhId.toString() + "/acl";
resp = rSys.path(nhAclUrl)
.put(ClientResponse.class, changes);
Assert.assertEquals(200, resp.getStatus());
// find a network to use
results = rSys.path("/vdc/networks/search").queryParam("name", "iptz")
.get(Resources.class);
Assert.assertTrue(results.resource.iterator().hasNext());
_networkId = results.resource.iterator().next().getId();
}
@Test
/**
* This test exercises only the server side functionaly, not the internal client
* @throws Exception
*/
public void testInternalFileService() throws Exception {
// create fs
FileSystemParam fsparam = new FileSystemParam();
fsparam.setVpool(_cosId);
fsparam.setLabel("test-internalapi-" + System.currentTimeMillis());
fsparam.setVarray(_nhId);
fsparam.setSize("20971520");
URI path = URI.create(_apiServer).resolve("/internal/file/filesystems");
WebResource rRoot = _client.resource(path);
WebResource.Builder rBuilder = _requestHelper.addSignature(rRoot);
TaskResourceRep resp = _requestHelper.addToken(rBuilder, _rootToken)
.post(TaskResourceRep.class, fsparam);
Assert.assertTrue(resp != null);
Assert.assertNotNull(resp.getOpId());
Assert.assertNotNull(resp.getResource());
String fsId = resp.getResource().getId().toString();
String opId = resp.getOpId();
// GET filesystem
path = URI.create(_apiServer).resolve("/internal/file/filesystems/" + fsId);
rRoot = _client.resource(path);
rBuilder = _requestHelper.addSignature(rRoot);
ClientResponse response = _requestHelper.addToken(rBuilder, _rootToken)
.get(ClientResponse.class);
Assert.assertTrue(response != null);
Assert.assertEquals(200, response.getStatus());
// wait for the create to finish
path = URI.create(_apiServer).resolve("/internal/file/filesystems/" + fsId + "/tasks/" + opId);
int checkCount = 1200;
String status;
do {
// wait upto ~2 minute for fs creation
Thread.sleep(100);
rRoot = _client.resource(path);
TaskResourceRep fsResp = _requestHelper.addSignature(rRoot)
.get(TaskResourceRep.class);
status = fsResp.getState();
} while (status.equals("pending") && checkCount-- > 0);
if (!status.equals("ready")) {
Assert.assertTrue("Fileshare create timed out", false);
}
// export
path = URI.create(_apiServer).resolve("/internal/file/filesystems/" + fsId + "/exports");
FileSystemExportParam export = new FileSystemExportParam();
export.setPermissions("root");
export.setRootUserMapping("root");
export.setProtocol("NFS");
export.setEndpoints(new ArrayList<String>());
export.getEndpoints().add("www.ford.com");
rRoot = _client.resource(path);
rBuilder = _requestHelper.addSignature(rRoot);
resp = _requestHelper.addToken(rBuilder, _rootToken)
.post(TaskResourceRep.class, export);
opId = resp.getOpId();
// wait for the export to finish
path = URI.create(_apiServer).resolve("/internal/file/filesystems/" + fsId + "/tasks/" + opId);
do {
// wait upto ~2 minute for fs creation
Thread.sleep(100);
rRoot = _client.resource(path);
TaskResourceRep fsResp = _requestHelper.addSignature(rRoot)
.get(TaskResourceRep.class);
status = fsResp.getState();
} while (status.equals("pending") && checkCount-- > 0);
if (!status.equals("ready")) {
Assert.assertTrue("Fileshare export timed out", false);
}
// unexport
String unexportPath = String.format("/internal/file/filesystems/%s/exports/%s,%s,%s,%s",
fsId, export.getProtocol(), export.getSecurityType(), export.getPermissions(), export.getRootUserMapping());
path = URI.create(_apiServer).resolve(unexportPath);
rRoot = _client.resource(path);
rBuilder = _requestHelper.addSignature(rRoot);
resp = _requestHelper.addToken(rBuilder, _rootToken)
.delete(TaskResourceRep.class, export);
opId = resp.getOpId();
// wait for the unexport to finish
path = URI.create(_apiServer).resolve("/internal/file/filesystems/" + fsId + "/tasks/" + opId);
do {
// wait upto ~2 minute for fs creation
Thread.sleep(100);
rRoot = _client.resource(path);
TaskResourceRep fsResp = _requestHelper.addSignature(rRoot)
.get(TaskResourceRep.class);
status = fsResp.getState();
} while (status.equals("pending") && checkCount-- > 0);
if (!status.equals("ready")) {
Assert.assertTrue("Fileshare unexport timed out", false);
}
// delete
path = URI.create(_apiServer).resolve("/internal/file/filesystems/" + fsId + "/deactivate");
FileSystemDeleteParam deleteParam = new FileSystemDeleteParam();
deleteParam.setForceDelete(false);
rRoot = _client.resource(path);
rBuilder = _requestHelper.addSignature(rRoot);
resp = _requestHelper.addToken(rBuilder, _rootToken)
.post(TaskResourceRep.class, deleteParam);
Assert.assertTrue(resp != null);
}
@Test
/**
* This test exercises both server side and internal client
* @throws Exception
*/
public void testFileServiceUsingInternalClient() throws Exception {
// create fs
FileSystemParam fsparam = new FileSystemParam();
fsparam.setVpool(_cosId);
fsparam.setLabel("test-internalapi-" + System.currentTimeMillis());
fsparam.setVarray(_nhId);
fsparam.setSize("20971520");
TaskResourceRep resp = _internalFileClient.createFileSystem(fsparam, _rootToken);
Assert.assertTrue(resp != null);
Assert.assertNotNull(resp.getOpId());
Assert.assertNotNull(resp.getResource());
URI fsId = resp.getResource().getId();
String opId = resp.getOpId();
// GET filesystem - no method on the client for this?
WebResource rRoot = _requestHelper.createRequest(_client, _apiServer, "/internal/file/filesystems/" + fsId);
WebResource.Builder rBuilder = _requestHelper.addSignature(rRoot);
ClientResponse response = _requestHelper.addToken(rBuilder, _rootToken)
.get(ClientResponse.class);
Assert.assertTrue(response != null);
Assert.assertEquals(200, response.getStatus());
// wait for the create to finish
int checkCount = 1200;
String status;
do {
// wait upto ~2 minute for fs creation
Thread.sleep(100);
TaskResourceRep fsResp = _internalFileClient.getTaskStatus(fsId, opId);
status = fsResp.getState();
} while (status.equals("pending") && checkCount-- > 0);
if (!status.equals("ready")) {
Assert.assertTrue("Fileshare create timed out", false);
}
// export
FileSystemExportParam export = new FileSystemExportParam();
export.setPermissions("root");
export.setRootUserMapping("root");
export.setProtocol("NFS");
export.setEndpoints(new ArrayList<String>());
export.getEndpoints().add("www.ford.com");
resp = _internalFileClient.exportFileSystem(fsId, export);
opId = resp.getOpId();
// wait for the export to finish
do {
// wait upto ~2 minute for fs creation
Thread.sleep(100);
TaskResourceRep fsResp = _internalFileClient.getTaskStatus(fsId, opId);
status = fsResp.getState();
} while (status.equals("pending") && checkCount-- > 0);
if (!status.equals("ready")) {
Assert.assertTrue("Fileshare export timed out", false);
}
// unexport
resp = _internalFileClient.unexportFileSystem(fsId, export.getProtocol(), export.getSecurityType(), export.getPermissions(),
export.getRootUserMapping(), null);
opId = resp.getOpId();
// wait for the unexport to finish
do {
// wait upto ~2 minute for fs creation
Thread.sleep(100);
TaskResourceRep fsResp = _internalFileClient.getTaskStatus(fsId, opId);
status = fsResp.getState();
} while (status.equals("pending") && checkCount-- > 0);
if (!status.equals("ready")) {
Assert.assertTrue("Fileshare unexport timed out", false);
}
// delete
FileSystemDeleteParam deleteParam = new FileSystemDeleteParam();
deleteParam.setForceDelete(false);
resp = _internalFileClient.deactivateFileSystem(fsId, _rootToken, deleteParam);
Assert.assertTrue(resp != null);
}
@Test
public void testFSReleaseUsingInternalClient() throws Exception {
// get tenant
TenantResponse tenant = rSys.path("/tenant").get(TenantResponse.class);
Assert.assertNotNull(tenant);
// create a project to host a normal file system
ProjectParam projectParam = new ProjectParam();
projectParam.setName("test-internalapi-" + System.currentTimeMillis());
ProjectElement projectResp = rSys.path("/tenants/" + tenant.getTenant().toString() + "/projects")
.post(ProjectElement.class, projectParam);
Assert.assertNotNull(projectResp);
// create a normal file system which we can then release
FileSystemParam fsparam = new FileSystemParam();
fsparam.setVpool(_cosId);
fsparam.setLabel("test-internalapi-" + System.currentTimeMillis());
fsparam.setVarray(_nhId);
fsparam.setSize("20971520");
TaskResourceRep taskResp = rSys.path("/file/filesystems").queryParam("project", projectResp.getId().toString())
.post(TaskResourceRep.class, fsparam);
Assert.assertTrue(taskResp != null);
Assert.assertNotNull(taskResp.getOpId());
Assert.assertNotNull(taskResp.getResource());
URI fsId = taskResp.getResource().getId();
String opId = taskResp.getOpId();
// get the file system object we just created
ClientResponse response = rSys.path("/file/filesystems/" + fsId.toString())
.get(ClientResponse.class);
Assert.assertTrue(response != null);
Assert.assertEquals(200, response.getStatus());
// wait for for the file system create to complete
int checkCount = 1200;
String status;
do {
// wait upto ~2 minute for fs creation
Thread.sleep(100);
taskResp = rSys.path("/file/filesystems/" + fsId + "/tasks/" + opId)
.get(TaskResourceRep.class);
status = taskResp.getState();
} while (status.equals("pending") && checkCount-- > 0);
if (!status.equals("ready")) {
Assert.assertTrue("Fileshare create timed out", false);
}
// a normal file system should be present in the bulk results
BulkIdParam bulkIds = rSys.path("/file/filesystems/bulk")
.get(BulkIdParam.class);
Assert.assertNotNull("bulk ids should not be null", bulkIds);
FileShareBulkRep bulkFileShares = rSys.path("/file/filesystems/bulk")
.post(FileShareBulkRep.class, bulkIds);
Assert.assertNotNull("bulk response should not be null", bulkFileShares);
boolean found = false;
for (FileShareRestRep fs : bulkFileShares.getFileShares()) {
if (fs.getId().equals(fsId)) {
found = true;
}
}
Assert.assertTrue("unable to find public FileShare in the bulk results", found);
// only token is used in release file system operation and hence
// setting dummy strings for username and tenant ID do not matter
StorageOSUser user = new StorageOSUser("dummyUserName", "dummyTeneatId");
user.setToken(_rootToken);
FileShareRestRep fileShareResponse = _internalFileClient.releaseFileSystem(fsId, user);
Assert.assertNotNull(fileShareResponse);
// after release, the file system should no longer be present in the bulk results
bulkFileShares = rSys.path("/file/filesystems/bulk")
.post(FileShareBulkRep.class, bulkIds);
Assert.assertNotNull("bulk response should not be null", bulkFileShares);
found = false;
for (FileShareRestRep fs : bulkFileShares.getFileShares()) {
if (fs.getId().equals(fsId)) {
found = true;
}
}
Assert.assertFalse("found internal FileShare in the bulk results", found);
// undo the release of the file system
fileShareResponse = _internalFileClient.undoReleaseFileSystem(fsId);
Assert.assertNotNull(fileShareResponse);
// release it again
fileShareResponse = _internalFileClient.releaseFileSystem(fsId, user);
Assert.assertNotNull(fileShareResponse);
// delete the file system via the internal api
FileSystemDeleteParam deleteParam = new FileSystemDeleteParam();
deleteParam.setForceDelete(false);
taskResp = _internalFileClient.deactivateFileSystem(fsId, _rootToken, deleteParam);
Assert.assertNotNull(taskResp);
}
@Test
public void testNetworkUsingInternalClient() {
// first add a new endpoint
String newEndpoint = "www.networktest-" + System.currentTimeMillis() + ".com";
NetworkEndpointParam endpointParam = new NetworkEndpointParam();
endpointParam.setEndpoints(Arrays.asList(newEndpoint));
endpointParam.setOp(NetworkEndpointParam.EndpointOp.add.name());
NetworkRestRep network = _internalNetworkClient.updateNetworkEndpoints(_networkId, endpointParam);
Assert.assertNotNull("update should not return a null response", network);
Assert.assertTrue("response should contain the new endpoint " + newEndpoint, network.getEndpoints().contains(newEndpoint));
// then remove it again
endpointParam.setOp(NetworkEndpointParam.EndpointOp.remove.name());
network = _internalNetworkClient.updateNetworkEndpoints(_networkId, endpointParam);
Assert.assertNotNull("update should not return a null response", network);
Assert.assertFalse("response should not contain the new endpoint " + newEndpoint, network.getEndpoints().contains(newEndpoint));
}
@After
public void teardown() throws Exception {
_internalFileClient.shutdown();
_internalNetworkClient.shutdown();
_client.destroy();
}
}