Skip to content

Commit f611908

Browse files
author
Mark Robinson
committed
Refactor ROBundle into service with dependency injection and add test
1 parent 8db81ba commit f611908

File tree

4 files changed

+134
-77
lines changed

4 files changed

+134
-77
lines changed

src/main/java/org/commonwl/view/researchobject/ROBundleFactory.java

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@
2020
package org.commonwl.view.researchobject;
2121

2222
import org.apache.commons.io.FilenameUtils;
23-
import org.commonwl.view.github.GitHubService;
23+
import org.apache.taverna.robundle.Bundle;
2424
import org.commonwl.view.github.GithubDetails;
2525
import org.commonwl.view.workflow.Workflow;
2626
import org.commonwl.view.workflow.WorkflowRepository;
2727
import org.slf4j.Logger;
2828
import org.slf4j.LoggerFactory;
2929
import org.springframework.beans.factory.annotation.Autowired;
30-
import org.springframework.beans.factory.annotation.Value;
3130
import org.springframework.scheduling.annotation.Async;
3231
import org.springframework.scheduling.annotation.EnableAsync;
3332
import org.springframework.stereotype.Component;
@@ -47,26 +46,14 @@ public class ROBundleFactory {
4746

4847
private final Logger logger = LoggerFactory.getLogger(this.getClass());
4948

50-
private final String applicationName;
51-
private final String applicationURL;
52-
private final int singleFileSizeLimit;
53-
private final Path storageLocation;
5449
private final WorkflowRepository workflowRepository;
55-
private final GitHubService githubService;
50+
private final ROBundleService roBundleService;
5651

5752
@Autowired
58-
public ROBundleFactory(@Value("${applicationName}") String applicationName,
59-
@Value("${applicationURL}") String applicationURL,
60-
@Value("${graphvizStorage}") Path graphvizStorage,
61-
@Value("${singleFileSizeLimit}") int singleFileSizeLimit,
62-
GitHubService gitHubService,
53+
public ROBundleFactory(ROBundleService roBundleService,
6354
WorkflowRepository workflowRepository) {
64-
this.applicationName = applicationName;
65-
this.applicationURL = applicationURL;
66-
this.storageLocation = graphvizStorage;
6755
this.workflowRepository = workflowRepository;
68-
this.githubService = gitHubService;
69-
this.singleFileSizeLimit = singleFileSizeLimit;
56+
this.roBundleService = roBundleService;
7057
}
7158

7259
/**
@@ -85,16 +72,15 @@ public void workflowROFromGithub(GithubDetails githubInfo)
8572
githubInfo.getBranch(), FilenameUtils.getPath(githubInfo.getPath()));
8673

8774
// Create a new Research Object Bundle with Github contents
88-
ROBundle bundle = new ROBundle(githubService, roDetails,
89-
applicationName, applicationURL, singleFileSizeLimit);
75+
Bundle bundle = roBundleService.newBundleFromGithub(roDetails);
9076

9177
// Save the bundle to the storage location in properties
92-
Path bundleLocation = bundle.saveToFile(storageLocation);
78+
Path bundleLocation = roBundleService.saveToFile(bundle);
9379

9480
// Add the path to the bundle to the bundle
9581
Workflow workflow = workflowRepository.findByRetrievedFrom(githubInfo);
9682

97-
// Chance that this thread could be created before workflow model is saved
83+
// Chance that this thread could be done before workflow model is saved
9884
int attempts = 5;
9985
while (attempts > 0 && workflow == null) {
10086
// Delay this thread by 0.5s and try again until success or too many attempts

src/main/java/org/commonwl/view/researchobject/ROBundle.java renamed to src/main/java/org/commonwl/view/researchobject/ROBundleService.java

Lines changed: 62 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
import org.eclipse.egit.github.core.User;
3535
import org.slf4j.Logger;
3636
import org.slf4j.LoggerFactory;
37+
import org.springframework.beans.factory.annotation.Autowired;
38+
import org.springframework.beans.factory.annotation.Value;
39+
import org.springframework.stereotype.Service;
3740

3841
import java.io.IOException;
3942
import java.net.URI;
@@ -48,54 +51,66 @@
4851
import java.util.regex.Pattern;
4952

5053
/**
51-
* Represents a Workflow Research Object Bundle
54+
* Service handling Research Object Bundles
5255
*/
53-
public class ROBundle {
56+
@Service
57+
public class ROBundleService {
5458

5559
private final Logger logger = LoggerFactory.getLogger(this.getClass());
5660

61+
// Services
5762
private GitHubService githubService;
5863

59-
private Bundle bundle;
60-
private GithubDetails githubInfo;
61-
private Agent thisApp;
64+
// Configuration variables
65+
private Agent appAgent;
6266
private int singleFileSizeLimit;
63-
private Set<HashableAgent> authors = new HashSet<>();
67+
private Path bundleStorage;
6468

6569
// Pattern for extracting version from a cwl file
6670
private final String CWL_VERSION_REGEX = "cwlVersion:\\s*\"?(?:cwl:)?([^\\s\"]+)\"?";
6771
private final Pattern cwlVersionPattern = Pattern.compile(CWL_VERSION_REGEX);
6872

6973
/**
70-
* Creates a new research object bundle for a workflow from a Github repository
71-
* @param githubService The service for handling Github functionality
72-
* @param githubInfo The information necessary to access the Github directory associated with the RO
74+
* Creates an instance of this service which handles Research Object Bundles
75+
* @param bundleStorage The configured storage location for bundles
7376
* @param appName The name of the application from properties, for attribution
7477
* @param appURL The URL of the application from properties, for attribution
75-
* @throws IOException Any API errors which may have occurred
78+
* @param singleFileSizeLimit The file size limit for the RO bundle
79+
* @param githubService The service for handling Github functionality
80+
* @throws URISyntaxException Error in creating URI for appURL
7681
*/
77-
public ROBundle(GitHubService githubService, GithubDetails githubInfo,
78-
String appName, String appURL, int singleFileSizeLimit) throws IOException {
79-
// File size limits
82+
@Autowired
83+
public ROBundleService(@Value("${bundleStorage}") Path bundleStorage,
84+
@Value("${applicationName}") String appName,
85+
@Value("${applicationURL}") String appURL,
86+
@Value("${singleFileSizeLimit}") int singleFileSizeLimit,
87+
GitHubService githubService) throws URISyntaxException {
88+
this.bundleStorage = bundleStorage;
89+
this.appAgent = new Agent(appName);
90+
appAgent.setUri(new URI(appURL));
8091
this.singleFileSizeLimit = singleFileSizeLimit;
81-
82-
// Create a new RO bundle
83-
this.bundle = Bundles.createBundle();
84-
this.githubInfo = githubInfo;
8592
this.githubService = githubService;
93+
}
94+
95+
/**
96+
* Creates a new research object bundle for a workflow from a Github repository
97+
* @param githubInfo The information to access the repository
98+
* @return The constructed bundle
99+
*/
100+
public Bundle newBundleFromGithub(GithubDetails githubInfo) throws IOException {
86101

102+
// Create a new RO bundle
103+
Bundle bundle = Bundles.createBundle();
87104
Manifest manifest = bundle.getManifest();
88105

89106
// Simplified attribution for RO bundle
90107
try {
91108
// Tool attribution in createdBy
92-
thisApp = new Agent(appName);
93-
thisApp.setUri(new URI(appURL));
94-
manifest.setCreatedBy(thisApp);
109+
manifest.setCreatedBy(appAgent);
95110

96111
// Retrieval Info
97112
// TODO: Make this importedBy/On/From
98-
manifest.setRetrievedBy(thisApp);
113+
manifest.setRetrievedBy(appAgent);
99114
manifest.setRetrievedOn(manifest.getCreatedOn());
100115
manifest.setRetrievedFrom(new URI(githubInfo.getURL()));
101116

@@ -109,18 +124,40 @@ public ROBundle(GitHubService githubService, GithubDetails githubInfo,
109124

110125
// Add the files from the Github repo to this workflow
111126
List<RepositoryContents> repoContents = githubService.getContents(githubInfo);
112-
addFiles(repoContents, bundleFiles);
127+
Set<HashableAgent> authors = new HashSet<HashableAgent>();
128+
addFilesToBundle(bundle, githubInfo, repoContents, bundleFiles, authors);
113129

114130
// Add combined authors
115131
manifest.setAuthoredBy(new ArrayList<>(authors));
132+
133+
// Return the completed bundle
134+
return bundle;
135+
136+
}
137+
138+
/**
139+
* Save the Research Object bundle to disk
140+
* @param roBundle The bundle to be saved
141+
* @return The path to the research object
142+
* @throws IOException Any errors in saving
143+
*/
144+
public Path saveToFile(Bundle roBundle) throws IOException {
145+
String fileName = "bundle-" + java.util.UUID.randomUUID() + ".zip";
146+
Path bundleLocation = Files.createFile(bundleStorage.resolve(fileName));
147+
Bundles.closeAndSaveBundle(roBundle, bundleLocation);
148+
return bundleLocation;
116149
}
117150

118151
/**
119152
* Add files to this bundle from a list of Github repository contents
153+
* @param bundle The RO bundle to add files/directories to
154+
* @param githubInfo The information used to access the repository
120155
* @param repoContents The contents of the Github repository
121156
* @param path The path in the Research Object to add the files
122157
*/
123-
private void addFiles(List<RepositoryContents> repoContents, Path path) throws IOException {
158+
private void addFilesToBundle(Bundle bundle, GithubDetails githubInfo,
159+
List<RepositoryContents> repoContents, Path path,
160+
Set<HashableAgent> authors) throws IOException {
124161

125162
// Loop through repo contents and add them
126163
for (RepositoryContents repoContent : repoContents) {
@@ -138,7 +175,7 @@ private void addFiles(List<RepositoryContents> repoContents, Path path) throws I
138175
Files.createDirectory(subdirPath);
139176

140177
// Add the files in the subdirectory to this new folder
141-
addFiles(subdirectory, subdirPath);
178+
addFilesToBundle(bundle, githubInfo, subdirectory, subdirPath, authors);
142179

143180
// Otherwise this is a file so add to the bundle
144181
} else if (repoContent.getType().equals(GitHubService.TYPE_FILE)) {
@@ -214,7 +251,7 @@ private void addFiles(List<RepositoryContents> repoContents, Path path) throws I
214251

215252
// Set retrieved information for this file in the manifest
216253
aggregation.setRetrievedFrom(rawURI);
217-
aggregation.setRetrievedBy(thisApp);
254+
aggregation.setRetrievedBy(appAgent);
218255
aggregation.setRetrievedOn(aggregation.getCreatedOn());
219256

220257
} catch (URISyntaxException ex) {
@@ -224,24 +261,4 @@ private void addFiles(List<RepositoryContents> repoContents, Path path) throws I
224261
}
225262
}
226263

227-
/**
228-
* Save the Research Object bundle to disk
229-
* @param directory The directory in which the RO will be saved
230-
* @return The path to the research object
231-
* @throws IOException Any errors in saving
232-
*/
233-
public Path saveToFile(Path directory) throws IOException {
234-
String fileName = "bundle-" + java.util.UUID.randomUUID() + ".zip";
235-
Path bundleLocation = Files.createFile(directory.resolve(fileName));
236-
Bundles.closeAndSaveBundle(bundle, bundleLocation);
237-
return bundleLocation;
238-
}
239-
240-
/**
241-
* Getter method for the bundle
242-
* @return The RO bundle
243-
*/
244-
public Bundle getBundle() {
245-
return bundle;
246-
}
247264
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.commonwl.view.researchobject;
2+
3+
import org.commonwl.view.github.GithubDetails;
4+
import org.commonwl.view.workflow.Workflow;
5+
import org.commonwl.view.workflow.WorkflowRepository;
6+
import org.junit.Test;
7+
import org.mockito.Mockito;
8+
9+
import java.nio.file.Paths;
10+
import java.util.HashMap;
11+
12+
import static org.junit.Assert.assertEquals;
13+
import static org.mockito.Matchers.anyObject;
14+
import static org.mockito.Mockito.when;
15+
16+
/**
17+
* Test the separate async method to call the ROBundle constructor
18+
*/
19+
public class ROBundleFactoryTest {
20+
21+
/**
22+
* Simulate creation of a valid workflow
23+
*/
24+
@Test
25+
public void bundleForValidWorkflow() throws Exception {
26+
27+
Workflow validWorkflow = new Workflow("Valid Workflow", "Doc for Valid Workflow",
28+
new HashMap<>(), new HashMap<>(), new HashMap<>(), null);
29+
30+
// Mocked path to a RO bundle
31+
ROBundleService mockROBundleService = Mockito.mock(ROBundleService.class);
32+
when(mockROBundleService.saveToFile(anyObject()))
33+
.thenReturn(Paths.get("test/path/to/check/for.zip"));
34+
35+
// Test method retries multiple times to get workflow model before success
36+
WorkflowRepository mockRepository = Mockito.mock(WorkflowRepository.class);
37+
when(mockRepository.findByRetrievedFrom(anyObject()))
38+
.thenReturn(null)
39+
.thenReturn(null)
40+
.thenReturn(validWorkflow);
41+
42+
// Create factory under test
43+
ROBundleFactory factory = new ROBundleFactory(mockROBundleService, mockRepository);
44+
45+
// Attempt to add RO to workflow
46+
factory.workflowROFromGithub(Mockito.mock(GithubDetails.class));
47+
48+
assertEquals("test/path/to/check/for.zip", validWorkflow.getRoBundle());
49+
50+
}
51+
52+
}

src/test/java/org/commonwl/view/researchobject/ROBundleTest.java renamed to src/test/java/org/commonwl/view/researchobject/ROBundleServiceTest.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import static org.mockito.Matchers.anyObject;
2525
import static org.mockito.Mockito.when;
2626

27-
public class ROBundleTest {
27+
public class ROBundleServiceTest {
2828

2929
/**
3030
* Use a temporary directory for testing
@@ -44,15 +44,16 @@ public void generateAndSaveROBundle() throws Exception {
4444
// Create new RO bundle
4545
GithubDetails lobSTRv1Details = new GithubDetails("common-workflow-language", "workflows",
4646
"933bf2a1a1cce32d88f88f136275535da9df0954", "workflows/lobSTR");
47-
ROBundle bundle = new ROBundle(mockGithubService, lobSTRv1Details, "CWL Viewer",
48-
"https://view.commonwl.org", 5242880);
49-
Path bundleRoot = bundle.getBundle().getRoot().resolve("workflow");
47+
ROBundleService bundleService = new ROBundleService(roBundleFolder.getRoot().toPath(),
48+
"CWL Viewer", "https://view.commonwl.org", 5242880, mockGithubService);
49+
Bundle bundle = bundleService.newBundleFromGithub(lobSTRv1Details);
50+
Path bundleRoot = bundle.getRoot().resolve("workflow");
5051

5152
// Check bundle exists
52-
assertNotNull(bundle.getBundle());
53+
assertNotNull(bundle);
5354

5455
// Check basic manifest metadata
55-
Manifest manifest = bundle.getBundle().getManifest();
56+
Manifest manifest = bundle.getManifest();
5657
assertEquals("CWL Viewer", manifest.getCreatedBy().getName());
5758
assertEquals("https://view.commonwl.org", manifest.getCreatedBy().getUri().toString());
5859
assertEquals("Mark Robinson", manifest.getAuthoredBy().get(0).getName());
@@ -69,7 +70,7 @@ public void generateAndSaveROBundle() throws Exception {
6970
assertEquals("https://w3id.org/cwl/v1.0", cwlAggregate.getConformsTo().toString());
7071

7172
// Save and check it exists in the temporary folder
72-
bundle.saveToFile(roBundleFolder.getRoot().toPath());
73+
bundleService.saveToFile(bundle);
7374
File[] fileList = roBundleFolder.getRoot().listFiles();
7475
assertTrue(fileList.length == 1);
7576
for (File ro : fileList) {
@@ -92,13 +93,14 @@ public void filesOverLimit() throws Exception {
9293
// Create new RO bundle where all files are external
9394
GithubDetails lobSTRv1Details = new GithubDetails("common-workflow-language", "workflows",
9495
"933bf2a1a1cce32d88f88f136275535da9df0954", "workflows/lobSTR");
95-
ROBundle bundle = new ROBundle(mockGithubService, lobSTRv1Details, "CWL Viewer",
96-
"https://view.commonwl.org", 0);
96+
ROBundleService bundleService = new ROBundleService(roBundleFolder.getRoot().toPath(),
97+
"CWL Viewer", "https://view.commonwl.org", 0, mockGithubService);
98+
Bundle bundle = bundleService.newBundleFromGithub(lobSTRv1Details);
9799

98-
Manifest manifest = bundle.getBundle().getManifest();
100+
Manifest manifest = bundle.getManifest();
99101

100102
// Check files are externally linked in the aggregate
101-
Path bundleRoot = bundle.getBundle().getRoot().resolve("workflow");
103+
Path bundleRoot = bundle.getRoot().resolve("workflow");
102104
PathMetadata urlAggregate = manifest.getAggregation(
103105
bundleRoot.resolve("lobSTR-demo.url"));
104106
assertEquals("Mark Robinson", urlAggregate.getAuthoredBy().get(0).getName());

0 commit comments

Comments
 (0)