This repository has been archived by the owner on Aug 13, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for multipart POST to framework
- Loading branch information
Showing
46 changed files
with
2,018 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
...java/uk/gov/justice/services/generators/commons/validator/MultipartHasFormParameters.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package uk.gov.justice.services.generators.commons.validator; | ||
|
||
import static java.lang.String.format; | ||
import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.raml.model.Action; | ||
import org.raml.model.ActionType; | ||
import org.raml.model.MimeType; | ||
import org.raml.model.ParamType; | ||
import org.raml.model.Resource; | ||
import org.raml.model.parameter.FormParameter; | ||
|
||
public class MultipartHasFormParameters extends AbstractResourceRamlValidator { | ||
|
||
@Override | ||
protected void validate(final Resource resource) { | ||
final Map<ActionType, Action> actions = resource.getActions(); | ||
|
||
if (!actions.isEmpty()) { | ||
actions.values().forEach(this::extractBodyMimeTypes); | ||
} | ||
} | ||
|
||
private void extractBodyMimeTypes(final Action action) { | ||
final Map<String, MimeType> body = action.getBody(); | ||
if (body != null) { | ||
body.values().stream() | ||
.filter(mimeType -> MULTIPART_FORM_DATA.equals(mimeType.getType())) | ||
.forEach(this::validateFormParameters); | ||
} | ||
} | ||
|
||
private void validateFormParameters(final MimeType mimeType) { | ||
final Map<String, List<FormParameter>> formParameters = mimeType.getFormParameters(); | ||
|
||
if (null == formParameters || formParameters.isEmpty()) { | ||
throw new RamlValidationException("Multipart form must contain form parameters"); | ||
} | ||
|
||
formParameters.values().forEach(this::validateFormParameter); | ||
} | ||
|
||
private void validateFormParameter(final List<FormParameter> values) { | ||
final FormParameter formParameter = values.get(0); | ||
|
||
if (!ParamType.FILE.equals(formParameter.getType())) { | ||
throw new RamlValidationException(format("Multipart form parameter is expected to be of type FILE, instead was %s", values.get(0).getType())); | ||
} | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
.../uk/gov/justice/services/generators/commons/validator/MultipartHasFormParametersTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package uk.gov.justice.services.generators.commons.validator; | ||
|
||
import static org.raml.model.ActionType.POST; | ||
import static org.raml.model.ParamType.STRING; | ||
import static uk.gov.justice.services.generators.test.utils.builder.HttpActionBuilder.httpAction; | ||
import static uk.gov.justice.services.generators.test.utils.builder.MimeTypeBuilder.multipartMimeType; | ||
import static uk.gov.justice.services.generators.test.utils.builder.MimeTypeBuilder.multipartWithFileFormParameter; | ||
import static uk.gov.justice.services.generators.test.utils.builder.RamlBuilder.restRamlWithDefaults; | ||
import static uk.gov.justice.services.generators.test.utils.builder.ResourceBuilder.resource; | ||
|
||
import org.junit.Rule; | ||
import org.junit.Test; | ||
import org.junit.rules.ExpectedException; | ||
import org.raml.model.Raml; | ||
|
||
public class MultipartHasFormParametersTest { | ||
|
||
@Rule | ||
public ExpectedException exception = ExpectedException.none(); | ||
|
||
private RamlValidator validator = new MultipartHasFormParameters(); | ||
|
||
@Test | ||
public void shouldPassIfMultipartContainsCorrectFormParameter() throws Exception { | ||
final Raml raml = restRamlWithDefaults() | ||
.with(resource("/some/path") | ||
.with(httpAction() | ||
.withHttpActionType(POST) | ||
.withMediaTypeWithoutSchema(multipartWithFileFormParameter("photoId"))) | ||
).build(); | ||
|
||
validator.validate(raml); | ||
} | ||
|
||
@Test | ||
public void shouldFailIfMultipartHasNoFormParameters() throws Exception { | ||
exception.expect(RamlValidationException.class); | ||
exception.expectMessage("Multipart form must contain form parameters"); | ||
|
||
final Raml raml = restRamlWithDefaults() | ||
.with(resource("/some/path") | ||
.with(httpAction() | ||
.withHttpActionType(POST) | ||
.withMediaTypeWithoutSchema(multipartMimeType())) | ||
).build(); | ||
|
||
validator.validate(raml); | ||
} | ||
|
||
@Test | ||
public void shouldFailIfMultipartHasFormParameterWithIncorrectType() throws Exception { | ||
exception.expect(RamlValidationException.class); | ||
exception.expectMessage("Multipart form parameter is expected to be of type FILE, instead was STRING"); | ||
|
||
final Raml raml = restRamlWithDefaults() | ||
.with(resource("/some/path") | ||
.with(httpAction() | ||
.withHttpActionType(POST) | ||
.withMediaTypeWithoutSchema(multipartMimeType() | ||
.withFormParameter("photoId", STRING, true))) | ||
).build(); | ||
|
||
validator.validate(raml); | ||
} | ||
|
||
@Test | ||
public void shouldPassIfNoMultipartPresent() throws Exception { | ||
final Raml raml = restRamlWithDefaults() | ||
.with(resource("/some/path") | ||
.withDefaultPostAction() | ||
).build(); | ||
|
||
validator.validate(raml); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
.../src/main/java/uk/gov/justice/services/generators/test/utils/builder/MimeTypeBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package uk.gov.justice.services.generators.test.utils.builder; | ||
|
||
import static java.util.Collections.singletonList; | ||
import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA; | ||
import static org.raml.model.ParamType.FILE; | ||
|
||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.raml.model.MimeType; | ||
import org.raml.model.ParamType; | ||
import org.raml.model.parameter.FormParameter; | ||
|
||
public class MimeTypeBuilder { | ||
|
||
final Map<String, List<FormParameter>> formParameters = new HashMap<>(); | ||
private final String type; | ||
|
||
public MimeTypeBuilder(final String type) { | ||
this.type = type; | ||
} | ||
|
||
public static MimeTypeBuilder multipartMimeType() { | ||
return new MimeTypeBuilder(MULTIPART_FORM_DATA); | ||
} | ||
|
||
public static MimeTypeBuilder multipartWithFileFormParameter(final String fieldName) { | ||
final MimeTypeBuilder mimeTypeBuilder = multipartMimeType(); | ||
mimeTypeBuilder.withRequiredFileTypeFormParameter(fieldName); | ||
return mimeTypeBuilder; | ||
} | ||
|
||
public MimeTypeBuilder withRequiredFileTypeFormParameter(final String fieldName) { | ||
return withFormParameter(fieldName, FILE, true); | ||
} | ||
|
||
public MimeTypeBuilder withRequiredFormParameter(final String fieldName, final ParamType paramType) { | ||
return withFormParameter(fieldName, paramType, true); | ||
} | ||
|
||
public MimeTypeBuilder withOptionalFormParameter(final String fieldName, final ParamType paramType) { | ||
return withFormParameter(fieldName, paramType, false); | ||
} | ||
|
||
public MimeTypeBuilder withNoDisplayNameFormParameter(final String fieldName, final ParamType paramType) { | ||
final FormParameter formParameter = new FormParameter(); | ||
formParameter.setType(paramType); | ||
formParameter.setRequired(true); | ||
|
||
formParameters.put(fieldName, singletonList(formParameter)); | ||
return this; | ||
} | ||
|
||
public MimeTypeBuilder withFormParameter(final String fieldName, final ParamType paramType, final boolean required) { | ||
final FormParameter formParameter = new FormParameter(); | ||
formParameter.setType(paramType); | ||
formParameter.setRequired(required); | ||
|
||
formParameters.put(fieldName, singletonList(formParameter)); | ||
return this; | ||
} | ||
|
||
public MimeType build() { | ||
final MimeType mimeType = new MimeType(type); | ||
mimeType.setFormParameters(formParameters); | ||
return mimeType; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
.../main/java/uk/gov/justice/services/adapter/rest/interceptor/FileStoreFailedException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package uk.gov.justice.services.adapter.rest.interceptor; | ||
|
||
public class FileStoreFailedException extends RuntimeException { | ||
|
||
public FileStoreFailedException(final String message, final Throwable cause) { | ||
super(message, cause); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
...ava/uk/gov/justice/services/adapter/rest/mutipart/FileBasedInterceptorContextFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package uk.gov.justice.services.adapter.rest.mutipart; | ||
|
||
import static uk.gov.justice.services.adapter.rest.mutipart.FileInputDetails.FILE_INPUT_DETAILS_LIST; | ||
import static uk.gov.justice.services.core.interceptor.InterceptorContext.interceptorContextWithInput; | ||
|
||
import uk.gov.justice.services.core.interceptor.InterceptorContext; | ||
import uk.gov.justice.services.messaging.JsonEnvelope; | ||
|
||
import java.util.List; | ||
|
||
import javax.enterprise.context.ApplicationScoped; | ||
|
||
@ApplicationScoped | ||
public class FileBasedInterceptorContextFactory { | ||
|
||
public InterceptorContext create(final List<FileInputDetails> fileInputDetails, final JsonEnvelope envelope) { | ||
final InterceptorContext interceptorContext = interceptorContextWithInput(envelope); | ||
interceptorContext.setInputParameter(FILE_INPUT_DETAILS_LIST, fileInputDetails); | ||
|
||
return interceptorContext; | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
...er-core/src/main/java/uk/gov/justice/services/adapter/rest/mutipart/FileInputDetails.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package uk.gov.justice.services.adapter.rest.mutipart; | ||
|
||
import java.io.InputStream; | ||
|
||
import javax.ws.rs.core.MediaType; | ||
|
||
public class FileInputDetails { | ||
|
||
public static final String FILE_INPUT_DETAILS_LIST = "fileInputDetailsList"; | ||
|
||
private final String fileName; | ||
private final String fieldName; | ||
private final MediaType mediaType; | ||
private final InputStream inputStream; | ||
|
||
public FileInputDetails( | ||
final String fileName, | ||
final String fieldName, | ||
final MediaType mediaType, | ||
final InputStream inputStream) { | ||
this.fileName = fileName; | ||
this.fieldName = fieldName; | ||
this.mediaType = mediaType; | ||
this.inputStream = inputStream; | ||
} | ||
|
||
public String getFileName() { | ||
return fileName; | ||
} | ||
|
||
public String getFieldName() { | ||
return fieldName; | ||
} | ||
|
||
public MediaType getMediaType() { | ||
return mediaType; | ||
} | ||
|
||
public InputStream getInputStream() { | ||
return inputStream; | ||
} | ||
} |
Oops, something went wrong.