Skip to content

Commit 439971e

Browse files
committed
Added MultipleWorkflowsException
.. which shows representations as text/uri-list and permalinks per format
1 parent 90a0e32 commit 439971e

File tree

2 files changed

+131
-5
lines changed

2 files changed

+131
-5
lines changed

src/main/java/org/commonwl/view/GlobalControllerErrorHandling.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
package org.commonwl.view;
2121

22+
import java.util.Collections;
23+
24+
import org.commonwl.view.workflow.MultipleWorkflowsException;
2225
import org.commonwl.view.workflow.RepresentationNotFoundException;
2326
import org.commonwl.view.workflow.WorkflowNotFoundException;
2427
import org.springframework.http.HttpHeaders;
@@ -29,7 +32,12 @@
2932
import org.springframework.web.bind.annotation.ExceptionHandler;
3033

3134
/**
32-
* Handles exception handling across the application
35+
* Handles exception handling across the application.
36+
* <p>
37+
* Because of Spring Boot's content negotiation these handlers are needed when
38+
* the error is returned with an otherwise "non acceptable" content type (e.g.
39+
* Accept: image/svg+xml but we have to say 404 Not Found)
40+
*
3341
*/
3442
@ControllerAdvice
3543
public class GlobalControllerErrorHandling {
@@ -42,20 +50,34 @@ public class GlobalControllerErrorHandling {
4250
public ResponseEntity<?> handleNotFound() {
4351
final HttpHeaders headers = new HttpHeaders();
4452
headers.setContentType(MediaType.TEXT_PLAIN);
45-
return new ResponseEntity<>("Workflow could not be found", headers, HttpStatus.NOT_FOUND);
53+
return new ResponseEntity<>("Workflow or git commit could not be found", headers, HttpStatus.NOT_FOUND);
54+
}
55+
56+
/**
57+
* More than one workflow (or workflow parts) found
58+
*
59+
* @return A text/uri-list of potential representations
60+
*/
61+
@ExceptionHandler(MultipleWorkflowsException.class)
62+
public ResponseEntity<?> handleMultipleWorkflows(MultipleWorkflowsException ex) {
63+
final HttpHeaders headers = new HttpHeaders();
64+
headers.setContentType(MediaType.parseMediaType("text/uri-list"));
65+
return new ResponseEntity<>(ex.toString(), headers, HttpStatus.MULTIPLE_CHOICES);
4666
}
4767

4868
/**
49-
* Workflow exists but representation is not found
50-
* eg Generic git workflow asking for raw workflow URL
69+
* Workflow exists but representation is not found eg Generic git workflow
70+
* asking for raw workflow URL
71+
*
5172
* @return A plain text error message
5273
*/
5374
@ExceptionHandler(RepresentationNotFoundException.class)
5475
public ResponseEntity<?> handleNoRepresentation() {
5576
final HttpHeaders headers = new HttpHeaders();
77+
headers.setVary(Collections.singletonList("Accept"));
5678
headers.setContentType(MediaType.TEXT_PLAIN);
5779
return new ResponseEntity<>("The workflow exists but the requested representation could not be found",
58-
headers, HttpStatus.NOT_FOUND);
80+
headers, HttpStatus.NOT_ACCEPTABLE);
5981
}
6082

6183
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.commonwl.view.workflow;
21+
22+
import java.util.Collection;
23+
import java.util.Collections;
24+
import java.util.HashSet;
25+
import java.util.Set;
26+
27+
import org.commonwl.view.WebConfig.Format;
28+
import org.springframework.http.HttpStatus;
29+
import org.springframework.web.bind.annotation.ResponseStatus;
30+
31+
/**
32+
* Exception thrown when multiple workflows exist for the request
33+
*/
34+
@ResponseStatus(value = HttpStatus.MULTIPLE_CHOICES)
35+
public class MultipleWorkflowsException extends RuntimeException {
36+
37+
private final Collection<Workflow> matches;
38+
39+
public MultipleWorkflowsException(Workflow match) {
40+
this(Collections.singleton(match));
41+
}
42+
43+
public MultipleWorkflowsException(Collection<Workflow> matches) {
44+
if (matches.isEmpty()) {
45+
throw new IllegalArgumentException("MultipleWorkflowsException, but empty list of workflows");
46+
}
47+
this.matches = matches;
48+
}
49+
50+
// Always CRLF in text/uri-list
51+
private final String CRLF = "\r\n";
52+
53+
public String getRawPermalink() {
54+
// all raw URIs should be the same without ?part=
55+
return matches.stream().findAny().get().getPermalink(Format.raw);
56+
}
57+
58+
/**
59+
* Generate a text/uri-list of potential representations/redirects
60+
*
61+
* @see https://www.iana.org/assignments/media-types/text/uri-list
62+
*/
63+
@Override
64+
public String toString() {
65+
StringBuffer sb = new StringBuffer();
66+
sb.append("## Multiple workflow representations found");
67+
sb.append(CRLF);
68+
sb.append("# ");
69+
sb.append(CRLF);
70+
71+
sb.append("# ");
72+
sb.append(Format.raw.mediaType());
73+
sb.append(CRLF);
74+
sb.append(getRawPermalink());
75+
sb.append(CRLF);
76+
77+
Set<String> seen = new HashSet<>();
78+
// For each workflow, link to each remaining format
79+
for (Workflow w : matches) {
80+
if (!seen.add(w.getIdentifier())) {
81+
// Skip permalink duplicates
82+
continue;
83+
}
84+
sb.append("#");
85+
sb.append(CRLF);
86+
sb.append("# ");
87+
sb.append(w.getIdentifier());
88+
sb.append(CRLF);
89+
for (Format f : Format.values()) {
90+
if (f == Format.raw) {
91+
// Already did that one above
92+
continue;
93+
}
94+
sb.append("# ");
95+
sb.append(f.mediaType());
96+
sb.append(CRLF);
97+
sb.append(w.getPermalink(f));
98+
sb.append(CRLF);
99+
}
100+
}
101+
return sb.toString();
102+
}
103+
104+
}

0 commit comments

Comments
 (0)