23
23
import org .commonwl .view .cwl .CWLToolRunner ;
24
24
import org .commonwl .view .cwl .CWLToolStatus ;
25
25
import org .commonwl .view .git .GitDetails ;
26
+ import org .commonwl .view .git .GitSemaphore ;
26
27
import org .commonwl .view .git .GitService ;
27
28
import org .commonwl .view .graphviz .GraphVizService ;
28
29
import org .commonwl .view .researchobject .ROBundleFactory ;
@@ -56,6 +57,7 @@ public class WorkflowService {
56
57
private final ROBundleFactory ROBundleFactory ;
57
58
private final GraphVizService graphVizService ;
58
59
private final CWLToolRunner cwlToolRunner ;
60
+ private final GitSemaphore gitSemaphore ;
59
61
private final int cacheDays ;
60
62
61
63
@ Autowired
@@ -66,6 +68,7 @@ public WorkflowService(GitService gitService,
66
68
ROBundleFactory ROBundleFactory ,
67
69
GraphVizService graphVizService ,
68
70
CWLToolRunner cwlToolRunner ,
71
+ GitSemaphore gitSemaphore ,
69
72
@ Value ("${cacheDays}" ) int cacheDays ) {
70
73
this .gitService = gitService ;
71
74
this .cwlService = cwlService ;
@@ -75,6 +78,7 @@ public WorkflowService(GitService gitService,
75
78
this .graphVizService = graphVizService ;
76
79
this .cwlToolRunner = cwlToolRunner ;
77
80
this .cacheDays = cacheDays ;
81
+ this .gitSemaphore = gitSemaphore ;
78
82
}
79
83
80
84
/**
@@ -217,50 +221,58 @@ public File getROBundle(GitDetails gitDetails) throws ROBundleNotFoundException
217
221
*/
218
222
public QueuedWorkflow createQueuedWorkflow (GitDetails gitInfo )
219
223
throws GitAPIException , WorkflowNotFoundException , IOException {
224
+ QueuedWorkflow queuedWorkflow ;
220
225
221
- // Clone repository to temporary folder
222
- Git repo = null ;
223
- while (repo == null ) {
224
- try {
225
- repo = gitService .getRepository (gitInfo );
226
- } catch (RefNotFoundException ex ) {
227
- // Attempt slashes in branch fix
228
- GitDetails correctedForSlash = transferPathToBranch (gitInfo );
229
- if (correctedForSlash != null ) {
230
- gitInfo = correctedForSlash ;
231
- } else {
232
- throw ex ;
226
+ try {
227
+ // Clone repository to temporary folder
228
+ Git repo = null ;
229
+ while (repo == null ) {
230
+ try {
231
+ boolean safeToAccess = gitSemaphore .acquire (gitInfo .getRepoUrl ());
232
+ repo = gitService .getRepository (gitInfo , safeToAccess );
233
+ } catch (RefNotFoundException ex ) {
234
+ // Attempt slashes in branch fix
235
+ GitDetails correctedForSlash = transferPathToBranch (gitInfo );
236
+ if (correctedForSlash != null ) {
237
+ gitSemaphore .release (gitInfo .getRepoUrl ());
238
+ gitInfo = correctedForSlash ;
239
+ } else {
240
+ throw ex ;
241
+ }
233
242
}
234
243
}
235
- }
236
- File localPath = repo .getRepository ().getWorkTree ();
237
- String latestCommit = gitService .getCurrentCommitID (repo );
244
+ File localPath = repo .getRepository ().getWorkTree ();
245
+ String latestCommit = gitService .getCurrentCommitID (repo );
238
246
239
- Path pathToWorkflowFile = localPath .toPath ().resolve (gitInfo .getPath ()).normalize ().toAbsolutePath ();
240
- // Prevent path traversal attacks
241
- if (!pathToWorkflowFile .startsWith (localPath .toPath ().normalize ().toAbsolutePath ())) {
242
- throw new WorkflowNotFoundException ();
243
- }
247
+ Path pathToWorkflowFile = localPath .toPath ().resolve (gitInfo .getPath ()).normalize ().toAbsolutePath ();
248
+ // Prevent path traversal attacks
249
+ if (!pathToWorkflowFile .startsWith (localPath .toPath ().normalize ().toAbsolutePath ())) {
250
+ throw new WorkflowNotFoundException ();
251
+ }
244
252
245
- File workflowFile = new File (pathToWorkflowFile .toString ());
246
- Workflow basicModel = cwlService .parseWorkflowNative (workflowFile );
253
+ File workflowFile = new File (pathToWorkflowFile .toString ());
254
+ Workflow basicModel = cwlService .parseWorkflowNative (workflowFile );
247
255
248
- // Set origin details
249
- basicModel .setRetrievedOn (new Date ());
250
- basicModel .setRetrievedFrom (gitInfo );
251
- basicModel .setLastCommit (latestCommit );
256
+ // Set origin details
257
+ basicModel .setRetrievedOn (new Date ());
258
+ basicModel .setRetrievedFrom (gitInfo );
259
+ basicModel .setLastCommit (latestCommit );
252
260
253
- // Save the queued workflow to database
254
- QueuedWorkflow queuedWorkflow = new QueuedWorkflow ();
255
- queuedWorkflow .setTempRepresentation (basicModel );
256
- queuedWorkflowRepository .save (queuedWorkflow );
261
+ // Save the queued workflow to database
262
+ queuedWorkflow = new QueuedWorkflow ();
263
+ queuedWorkflow .setTempRepresentation (basicModel );
264
+ queuedWorkflowRepository .save (queuedWorkflow );
257
265
258
- // ASYNC OPERATIONS
259
- // Parse with cwltool and update model
260
- try {
261
- cwlToolRunner .createWorkflowFromQueued (queuedWorkflow , workflowFile );
262
- } catch (Exception e ) {
263
- logger .error ("Could not update workflow with cwltool" , e );
266
+ // ASYNC OPERATIONS
267
+ // Parse with cwltool and update model
268
+ try {
269
+ cwlToolRunner .createWorkflowFromQueued (queuedWorkflow , workflowFile );
270
+ } catch (Exception e ) {
271
+ logger .error ("Could not update workflow with cwltool" , e );
272
+ }
273
+
274
+ } finally {
275
+ gitSemaphore .release (gitInfo .getRepoUrl ());
264
276
}
265
277
266
278
// Return this model to be displayed
@@ -275,14 +287,17 @@ public void retryCwltool(QueuedWorkflow queuedWorkflow) {
275
287
queuedWorkflow .setMessage (null );
276
288
queuedWorkflow .setCwltoolStatus (CWLToolStatus .RUNNING );
277
289
queuedWorkflowRepository .save (queuedWorkflow );
290
+ GitDetails gitDetails = queuedWorkflow .getTempRepresentation ().getRetrievedFrom ();
291
+ boolean safeToAccess = gitSemaphore .acquire (gitDetails .getRepoUrl ());
278
292
try {
279
- GitDetails gitDetails = queuedWorkflow .getTempRepresentation ().getRetrievedFrom ();
280
- Git repo = gitService .getRepository (gitDetails );
293
+ Git repo = gitService .getRepository (gitDetails , safeToAccess );
281
294
File localPath = repo .getRepository ().getWorkTree ();
282
295
Path pathToWorkflowFile = localPath .toPath ().resolve (gitDetails .getPath ()).normalize ().toAbsolutePath ();
283
296
cwlToolRunner .createWorkflowFromQueued (queuedWorkflow , new File (pathToWorkflowFile .toString ()));
284
297
} catch (Exception e ) {
285
298
logger .error ("Could not update workflow with cwltool" , e );
299
+ } finally {
300
+ gitSemaphore .release (gitDetails .getRepoUrl ());
286
301
}
287
302
}
288
303
@@ -343,8 +358,14 @@ private boolean cacheExpired(Workflow workflow) {
343
358
// Cache expiry time has elapsed
344
359
// Check current head of the branch with the cached head
345
360
logger .info ("Time has expired for caching, checking commits..." );
346
- Git repo = gitService .getRepository (workflow .getRetrievedFrom ());
347
- String currentHead = gitService .getCurrentCommitID (repo );
361
+ String currentHead ;
362
+ boolean safeToAccess = gitSemaphore .acquire (workflow .getRetrievedFrom ().getRepoUrl ());
363
+ try {
364
+ Git repo = gitService .getRepository (workflow .getRetrievedFrom (), safeToAccess );
365
+ currentHead = gitService .getCurrentCommitID (repo );
366
+ } finally {
367
+ gitSemaphore .release (workflow .getRetrievedFrom ().getRepoUrl ());
368
+ }
348
369
logger .info ("Current: " + workflow .getLastCommit () + ", HEAD: " + currentHead );
349
370
350
371
// Reset date in database if there are still no changes
0 commit comments