/**
* =============================================================================
*
* ORCID (R) Open Source
* http://orcid.org
*
* Copyright (c) 2012-2014 ORCID, Inc.
* Licensed under an MIT-Style License (MIT)
* http://orcid.org/open-source-license
*
* This copyright and license information (including a link to the full license)
* shall be included in its entirety in all copies or substantial portion of
* the software.
*
* =============================================================================
*/
package org.orcid.integration.performance;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.net.URISyntaxException;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.time.StopWatch;
import org.codehaus.jettison.json.JSONException;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.orcid.integration.blackbox.api.v2.release.BlackBoxBaseV2Release;
import org.orcid.jaxb.model.message.ScopePathType;
import org.orcid.jaxb.model.record.summary_v2.ActivitiesSummary;
import org.orcid.jaxb.model.record.summary_v2.EducationSummary;
import org.orcid.jaxb.model.record.summary_v2.EmploymentSummary;
import org.orcid.jaxb.model.record.summary_v2.FundingGroup;
import org.orcid.jaxb.model.record.summary_v2.FundingSummary;
import org.orcid.jaxb.model.record.summary_v2.PeerReviewGroup;
import org.orcid.jaxb.model.record.summary_v2.PeerReviewSummary;
import org.orcid.jaxb.model.record.summary_v2.WorkGroup;
import org.orcid.jaxb.model.record.summary_v2.WorkSummary;
import org.orcid.jaxb.model.record_rc1.WorkExternalIdentifierType;
import org.orcid.jaxb.model.record_v2.ExternalID;
import org.orcid.jaxb.model.record_v2.Relationship;
import org.orcid.jaxb.model.record_v2.Work;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.sun.jersey.api.client.ClientResponse;
/**
*
* @author Will Simpson
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:test-context.xml" })
public class MemberV2PerformanceTest extends BlackBoxBaseV2Release {
@After
public void after() throws JSONException, InterruptedException, URISyntaxException {
cleanActivities();
}
@Test
public void createManyWorks() throws JSONException, InterruptedException, URISyntaxException {
int numWorks = 1000;
// Amount of linear increase allowed
float scalingFactor = 1.5f;
int numInitialSample = numWorks / 10;
long initialSampleTime = 0;
StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (int i = 1; i <= numWorks; i++) {
StopWatch singleWorkStopWatch = new StopWatch();
singleWorkStopWatch.start();
long time = System.currentTimeMillis();
Work workToCreate = (Work) unmarshallFromPath("/record_2.0/samples/work-2.0.xml", Work.class);
workToCreate.setPutCode(null);
workToCreate.getExternalIdentifiers().getExternalIdentifier().clear();
ExternalID wExtId = new ExternalID();
wExtId.setValue("Work Id " + i + " " + time);
wExtId.setType(WorkExternalIdentifierType.AGR.value());
wExtId.setRelationship(Relationship.SELF);
workToCreate.getExternalIdentifiers().getExternalIdentifier().add(wExtId);
String accessToken = getAccessToken();
ClientResponse postResponse = memberV2ApiClient.createWorkXml(this.getUser1OrcidId(), workToCreate, accessToken);
stopWatch.split();
long splitTime = stopWatch.getSplitTime();
System.out.println("Split time: " + splitTime);
if (i == numInitialSample) {
initialSampleTime = splitTime;
} else if (i > numInitialSample) {
float maxTime = (initialSampleTime / numInitialSample) * scalingFactor * i;
System.out.println("Max time: " + maxTime);
assertTrue("Split time = " + splitTime + ", but max allowed time = " + maxTime + ", when num added = " + i, splitTime <= maxTime);
}
assertNotNull(postResponse);
assertEquals(Response.Status.CREATED.getStatusCode(), postResponse.getStatus());
String locationPath = postResponse.getLocation().getPath();
assertTrue("Location header path should match pattern, but was " + locationPath,
locationPath.matches(".*/v2.0/" + this.getUser1OrcidId() + "/work/\\d+"));
ClientResponse getResponse = memberV2ApiClient.viewLocationXml(postResponse.getLocation(), accessToken);
assertEquals(Response.Status.OK.getStatusCode(), getResponse.getStatus());
Work gotWork = getResponse.getEntity(Work.class);
assertEquals("common:title", gotWork.getWorkTitle().getTitle().getContent());
System.out.println("Time for single work = " + singleWorkStopWatch);
}
}
private void cleanActivities() throws JSONException, InterruptedException, URISyntaxException {
String token = getAccessToken();
// Remove all activities
ClientResponse activitiesResponse = memberV2ApiClient.viewActivities(this.getUser1OrcidId(), token);
assertNotNull(activitiesResponse);
ActivitiesSummary summary = activitiesResponse.getEntity(ActivitiesSummary.class);
assertNotNull(summary);
if (summary.getEducations() != null && !summary.getEducations().getSummaries().isEmpty()) {
for (EducationSummary education : summary.getEducations().getSummaries()) {
memberV2ApiClient.deleteEducationXml(this.getUser1OrcidId(), education.getPutCode(), token);
}
}
if (summary.getEmployments() != null && !summary.getEmployments().getSummaries().isEmpty()) {
for (EmploymentSummary employment : summary.getEmployments().getSummaries()) {
memberV2ApiClient.deleteEmploymentXml(this.getUser1OrcidId(), employment.getPutCode(), token);
}
}
if (summary.getFundings() != null && !summary.getFundings().getFundingGroup().isEmpty()) {
for (FundingGroup group : summary.getFundings().getFundingGroup()) {
for (FundingSummary funding : group.getFundingSummary()) {
memberV2ApiClient.deleteFundingXml(this.getUser1OrcidId(), funding.getPutCode(), token);
}
}
}
if (summary.getWorks() != null && !summary.getWorks().getWorkGroup().isEmpty()) {
for (WorkGroup group : summary.getWorks().getWorkGroup()) {
for (WorkSummary work : group.getWorkSummary()) {
memberV2ApiClient.deleteWorkXml(this.getUser1OrcidId(), work.getPutCode(), token);
}
}
}
if (summary.getPeerReviews() != null && !summary.getPeerReviews().getPeerReviewGroup().isEmpty()) {
for (PeerReviewGroup group : summary.getPeerReviews().getPeerReviewGroup()) {
for (PeerReviewSummary peerReview : group.getPeerReviewSummary()) {
memberV2ApiClient.deletePeerReviewXml(this.getUser1OrcidId(), peerReview.getPutCode(), token);
}
}
}
}
private String getAccessToken() throws InterruptedException, JSONException {
return getAccessToken(getScopes(ScopePathType.ACTIVITIES_UPDATE, ScopePathType.ACTIVITIES_READ_LIMITED));
}
}