diff --git a/changelog/@unreleased/pr-1102.v2.yml b/changelog/@unreleased/pr-1102.v2.yml new file mode 100644 index 000000000..ca5ea0a2f --- /dev/null +++ b/changelog/@unreleased/pr-1102.v2.yml @@ -0,0 +1,5 @@ +type: fix +fix: + description: conjure-undertow correctly dealiases binary response types + links: + - https://github.com/palantir/conjure-java/pull/1102 diff --git a/conjure-java-core/src/integrationInput/java/com/palantir/product/AliasOptionalDoubleAliasedBinaryResult.java b/conjure-java-core/src/integrationInput/java/com/palantir/product/AliasOptionalDoubleAliasedBinaryResult.java new file mode 100644 index 000000000..3cd181f34 --- /dev/null +++ b/conjure-java-core/src/integrationInput/java/com/palantir/product/AliasOptionalDoubleAliasedBinaryResult.java @@ -0,0 +1,48 @@ +package com.palantir.product; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.palantir.logsafe.Preconditions; +import java.util.Optional; +import javax.annotation.Generated; +import javax.annotation.Nonnull; + +@Generated("com.palantir.conjure.java.types.AliasGenerator") +public final class AliasOptionalDoubleAliasedBinaryResult { + private final Optional value; + + private AliasOptionalDoubleAliasedBinaryResult(@Nonnull Optional value) { + this.value = Preconditions.checkNotNull(value, "value cannot be null"); + } + + private AliasOptionalDoubleAliasedBinaryResult() { + this(Optional.empty()); + } + + @JsonValue + public Optional get() { + return value; + } + + @Override + public String toString() { + return value.toString(); + } + + @Override + public boolean equals(Object other) { + return this == other + || (other instanceof AliasOptionalDoubleAliasedBinaryResult + && this.value.equals(((AliasOptionalDoubleAliasedBinaryResult) other).value)); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + @JsonCreator + public static AliasOptionalDoubleAliasedBinaryResult of(@Nonnull Optional value) { + return new AliasOptionalDoubleAliasedBinaryResult(value); + } +} diff --git a/conjure-java-core/src/integrationInput/java/com/palantir/product/AliasedBinaryResult.java b/conjure-java-core/src/integrationInput/java/com/palantir/product/AliasedBinaryResult.java new file mode 100644 index 000000000..f0c206e5e --- /dev/null +++ b/conjure-java-core/src/integrationInput/java/com/palantir/product/AliasedBinaryResult.java @@ -0,0 +1,43 @@ +package com.palantir.product; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.palantir.logsafe.Preconditions; +import java.nio.ByteBuffer; +import javax.annotation.Generated; +import javax.annotation.Nonnull; + +@Generated("com.palantir.conjure.java.types.AliasGenerator") +public final class AliasedBinaryResult { + private final ByteBuffer value; + + private AliasedBinaryResult(@Nonnull ByteBuffer value) { + this.value = Preconditions.checkNotNull(value, "value cannot be null"); + } + + @JsonValue + public ByteBuffer get() { + return value; + } + + @Override + public String toString() { + return value.toString(); + } + + @Override + public boolean equals(Object other) { + return this == other + || (other instanceof AliasedBinaryResult && this.value.equals(((AliasedBinaryResult) other).value)); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + @JsonCreator + public static AliasedBinaryResult of(@Nonnull ByteBuffer value) { + return new AliasedBinaryResult(value); + } +} diff --git a/conjure-java-core/src/integrationInput/java/com/palantir/product/DialogueEteBinaryEndpoints.java b/conjure-java-core/src/integrationInput/java/com/palantir/product/DialogueEteBinaryEndpoints.java index 19633e7db..7d66deaac 100644 --- a/conjure-java-core/src/integrationInput/java/com/palantir/product/DialogueEteBinaryEndpoints.java +++ b/conjure-java-core/src/integrationInput/java/com/palantir/product/DialogueEteBinaryEndpoints.java @@ -164,6 +164,36 @@ public String endpointName() { return "getBinaryFailure"; } + @Override + public String version() { + return "1.2.3"; + } + }, + + getAliased { + private final PathTemplate pathTemplate = + PathTemplate.builder().fixed("binary").fixed("aliased").build(); + + @Override + public void renderPath(Map params, UrlBuilder url) { + pathTemplate.fill(params, url); + } + + @Override + public HttpMethod httpMethod() { + return HttpMethod.GET; + } + + @Override + public String serviceName() { + return "EteBinaryService"; + } + + @Override + public String endpointName() { + return "getAliased"; + } + @Override public String version() { return "1.2.3"; diff --git a/conjure-java-core/src/integrationInput/java/com/palantir/product/DoubleAliasedBinaryResult.java b/conjure-java-core/src/integrationInput/java/com/palantir/product/DoubleAliasedBinaryResult.java new file mode 100644 index 000000000..34589c61d --- /dev/null +++ b/conjure-java-core/src/integrationInput/java/com/palantir/product/DoubleAliasedBinaryResult.java @@ -0,0 +1,43 @@ +package com.palantir.product; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.palantir.logsafe.Preconditions; +import javax.annotation.Generated; +import javax.annotation.Nonnull; + +@Generated("com.palantir.conjure.java.types.AliasGenerator") +public final class DoubleAliasedBinaryResult { + private final AliasedBinaryResult value; + + private DoubleAliasedBinaryResult(@Nonnull AliasedBinaryResult value) { + this.value = Preconditions.checkNotNull(value, "value cannot be null"); + } + + @JsonValue + public AliasedBinaryResult get() { + return value; + } + + @Override + public String toString() { + return value.toString(); + } + + @Override + public boolean equals(Object other) { + return this == other + || (other instanceof DoubleAliasedBinaryResult + && this.value.equals(((DoubleAliasedBinaryResult) other).value)); + } + + @Override + public int hashCode() { + return value.hashCode(); + } + + @JsonCreator + public static DoubleAliasedBinaryResult of(@Nonnull AliasedBinaryResult value) { + return new DoubleAliasedBinaryResult(value); + } +} diff --git a/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryService.java b/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryService.java index da7ebb039..1b4cc9a1f 100644 --- a/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryService.java +++ b/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryService.java @@ -53,4 +53,9 @@ StreamingOutput postBinaryThrows( @Produces(MediaType.APPLICATION_OCTET_STREAM) StreamingOutput getBinaryFailure( @HeaderParam("Authorization") @NotNull AuthHeader authHeader, @QueryParam("numBytes") int numBytes); + + @GET + @Path("binary/aliased") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + Optional getAliased(@HeaderParam("Authorization") @NotNull AuthHeader authHeader); } diff --git a/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceAsync.java b/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceAsync.java index 614eb6fd0..f5b42c391 100644 --- a/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceAsync.java +++ b/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceAsync.java @@ -44,6 +44,11 @@ public interface EteBinaryServiceAsync { */ ListenableFuture getBinaryFailure(AuthHeader authHeader, int numBytes); + /** + * @apiNote {@code GET /binary/aliased} + */ + ListenableFuture> getAliased(AuthHeader authHeader); + /** * Creates an asynchronous/non-blocking client for a EteBinaryService service. */ @@ -66,6 +71,9 @@ static EteBinaryServiceAsync of(EndpointChannelFactory _endpointChannelFactory, private final EndpointChannel getBinaryFailureChannel = _endpointChannelFactory.endpoint(DialogueEteBinaryEndpoints.getBinaryFailure); + private final EndpointChannel getAliasedChannel = + _endpointChannelFactory.endpoint(DialogueEteBinaryEndpoints.getAliased); + @Override public ListenableFuture postBinary(AuthHeader authHeader, BinaryRequestBody body) { Request.Builder _request = Request.builder(); @@ -126,6 +134,17 @@ public ListenableFuture getBinaryFailure(AuthHeader authHeader, int _runtime.bodySerDe().inputStreamDeserializer()); } + @Override + public ListenableFuture> getAliased(AuthHeader authHeader) { + Request.Builder _request = Request.builder(); + _request.putHeaderParams("Authorization", authHeader.toString()); + return _runtime.clients() + .call( + getAliasedChannel, + _request.build(), + _runtime.bodySerDe().optionalInputStreamDeserializer()); + } + @Override public String toString() { return "EteBinaryServiceAsync{_endpointChannelFactory=" + _endpointChannelFactory + ", runtime=" diff --git a/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceBlocking.java b/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceBlocking.java index cd2d62095..3e62ac828 100644 --- a/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceBlocking.java +++ b/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceBlocking.java @@ -45,6 +45,11 @@ public interface EteBinaryServiceBlocking { @MustBeClosed InputStream getBinaryFailure(AuthHeader authHeader, int numBytes); + /** + * @apiNote {@code GET /binary/aliased} + */ + Optional getAliased(AuthHeader authHeader); + /** * Creates a synchronous/blocking client for a EteBinaryService service. */ @@ -76,6 +81,11 @@ public InputStream getBinaryFailure(AuthHeader authHeader, int numBytes) { return _runtime.clients().block(delegate.getBinaryFailure(authHeader, numBytes)); } + @Override + public Optional getAliased(AuthHeader authHeader) { + return _runtime.clients().block(delegate.getAliased(authHeader)); + } + @Override public String toString() { return "EteBinaryServiceBlocking{_endpointChannelFactory=" + _endpointChannelFactory + ", runtime=" diff --git a/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceEndpoints.java b/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceEndpoints.java index 81a04d40d..3a6ec70df 100644 --- a/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceEndpoints.java +++ b/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceEndpoints.java @@ -39,7 +39,8 @@ public List endpoints(UndertowRuntime runtime) { new PostBinaryThrowsEndpoint(runtime, delegate), new GetOptionalBinaryPresentEndpoint(runtime, delegate), new GetOptionalBinaryEmptyEndpoint(runtime, delegate), - new GetBinaryFailureEndpoint(runtime, delegate))); + new GetBinaryFailureEndpoint(runtime, delegate), + new GetAliasedEndpoint(runtime, delegate))); } private static final class PostBinaryEndpoint implements HttpHandler, Endpoint { @@ -270,4 +271,51 @@ public HttpHandler handler() { return this; } } + + private static final class GetAliasedEndpoint implements HttpHandler, Endpoint { + private final UndertowRuntime runtime; + + private final UndertowEteBinaryService delegate; + + GetAliasedEndpoint(UndertowRuntime runtime, UndertowEteBinaryService delegate) { + this.runtime = runtime; + this.delegate = delegate; + } + + @Override + public void handleRequest(HttpServerExchange exchange) throws IOException { + AuthHeader authHeader = runtime.auth().header(exchange); + Optional result = delegate.getAliased(authHeader); + if (result.isPresent()) { + runtime.bodySerDe().serialize(result.get(), exchange); + } else { + exchange.setStatusCode(StatusCodes.NO_CONTENT); + } + } + + @Override + public HttpString method() { + return Methods.GET; + } + + @Override + public String template() { + return "/binary/aliased"; + } + + @Override + public String serviceName() { + return "EteBinaryService"; + } + + @Override + public String name() { + return "getAliased"; + } + + @Override + public HttpHandler handler() { + return this; + } + } } diff --git a/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceRetrofit.java b/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceRetrofit.java index 9aa71e153..36c31b235 100644 --- a/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceRetrofit.java +++ b/conjure-java-core/src/integrationInput/java/com/palantir/product/EteBinaryServiceRetrofit.java @@ -47,4 +47,9 @@ ListenableFuture postBinaryThrows( @Streaming ListenableFuture getBinaryFailure( @Header("Authorization") AuthHeader authHeader, @Query("numBytes") int numBytes); + + @GET("./binary/aliased") + @Headers({"hr-path-template: /binary/aliased", "Accept: application/octet-stream"}) + @Streaming + ListenableFuture> getAliased(@Header("Authorization") AuthHeader authHeader); } diff --git a/conjure-java-core/src/integrationInput/java/com/palantir/product/UndertowEteBinaryService.java b/conjure-java-core/src/integrationInput/java/com/palantir/product/UndertowEteBinaryService.java index 11c22d149..5e4293f75 100644 --- a/conjure-java-core/src/integrationInput/java/com/palantir/product/UndertowEteBinaryService.java +++ b/conjure-java-core/src/integrationInput/java/com/palantir/product/UndertowEteBinaryService.java @@ -33,4 +33,9 @@ public interface UndertowEteBinaryService { * @apiNote {@code GET /binary/failure} */ BinaryResponseBody getBinaryFailure(AuthHeader authHeader, int numBytes); + + /** + * @apiNote {@code GET /binary/aliased} + */ + Optional getAliased(AuthHeader authHeader); } diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/JerseyServiceGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/JerseyServiceGenerator.java index 9349d5f87..86122c6bf 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/JerseyServiceGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/JerseyServiceGenerator.java @@ -19,13 +19,14 @@ import com.google.common.collect.ImmutableList; import com.palantir.conjure.java.ConjureAnnotations; import com.palantir.conjure.java.Options; +import com.palantir.conjure.java.types.ClassNameVisitor; import com.palantir.conjure.java.types.DefaultClassNameVisitor; -import com.palantir.conjure.java.types.ReturnTypeClassNameVisitor; import com.palantir.conjure.java.types.SpecializeBinaryClassNameVisitor; import com.palantir.conjure.java.types.TypeMapper; import com.palantir.conjure.java.util.Javadoc; import com.palantir.conjure.java.util.Packages; import com.palantir.conjure.java.util.ParameterOrder; +import com.palantir.conjure.java.util.TypeFunctions; import com.palantir.conjure.spec.ArgumentDefinition; import com.palantir.conjure.spec.AuthType; import com.palantir.conjure.spec.ConjureDefinition; @@ -34,6 +35,7 @@ import com.palantir.conjure.spec.ParameterType; import com.palantir.conjure.spec.ServiceDefinition; import com.palantir.conjure.spec.Type; +import com.palantir.conjure.spec.TypeDefinition; import com.palantir.conjure.visitor.AuthTypeVisitor; import com.palantir.conjure.visitor.ParameterTypeVisitor; import com.palantir.conjure.visitor.TypeVisitor; @@ -50,6 +52,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -75,26 +78,26 @@ public JerseyServiceGenerator(Options options) { } @Override - public Set generate(ConjureDefinition conjureDefinition) { + public List generate(ConjureDefinition conjureDefinition) { ClassName binaryReturnType = options.jerseyBinaryAsResponse() ? BINARY_RETURN_TYPE_RESPONSE : BINARY_RETURN_TYPE_OUTPUT; TypeName optionalBinaryReturnType = options.jerseyBinaryAsResponse() ? BINARY_RETURN_TYPE_RESPONSE : OPTIONAL_BINARY_RETURN_TYPE; + Map types = TypeFunctions.toTypesMap(conjureDefinition); + ClassNameVisitor defaultVisitor = new DefaultClassNameVisitor(types.keySet(), options); TypeMapper returnTypeMapper = new TypeMapper( - conjureDefinition.getTypes(), - new ReturnTypeClassNameVisitor( - conjureDefinition.getTypes(), binaryReturnType, optionalBinaryReturnType, options)); + types, + new SpecializeBinaryClassNameVisitor( + defaultVisitor, types, binaryReturnType, optionalBinaryReturnType)); TypeMapper argumentTypeMapper = new TypeMapper( - conjureDefinition.getTypes(), - new SpecializeBinaryClassNameVisitor( - new DefaultClassNameVisitor(conjureDefinition.getTypes(), options), BINARY_ARGUMENT_TYPE)); + types, new SpecializeBinaryClassNameVisitor(defaultVisitor, types, BINARY_ARGUMENT_TYPE)); return conjureDefinition.getServices().stream() .map(serviceDef -> generateService(serviceDef, returnTypeMapper, argumentTypeMapper)) - .collect(Collectors.toSet()); + .collect(Collectors.toList()); } private JavaFile generateService( diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/Retrofit2ServiceGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/Retrofit2ServiceGenerator.java index a447a7aed..5012494e4 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/Retrofit2ServiceGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/Retrofit2ServiceGenerator.java @@ -21,13 +21,14 @@ import com.google.common.collect.ImmutableSet; import com.palantir.conjure.java.ConjureAnnotations; import com.palantir.conjure.java.Options; +import com.palantir.conjure.java.types.ClassNameVisitor; import com.palantir.conjure.java.types.DefaultClassNameVisitor; -import com.palantir.conjure.java.types.ReturnTypeClassNameVisitor; import com.palantir.conjure.java.types.SpecializeBinaryClassNameVisitor; import com.palantir.conjure.java.types.TypeMapper; import com.palantir.conjure.java.util.Javadoc; import com.palantir.conjure.java.util.Packages; import com.palantir.conjure.java.util.ParameterOrder; +import com.palantir.conjure.java.util.TypeFunctions; import com.palantir.conjure.spec.ArgumentDefinition; import com.palantir.conjure.spec.ArgumentName; import com.palantir.conjure.spec.AuthType; @@ -37,6 +38,7 @@ import com.palantir.conjure.spec.ParameterId; import com.palantir.conjure.spec.ParameterType; import com.palantir.conjure.spec.ServiceDefinition; +import com.palantir.conjure.spec.TypeDefinition; import com.palantir.conjure.visitor.AuthTypeVisitor; import com.palantir.conjure.visitor.ParameterTypeVisitor; import com.palantir.util.syntacticpath.Path; @@ -52,6 +54,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.regex.Matcher; @@ -72,7 +75,7 @@ public final class Retrofit2ServiceGenerator extends ServiceGenerator { private static final ClassName BINARY_ARGUMENT_TYPE = ClassName.get("okhttp3", "RequestBody"); private static final ClassName BINARY_RETURN_TYPE = ClassName.get("okhttp3", "ResponseBody"); private static final TypeName OPTIONAL_BINARY_RETURN_TYPE = - ParameterizedTypeName.get(ClassName.get(Optional.class), ClassName.get("okhttp3", "ResponseBody")); + ParameterizedTypeName.get(ClassName.get(Optional.class), BINARY_RETURN_TYPE); private static final Logger log = LoggerFactory.getLogger(Retrofit2ServiceGenerator.class); @@ -83,20 +86,20 @@ public Retrofit2ServiceGenerator(Options options) { } @Override - public Set generate(ConjureDefinition conjureDefinition) { + public List generate(ConjureDefinition conjureDefinition) { + Map types = TypeFunctions.toTypesMap(conjureDefinition); + ClassNameVisitor defaultVisitor = new DefaultClassNameVisitor(types.keySet(), options); TypeMapper returnTypeMapper = new TypeMapper( - conjureDefinition.getTypes(), - new ReturnTypeClassNameVisitor( - conjureDefinition.getTypes(), BINARY_RETURN_TYPE, OPTIONAL_BINARY_RETURN_TYPE, options)); + types, + new SpecializeBinaryClassNameVisitor( + defaultVisitor, types, BINARY_RETURN_TYPE, OPTIONAL_BINARY_RETURN_TYPE)); TypeMapper argumentTypeMapper = new TypeMapper( - conjureDefinition.getTypes(), - new SpecializeBinaryClassNameVisitor( - new DefaultClassNameVisitor(conjureDefinition.getTypes(), options), BINARY_ARGUMENT_TYPE)); + types, new SpecializeBinaryClassNameVisitor(defaultVisitor, types, BINARY_ARGUMENT_TYPE)); return conjureDefinition.getServices().stream() .map(serviceDef -> generateService(serviceDef, returnTypeMapper, argumentTypeMapper)) - .collect(Collectors.toSet()); + .collect(Collectors.toList()); } private JavaFile generateService( diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/ServiceGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/ServiceGenerator.java index e02eb3fb1..365017c2c 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/ServiceGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/ServiceGenerator.java @@ -28,13 +28,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; -import java.util.Set; import java.util.stream.Collectors; public abstract class ServiceGenerator { /** Returns the set of Java files generated from the service definitions in the given conjure specification. */ - public abstract Set generate(ConjureDefinition conjureDefinition); + public abstract List generate(ConjureDefinition conjureDefinition); /** * Generates and emits to the given output directory all services and types of the given conjure definition, using diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowRequestBodyClassNameVisitor.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowRequestBodyClassNameVisitor.java deleted file mode 100644 index ec8aa49e0..000000000 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowRequestBodyClassNameVisitor.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.palantir.conjure.java.services; - -import com.palantir.conjure.java.Options; -import com.palantir.conjure.java.types.ClassNameVisitor; -import com.palantir.conjure.java.types.DefaultClassNameVisitor; -import com.palantir.conjure.spec.ExternalReference; -import com.palantir.conjure.spec.ListType; -import com.palantir.conjure.spec.MapType; -import com.palantir.conjure.spec.OptionalType; -import com.palantir.conjure.spec.PrimitiveType; -import com.palantir.conjure.spec.SetType; -import com.palantir.conjure.spec.TypeDefinition; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.TypeName; -import java.io.InputStream; -import java.util.List; - -public final class UndertowRequestBodyClassNameVisitor implements ClassNameVisitor { - - private final ClassNameVisitor delegate; - - public UndertowRequestBodyClassNameVisitor(List types, Options options) { - delegate = new DefaultClassNameVisitor(types, options); - } - - @Override - public TypeName visitUnknown(String unknownType) { - return delegate.visitUnknown(unknownType); - } - - @Override - public TypeName visitPrimitive(PrimitiveType primitiveType) { - if (PrimitiveType.BINARY.equals(primitiveType)) { - return ClassName.get(InputStream.class); - } - return delegate.visitPrimitive(primitiveType); - } - - @Override - public TypeName visitOptional(OptionalType optionalType) { - // TODO(ckozak): Support this? I don't know that jersey does. - return delegate.visitOptional(optionalType); - } - - @Override - public TypeName visitList(ListType listType) { - return delegate.visitList(listType); - } - - @Override - public TypeName visitSet(SetType setType) { - return delegate.visitSet(setType); - } - - @Override - public TypeName visitMap(MapType mapType) { - return delegate.visitMap(mapType); - } - - @Override - public TypeName visitReference(com.palantir.conjure.spec.TypeName typeName) { - return delegate.visitReference(typeName); - } - - @Override - public TypeName visitExternal(ExternalReference externalReference) { - return delegate.visitExternal(externalReference); - } -} diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowReturnValueClassNameVisitor.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowReturnValueClassNameVisitor.java deleted file mode 100644 index 9c9a8df52..000000000 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowReturnValueClassNameVisitor.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.palantir.conjure.java.services; - -import com.palantir.conjure.java.Options; -import com.palantir.conjure.java.types.ClassNameVisitor; -import com.palantir.conjure.java.types.DefaultClassNameVisitor; -import com.palantir.conjure.java.undertow.lib.BinaryResponseBody; -import com.palantir.conjure.spec.ExternalReference; -import com.palantir.conjure.spec.ListType; -import com.palantir.conjure.spec.MapType; -import com.palantir.conjure.spec.OptionalType; -import com.palantir.conjure.spec.PrimitiveType; -import com.palantir.conjure.spec.SetType; -import com.palantir.conjure.spec.TypeDefinition; -import com.palantir.conjure.visitor.TypeVisitor; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.ParameterizedTypeName; -import com.squareup.javapoet.TypeName; -import java.util.List; -import java.util.Optional; - -public final class UndertowReturnValueClassNameVisitor implements ClassNameVisitor { - - private final ClassNameVisitor delegate; - - public UndertowReturnValueClassNameVisitor(List types, Options featureFlags) { - delegate = new DefaultClassNameVisitor(types, featureFlags); - } - - @Override - public TypeName visitUnknown(String unknownType) { - return delegate.visitUnknown(unknownType); - } - - @Override - public TypeName visitPrimitive(PrimitiveType primitiveType) { - if (PrimitiveType.BINARY.equals(primitiveType)) { - return ClassName.get(BinaryResponseBody.class); - } - return delegate.visitPrimitive(primitiveType); - } - - @Override - public TypeName visitOptional(OptionalType optionalType) { - if (optionalType.getItemType().accept(TypeVisitor.IS_BINARY)) { - return ParameterizedTypeName.get( - ClassName.get(Optional.class), optionalType.getItemType().accept(this)); - } - return delegate.visitOptional(optionalType); - } - - @Override - public TypeName visitList(ListType listType) { - return delegate.visitList(listType); - } - - @Override - public TypeName visitSet(SetType setType) { - return delegate.visitSet(setType); - } - - @Override - public TypeName visitMap(MapType mapType) { - return delegate.visitMap(mapType); - } - - @Override - public TypeName visitReference(com.palantir.conjure.spec.TypeName typeName) { - return delegate.visitReference(typeName); - } - - @Override - public TypeName visitExternal(ExternalReference externalReference) { - return delegate.visitExternal(externalReference); - } -} diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowServiceGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowServiceGenerator.java index 94624cc74..17dd2af8f 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowServiceGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowServiceGenerator.java @@ -18,13 +18,21 @@ import com.google.common.collect.ImmutableList; import com.palantir.conjure.java.Options; +import com.palantir.conjure.java.types.ClassNameVisitor; +import com.palantir.conjure.java.types.DefaultClassNameVisitor; +import com.palantir.conjure.java.types.SpecializeBinaryClassNameVisitor; import com.palantir.conjure.java.types.TypeMapper; +import com.palantir.conjure.java.undertow.lib.BinaryResponseBody; +import com.palantir.conjure.java.util.TypeFunctions; import com.palantir.conjure.spec.ConjureDefinition; import com.palantir.conjure.spec.ServiceDefinition; import com.palantir.conjure.spec.TypeDefinition; +import com.palantir.conjure.spec.TypeName; +import com.squareup.javapoet.ClassName; import com.squareup.javapoet.JavaFile; +import java.io.InputStream; import java.util.List; -import java.util.Set; +import java.util.Map; import java.util.stream.Collectors; public final class UndertowServiceGenerator extends ServiceGenerator { @@ -36,24 +44,23 @@ public UndertowServiceGenerator(Options options) { } @Override - public Set generate(ConjureDefinition conjureDefinition) { + public List generate(ConjureDefinition conjureDefinition) { + Map types = TypeFunctions.toTypesMap(conjureDefinition); + ClassNameVisitor defaultVisitor = new DefaultClassNameVisitor(types.keySet(), options); + ClassNameVisitor argumentVisitor = + new SpecializeBinaryClassNameVisitor(defaultVisitor, types, ClassName.get(InputStream.class)); + ClassNameVisitor returnVisitor = + new SpecializeBinaryClassNameVisitor(defaultVisitor, types, ClassName.get(BinaryResponseBody.class)); return conjureDefinition.getServices().stream() .flatMap(serviceDef -> generateService( - serviceDef, - conjureDefinition.getTypes(), - new TypeMapper( - conjureDefinition.getTypes(), - new UndertowRequestBodyClassNameVisitor(conjureDefinition.getTypes(), options)), - new TypeMapper( - conjureDefinition.getTypes(), - new UndertowReturnValueClassNameVisitor(conjureDefinition.getTypes(), options))) + serviceDef, types, new TypeMapper(types, argumentVisitor), new TypeMapper(types, returnVisitor)) .stream()) - .collect(Collectors.toSet()); + .collect(Collectors.toList()); } private List generateService( ServiceDefinition serviceDefinition, - List typeDefinitions, + Map typeDefinitions, TypeMapper typeMapper, TypeMapper returnTypeMapper) { return ImmutableList.of( diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowServiceHandlerGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowServiceHandlerGenerator.java index 3ec706f70..a9d225a67 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowServiceHandlerGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowServiceHandlerGenerator.java @@ -35,6 +35,7 @@ import com.palantir.conjure.java.util.JavaNameSanitizer; import com.palantir.conjure.java.util.Packages; import com.palantir.conjure.java.util.ParameterOrder; +import com.palantir.conjure.java.util.TypeFunctions; import com.palantir.conjure.java.visitor.DefaultTypeVisitor; import com.palantir.conjure.java.visitor.MoreVisitors; import com.palantir.conjure.spec.ArgumentDefinition; @@ -108,7 +109,7 @@ final class UndertowServiceHandlerGenerator { public JavaFile generateServiceHandler( ServiceDefinition serviceDefinition, - List typeDefinitions, + Map typeDefinitions, TypeMapper typeMapper, TypeMapper returnTypeMapper) { String serviceName = serviceDefinition.getServiceName().getName(); @@ -204,7 +205,7 @@ private TypeSpec generateEndpointHandler( EndpointDefinition endpointDefinition, ServiceDefinition serviceDefinition, ClassName serviceClass, - List typeDefinitions, + Map typeDefinitions, TypeMapper typeMapper, TypeMapper returnTypeMapper) { MethodSpec.Builder handleMethodBuilder = MethodSpec.methodBuilder("handleRequest") @@ -240,7 +241,10 @@ private TypeSpec generateEndpointHandler( getBodyParamTypeArgument(endpointDefinition.getArgs()) .map(ArgumentDefinition::getType) // Filter out binary data - .flatMap(type -> type.accept(TypeVisitor.IS_BINARY) ? Optional.empty() : Optional.of(type)) + .flatMap(type -> { + Type dealiased = TypeFunctions.toConjureTypeWithoutAliases(type, typeDefinitions); + return TypeFunctions.isBinaryOrOptionalBinary(dealiased) ? Optional.empty() : Optional.of(type); + }) .map(typeMapper::getClassName) .map(TypeName::box) .map(this::immutableCollection) @@ -257,7 +261,8 @@ private TypeSpec generateEndpointHandler( }); endpointDefinition.getReturns().ifPresent(returnType -> { - if (!UndertowTypeFunctions.isOptionalBinary(returnType) && !returnType.accept(TypeVisitor.IS_BINARY)) { + Type dealiased = TypeFunctions.toConjureTypeWithoutAliases(returnType, typeDefinitions); + if (!TypeFunctions.isBinaryOrOptionalBinary(dealiased)) { TypeName typeName = returnTypeMapper.getClassName(returnType).box(); TypeName type = ParameterizedTypeName.get(ClassName.get(Serializer.class), typeName); endpointBuilder.addField(FieldSpec.builder(type, SERIALIZER_VAR_NAME, Modifier.PRIVATE, Modifier.FINAL) @@ -370,7 +375,7 @@ private TypeName immutableCollection(TypeName input) { private CodeBlock endpointInvocation( EndpointDefinition endpointDefinition, - List typeDefinitions, + Map typeDefinitions, TypeMapper typeMapper, TypeMapper returnTypeMapper) { CodeBlock.Builder code = CodeBlock.builder(); @@ -381,8 +386,8 @@ private CodeBlock endpointInvocation( // body parameter getBodyParamTypeArgument(endpointDefinition.getArgs()).ifPresent(bodyParam -> { String paramName = sanitizeVarName(bodyParam.getArgName().get(), endpointDefinition); - if (bodyParam.getType().accept(TypeVisitor.IS_BINARY)) { - // TODO(ckozak): Support aliased and optional binary types + Type dealiased = TypeFunctions.toConjureTypeWithoutAliases(bodyParam.getType(), typeDefinitions); + if (TypeFunctions.isBinaryOrOptionalBinary(dealiased)) { code.addStatement( "$1T $2N = $3N.bodySerDe().deserializeInputStream($4N)", InputStream.class, @@ -447,36 +452,45 @@ private CodeBlock endpointInvocation( } private CodeBlock generateReturnValueCodeBlock( - EndpointDefinition endpointDefinition, List typeDefinitions) { + EndpointDefinition endpointDefinition, + Map typeDefinitions) { CodeBlock.Builder code = CodeBlock.builder(); if (endpointDefinition.getReturns().isPresent()) { Type returnType = endpointDefinition.getReturns().get(); // optional<> handling - // TODO(ckozak): Support aliased binary types - if (UndertowTypeFunctions.toConjureTypeWithoutAliases(returnType, typeDefinitions) - .accept(TypeVisitor.IS_OPTIONAL)) { - CodeBlock serializer = UndertowTypeFunctions.isOptionalBinary(returnType) - ? CodeBlock.builder() - .add( - "$1N.bodySerDe().serialize($2N.get(), $3N)", - RUNTIME_VAR_NAME, - RESULT_VAR_NAME, - EXCHANGE_VAR_NAME) - .build() - : CodeBlock.builder() - .add("$1N.serialize($2N, $3N)", SERIALIZER_VAR_NAME, RESULT_VAR_NAME, EXCHANGE_VAR_NAME) - .build(); + Type dealiased = TypeFunctions.toConjureTypeWithoutAliases(returnType, typeDefinitions); + if (dealiased.accept(TypeVisitor.IS_OPTIONAL)) { + CodeBlock serializer; + if (TypeFunctions.isBinaryOrOptionalBinary(dealiased)) { + serializer = CodeBlock.builder() + .add( + dealiased.accept(TypeVisitor.IS_BINARY) + ? "$1N.bodySerDe().serialize($2N, $3N)" + : "$1N.bodySerDe().serialize($2N.get(), $3N)", + RUNTIME_VAR_NAME, + RESULT_VAR_NAME, + EXCHANGE_VAR_NAME) + .build(); + } else { + serializer = CodeBlock.builder() + .add("$1N.serialize($2N, $3N)", SERIALIZER_VAR_NAME, RESULT_VAR_NAME, EXCHANGE_VAR_NAME) + .build(); + } // For optional<>: set response code to 204/NO_CONTENT if result is absent code.add(CodeBlock.builder() .beginControlFlow( - "if ($1L)", createIsOptionalPresentCall(returnType, RESULT_VAR_NAME, typeDefinitions)) + "if ($1L)", + createIsOptionalPresentCall( + TypeFunctions.isBinaryOrOptionalBinary(dealiased) ? dealiased : returnType, + RESULT_VAR_NAME, + typeDefinitions)) .addStatement(serializer) .nextControlFlow("else") .addStatement("$1N.setStatusCode($2T.NO_CONTENT)", EXCHANGE_VAR_NAME, StatusCodes.class) .endControlFlow() .build()); } else { - if (returnType.accept(TypeVisitor.IS_BINARY)) { + if (dealiased.accept(TypeVisitor.IS_BINARY)) { code.addStatement( "$1N.bodySerDe().serialize($2N, $3N)", RUNTIME_VAR_NAME, @@ -558,7 +572,7 @@ public Optional visitUnknown(String unknownType) { private void addPathParamsCode( CodeBlock.Builder code, EndpointDefinition endpointDefinition, - List typeDefinitions, + Map typeDefinitions, TypeMapper typeMapper) { if (hasPathArgument(endpointDefinition.getArgs())) { code.addStatement( @@ -575,7 +589,7 @@ private void addPathParamsCode( private void addHeaderParamsCode( CodeBlock.Builder code, EndpointDefinition endpointDefinition, - List typeDefinitions, + Map typeDefinitions, TypeMapper typeMapper) { if (hasHeaderArgument(endpointDefinition.getArgs())) { code.addStatement( @@ -590,7 +604,7 @@ private void addHeaderParamsCode( private void addQueryParamsCode( CodeBlock.Builder code, EndpointDefinition endpointDefinition, - List typeDefinitions, + Map typeDefinitions, TypeMapper typeMapper) { if (hasQueryArgument(endpointDefinition.getArgs())) { code.addStatement( @@ -618,7 +632,9 @@ private boolean hasHeaderArgument(List args) { } private CodeBlock generatePathParameterCodeBlock( - EndpointDefinition endpoint, List typeDefinitions, TypeMapper typeMapper) { + EndpointDefinition endpoint, + Map typeDefinitions, + TypeMapper typeMapper) { return generateParameterCodeBlock( endpoint, ParameterTypeVisitor.IS_PATH, @@ -629,7 +645,9 @@ private CodeBlock generatePathParameterCodeBlock( } private CodeBlock generateQueryParameterCodeBlock( - EndpointDefinition endpoint, List typeDefinitions, TypeMapper typeMapper) { + EndpointDefinition endpoint, + Map typeDefinitions, + TypeMapper typeMapper) { return generateParameterCodeBlock( endpoint, ParameterTypeVisitor.IS_QUERY, @@ -643,7 +661,9 @@ private CodeBlock generateQueryParameterCodeBlock( } private CodeBlock generateHeaderParameterCodeBlock( - EndpointDefinition endpoint, List typeDefinitions, TypeMapper typeMapper) { + EndpointDefinition endpoint, + Map typeDefinitions, + TypeMapper typeMapper) { return generateParameterCodeBlock( endpoint, ParameterTypeVisitor.IS_HEADER, @@ -661,18 +681,17 @@ private CodeBlock generateParameterCodeBlock( ParameterType.Visitor paramTypeVisitor, String paramsVarName, Function toParamId, - List typeDefinitions, + Map typeDefinitions, TypeMapper typeMapper) { return CodeBlocks.of(endpoint.getArgs().stream() .filter(param -> param.getParamType().accept(paramTypeVisitor)) .map(arg -> { - Type normalizedType = - UndertowTypeFunctions.toConjureTypeWithoutAliases(arg.getType(), typeDefinitions); + Type normalizedType = TypeFunctions.toConjureTypeWithoutAliases(arg.getType(), typeDefinitions); String paramName = sanitizeVarName(arg.getArgName().get(), endpoint); final CodeBlock retrieveParam; if (normalizedType.equals(arg.getType()) // Collections of alias types are handled the same way as external imports - || UndertowTypeFunctions.isCollectionType(arg.getType())) { + || TypeFunctions.isListOrSet(arg.getType())) { // type is not an alias or optional of an alias retrieveParam = decodePlainParameterCodeBlock( arg.getType(), typeMapper, paramName, paramsVarName, toParamId.apply(arg)); @@ -823,13 +842,13 @@ public Optional visitDefault() { * optional. */ private static CodeBlock createIsOptionalPresentCall( - Type inType, String varName, List typeDefinitions) { + Type inType, String varName, Map typeDefinitions) { if (inType.accept(TypeVisitor.IS_OPTIONAL)) { // current type is optional type: call isPresent return CodeBlock.of("$1N.isPresent()", varName); - } else if (UndertowTypeFunctions.isAliasType(inType)) { + } else if (TypeFunctions.isReferenceType(inType)) { // current type is an alias type: call "get()" to resolve alias and generate recursively on aliased type - Type aliasedType = UndertowTypeFunctions.getAliasedType(inType, typeDefinitions); + Type aliasedType = TypeFunctions.getReferencedType(inType, typeDefinitions); return createIsOptionalPresentCall(aliasedType, varName + ".get()", typeDefinitions); } else { throw new IllegalArgumentException("inType must be either an optional or alias type, was " + inType); @@ -850,7 +869,10 @@ private static CodeBlock createIsOptionalPresentCall( * these rules (recursive definition). */ private static CodeBlock createConstructorForTypeWithReference( - Type inType, String decodedVarName, List typeDefinitions, TypeMapper typeMapper) { + Type inType, + String decodedVarName, + Map typeDefinitions, + TypeMapper typeMapper) { // "in" must be 1 of 2 types: optional or alias if (inType.accept(TypeVisitor.IS_OPTIONAL)) { // optional @@ -870,7 +892,7 @@ private static CodeBlock createConstructorForTypeWithReference( // * optional // * optional // * alias that follows one of these rules (recursive definition) - Type aliasedType = UndertowTypeFunctions.getAliasedType(inType, typeDefinitions); + Type aliasedType = TypeFunctions.getReferencedType(inType, typeDefinitions); if (aliasedType.accept(TypeVisitor.IS_PRIMITIVE) || aliasedType.accept(MoreVisitors.IS_EXTERNAL)) { // primitive ofContent = CodeBlock.of("$1N", decodedVarName); @@ -899,14 +921,12 @@ private static CodeBlock createConstructorForTypeWithReference( private static String deserializeFunctionName(Type type) { if (type.accept(TypeVisitor.IS_PRIMITIVE)) { - return "deserialize" - + UndertowTypeFunctions.primitiveTypeName(type.accept(UndertowTypeFunctions.PRIMITIVE_VISITOR)); + return "deserialize" + TypeFunctions.primitiveTypeName(type.accept(TypeFunctions.PRIMITIVE_VISITOR)); } else if (type.accept(TypeVisitor.IS_OPTIONAL) && type.accept(TypeVisitor.OPTIONAL).getItemType().accept(TypeVisitor.IS_PRIMITIVE)) { - PrimitiveType innerPrimitiveType = type.accept(UndertowTypeFunctions.OPTIONAL_VISITOR) - .getItemType() - .accept(UndertowTypeFunctions.PRIMITIVE_VISITOR); - return "deserializeOptional" + UndertowTypeFunctions.primitiveTypeName(innerPrimitiveType); + PrimitiveType innerPrimitiveType = + type.accept(TypeFunctions.OPTIONAL_VISITOR).getItemType().accept(TypeFunctions.PRIMITIVE_VISITOR); + return "deserializeOptional" + TypeFunctions.primitiveTypeName(innerPrimitiveType); } else if (type.accept(TypeVisitor.IS_LIST) && type.accept(TypeVisitor.LIST).getItemType().accept(TypeVisitor.IS_PRIMITIVE)) { Type subtype = type.accept(TypeVisitor.LIST).getItemType(); diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowTypeFunctions.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowTypeFunctions.java index f1726200f..2c4318ac6 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowTypeFunctions.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/UndertowTypeFunctions.java @@ -1,5 +1,5 @@ /* - * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. + * (c) Copyright 2020 Palantir Technologies Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,195 +17,16 @@ package com.palantir.conjure.java.services; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; import com.google.common.util.concurrent.ListenableFuture; import com.palantir.conjure.java.Options; import com.palantir.conjure.java.types.TypeMapper; -import com.palantir.conjure.java.visitor.DefaultTypeVisitor; -import com.palantir.conjure.spec.AliasDefinition; import com.palantir.conjure.spec.EndpointDefinition; -import com.palantir.conjure.spec.ExternalReference; -import com.palantir.conjure.spec.ListType; -import com.palantir.conjure.spec.MapType; -import com.palantir.conjure.spec.OptionalType; -import com.palantir.conjure.spec.PrimitiveType; -import com.palantir.conjure.spec.SetType; -import com.palantir.conjure.spec.Type; -import com.palantir.conjure.spec.TypeDefinition; -import com.palantir.conjure.visitor.TypeDefinitionVisitor; -import com.palantir.conjure.visitor.TypeVisitor; import com.palantir.logsafe.SafeArg; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.ParameterizedTypeName; -import java.util.List; -import java.util.Optional; final class UndertowTypeFunctions { - static boolean isAliasType(Type type) { - return type.accept(new IsTypeVisitor() { - @Override - public Boolean visitReference(com.palantir.conjure.spec.TypeName _value) { - return true; - } - }); - } - - static boolean isOptionalBinary(Type type) { - return type.accept(new IsTypeVisitor() { - @Override - public Boolean visitOptional(OptionalType value) { - return value.getItemType().accept(TypeVisitor.IS_BINARY); - } - }); - } - - static boolean isCollectionType(Type type) { - return type.accept(TypeVisitor.IS_LIST) || type.accept(TypeVisitor.IS_SET); - } - - // Returns the type that the given alias type refers to. For example, if the input type is defined as - // "alias: integer", the returned type will be the type for "integer". The provided type must be an alias - // (reference) type. - static Type getAliasedType(Type type, List typeDefinitions) { - com.palantir.logsafe.Preconditions.checkArgument( - isAliasType(type), "Expected an alias", SafeArg.of("type", type)); - return getAliasedType( - type.accept(new AbstractTypeVisitor() { - @Override - public com.palantir.conjure.spec.TypeName visitReference( - com.palantir.conjure.spec.TypeName value) { - return value; - } - }), - typeDefinitions) - .get(); - } - - static Optional getAliasedType( - com.palantir.conjure.spec.TypeName typeName, List typeDefinitions) { - // return type definition for the provided alias type - TypeDefinition typeDefinition = typeDefinitions.stream() - .filter(typeDef -> { - com.palantir.conjure.spec.TypeName currName = typeDef.accept(TypeDefinitionVisitor.TYPE_NAME); - String currClassName = currName.getPackage() + "." + currName.getName(); - return currClassName.equals(typeName.getPackage() + "." + typeName.getName()); - }) - .findFirst() - .get(); - - if (typeDefinition.accept(TypeDefinitionVisitor.IS_ALIAS)) { - AliasDefinition aliasDefinition = typeDefinition.accept(TypeDefinitionVisitor.ALIAS); - return Optional.of(aliasDefinition.getAlias()); - } - return Optional.empty(); - } - - private static final ImmutableMap PRIMITIVE_TO_TYPE_NAME = new ImmutableMap.Builder< - PrimitiveType.Value, String>() - .put(PrimitiveType.Value.BEARERTOKEN, "BearerToken") - .put(PrimitiveType.Value.BOOLEAN, "Boolean") - .put(PrimitiveType.Value.DATETIME, "DateTime") - .put(PrimitiveType.Value.DOUBLE, "Double") - .put(PrimitiveType.Value.INTEGER, "Integer") - .put(PrimitiveType.Value.RID, "Rid") - .put(PrimitiveType.Value.SAFELONG, "SafeLong") - .put(PrimitiveType.Value.STRING, "String") - .put(PrimitiveType.Value.UUID, "Uuid") - .build(); - - static String primitiveTypeName(PrimitiveType in) { - String typeName = PRIMITIVE_TO_TYPE_NAME.get(in.get()); - if (typeName == null) { - throw new IllegalStateException("unrecognized primitive type: " + in); - } - return typeName; - } - - static Type toConjureTypeWithoutAliases(final Type in, final List typeDefinitions) { - return in.accept(new Type.Visitor() { - @Override - public Type visitPrimitive(PrimitiveType _value) { - return in; - } - - @Override - public Type visitOptional(OptionalType value) { - return Type.optional( - OptionalType.of(toConjureTypeWithoutAliases(value.getItemType(), typeDefinitions))); - } - - @Override - public Type visitList(ListType value) { - return Type.list(ListType.of(toConjureTypeWithoutAliases(value.getItemType(), typeDefinitions))); - } - - @Override - public Type visitSet(SetType value) { - return Type.set(SetType.of(toConjureTypeWithoutAliases(value.getItemType(), typeDefinitions))); - } - - @Override - public Type visitMap(MapType value) { - return Type.map(MapType.of( - toConjureTypeWithoutAliases(value.getKeyType(), typeDefinitions), - toConjureTypeWithoutAliases(value.getValueType(), typeDefinitions))); - } - - @Override - public Type visitReference(com.palantir.conjure.spec.TypeName value) { - return getAliasedType(value, typeDefinitions) - .map(aliasedType -> toConjureTypeWithoutAliases(aliasedType, typeDefinitions)) - .orElse(in); - } - - @Override - public Type visitExternal(ExternalReference _value) { - return in; - } - - @Override - public Type visitUnknown(String _unknownType) { - return in; - } - }); - } - - static final GetTypeVisitor PRIMITIVE_VISITOR = new GetTypeVisitor() { - @Override - public PrimitiveType visitPrimitive(PrimitiveType value) { - return value; - } - }; - - static final GetTypeVisitor OPTIONAL_VISITOR = new GetTypeVisitor() { - @Override - public OptionalType visitOptional(OptionalType value) { - return value; - } - }; - - private abstract static class GetTypeVisitor extends DefaultTypeVisitor { - @Override - public T visitUnknown(String _unknownType) { - throw new UnsupportedOperationException(); - } - } - - private abstract static class AbstractTypeVisitor extends DefaultTypeVisitor { - @Override - public T visitDefault() { - throw new UnsupportedOperationException(); - } - } - - private abstract static class IsTypeVisitor extends DefaultTypeVisitor { - @Override - public final Boolean visitDefault() { - return false; - } - } - /** * Asynchronous-processing capable endpoints are generated if either of the following are true. * diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/dialogue/DialogueServiceGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/dialogue/DialogueServiceGenerator.java index 1dbb82d50..9ef66d12c 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/services/dialogue/DialogueServiceGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/services/dialogue/DialogueServiceGenerator.java @@ -18,16 +18,22 @@ import com.palantir.conjure.java.Options; import com.palantir.conjure.java.services.ServiceGenerator; +import com.palantir.conjure.java.types.DefaultClassNameVisitor; +import com.palantir.conjure.java.types.SpecializeBinaryClassNameVisitor; import com.palantir.conjure.java.types.TypeMapper; -import com.palantir.conjure.java.visitor.DialogueClassVisitor; +import com.palantir.conjure.java.util.TypeFunctions; import com.palantir.conjure.spec.ConjureDefinition; import com.palantir.conjure.spec.TypeDefinition; +import com.palantir.conjure.spec.TypeName; import com.palantir.conjure.visitor.TypeDefinitionVisitor; +import com.palantir.dialogue.BinaryRequestBody; import com.palantir.logsafe.Preconditions; import com.palantir.logsafe.SafeArg; +import com.squareup.javapoet.ClassName; import com.squareup.javapoet.JavaFile; +import java.io.InputStream; +import java.util.List; import java.util.Map; -import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -42,16 +48,19 @@ public DialogueServiceGenerator(Options options) { } @Override - public Set generate(ConjureDefinition conjureDefinition) { + public List generate(ConjureDefinition conjureDefinition) { + Map types = TypeFunctions.toTypesMap(conjureDefinition); DialogueEndpointsGenerator endpoints = new DialogueEndpointsGenerator(options); - TypeMapper parameterTypes = new TypeMapper( - conjureDefinition.getTypes(), - new DialogueClassVisitor(conjureDefinition.getTypes(), options, DialogueClassVisitor.Mode.PARAMETER)); + types, + new SpecializeBinaryClassNameVisitor( + new DefaultClassNameVisitor(types.keySet(), options), + types, + ClassName.get(BinaryRequestBody.class))); TypeMapper returnTypes = new TypeMapper( - conjureDefinition.getTypes(), - new DialogueClassVisitor( - conjureDefinition.getTypes(), options, DialogueClassVisitor.Mode.RETURN_VALUE)); + types, + new SpecializeBinaryClassNameVisitor( + new DefaultClassNameVisitor(types.keySet(), options), types, ClassName.get(InputStream.class))); Map typeDefinitionsByName = conjureDefinition.getTypes().stream() .collect(Collectors.toMap( @@ -70,12 +79,10 @@ public Set generate(ConjureDefinition conjureDefinition) { options, new ParameterTypeMapper(parameterTypes), new ReturnTypeMapper(returnTypes)); return conjureDefinition.getServices().stream() - .flatMap(serviceDef -> { - return Stream.of( - endpoints.endpointsClass(serviceDef), - interfaceGenerator.generateBlocking(serviceDef, blockingGenerator), - interfaceGenerator.generateAsync(serviceDef, asyncGenerator)); - }) - .collect(Collectors.toSet()); + .flatMap(serviceDef -> Stream.of( + endpoints.endpointsClass(serviceDef), + interfaceGenerator.generateBlocking(serviceDef, blockingGenerator), + interfaceGenerator.generateAsync(serviceDef, asyncGenerator))) + .collect(Collectors.toList()); } } diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/DefaultClassNameVisitor.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/DefaultClassNameVisitor.java index 05e96ab12..8f01c802b 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/DefaultClassNameVisitor.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/DefaultClassNameVisitor.java @@ -26,8 +26,6 @@ import com.palantir.conjure.spec.OptionalType; import com.palantir.conjure.spec.PrimitiveType; import com.palantir.conjure.spec.SetType; -import com.palantir.conjure.spec.TypeDefinition; -import com.palantir.conjure.visitor.TypeDefinitionVisitor; import com.palantir.conjure.visitor.TypeVisitor; import com.palantir.ri.ResourceIdentifier; import com.palantir.tokens.auth.BearerToken; @@ -36,13 +34,11 @@ import com.squareup.javapoet.TypeName; import java.nio.ByteBuffer; import java.time.OffsetDateTime; -import java.util.List; import java.util.Optional; import java.util.OptionalDouble; import java.util.OptionalInt; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; /** * Maps the conjure type into the 'standard' java type i.e. the type one would use in beans/normal variables (as opposed @@ -50,13 +46,11 @@ */ public final class DefaultClassNameVisitor implements ClassNameVisitor { - private final Set typesByName; + private final Set typeNames; private final Options options; - public DefaultClassNameVisitor(List types, Options options) { - this.typesByName = types.stream() - .map(type -> type.accept(TypeDefinitionVisitor.TYPE_NAME)) - .collect(Collectors.toSet()); + public DefaultClassNameVisitor(Set typeNames, Options options) { + this.typeNames = typeNames; this.options = options; } @@ -144,7 +138,7 @@ public TypeName visitPrimitive(PrimitiveType type) { @Override public TypeName visitReference(com.palantir.conjure.spec.TypeName type) { // Types without namespace are either defined locally in this conjure definition, or raw imports. - if (typesByName.contains(type)) { + if (typeNames.contains(type)) { return ClassName.get( Packages.getPrefixedPackage(type.getPackage(), options.packagePrefix()), type.getName()); } else { diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ErrorGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ErrorGenerator.java index c659b7315..4b609c785 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ErrorGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ErrorGenerator.java @@ -40,7 +40,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -51,7 +50,7 @@ public final class ErrorGenerator { private ErrorGenerator() {} - public static Set generateErrorTypes( + public static List generateErrorTypes( TypeMapper typeMapper, List errorTypeNameToDef, Options options) { return splitErrorDefsByNamespace(errorTypeNameToDef).entrySet().stream() .flatMap(entry -> entry.getValue().entrySet().stream() @@ -60,7 +59,7 @@ public static Set generateErrorTypes( Packages.getPrefixedPackage(entry.getKey(), options.packagePrefix()), innerEntry.getKey(), innerEntry.getValue()))) - .collect(Collectors.toSet()); + .collect(Collectors.toList()); } private static Map>> splitErrorDefsByNamespace( diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ObjectGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ObjectGenerator.java index 3f362956f..cc243e4fa 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ObjectGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ObjectGenerator.java @@ -16,14 +16,14 @@ package com.palantir.conjure.java.types; -import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableList; import com.palantir.conjure.java.Options; +import com.palantir.conjure.java.util.TypeFunctions; import com.palantir.conjure.spec.ErrorDefinition; import com.palantir.conjure.spec.TypeDefinition; import com.palantir.conjure.visitor.TypeDefinitionVisitor; import com.squareup.javapoet.JavaFile; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; public final class ObjectGenerator implements TypeGenerator { @@ -35,8 +35,8 @@ public ObjectGenerator(Options options) { } @Override - public Set generateTypes(List types) { - TypeMapper typeMapper = new TypeMapper(types, options); + public List generateTypes(List types) { + TypeMapper typeMapper = new TypeMapper(TypeFunctions.toTypesMap(types), options); return types.stream() .map(typeDef -> { @@ -55,16 +55,16 @@ public Set generateTypes(List types) { throw new IllegalArgumentException("Unknown object definition type " + typeDef.getClass()); } }) - .collect(Collectors.toSet()); + .collect(Collectors.toList()); } @Override - public Set generateErrors(List types, List errors) { + public List generateErrors(List types, List errors) { if (errors.isEmpty()) { - return ImmutableSet.of(); + return ImmutableList.of(); } - TypeMapper typeMapper = new TypeMapper(types, options); + TypeMapper typeMapper = new TypeMapper(TypeFunctions.toTypesMap(types), options); return ErrorGenerator.generateErrorTypes(typeMapper, errors, options); } } diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ReturnTypeClassNameVisitor.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ReturnTypeClassNameVisitor.java deleted file mode 100644 index 9836acbc7..000000000 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/ReturnTypeClassNameVisitor.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.palantir.conjure.java.types; - -import com.palantir.conjure.java.Options; -import com.palantir.conjure.spec.ExternalReference; -import com.palantir.conjure.spec.ListType; -import com.palantir.conjure.spec.MapType; -import com.palantir.conjure.spec.OptionalType; -import com.palantir.conjure.spec.PrimitiveType; -import com.palantir.conjure.spec.SetType; -import com.palantir.conjure.spec.Type; -import com.palantir.conjure.spec.TypeDefinition; -import com.palantir.conjure.visitor.TypeDefinitionVisitor; -import com.palantir.conjure.visitor.TypeVisitor; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.TypeName; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -public final class ReturnTypeClassNameVisitor implements ClassNameVisitor { - - private final DefaultClassNameVisitor delegate; - private final Map types; - private final ClassName binaryClassName; - private final TypeName optionalBinaryTypeName; - - public ReturnTypeClassNameVisitor( - List types, - ClassName binaryClassName, - TypeName optionalBinaryTypeName, - Options featureFlags) { - this.delegate = new DefaultClassNameVisitor(types, featureFlags); - this.types = types.stream() - .collect(Collectors.toMap(t -> t.accept(TypeDefinitionVisitor.TYPE_NAME), Function.identity())); - this.binaryClassName = binaryClassName; - this.optionalBinaryTypeName = optionalBinaryTypeName; - } - - @Override - public TypeName visitList(ListType type) { - return delegate.visitList(type); - } - - @Override - public TypeName visitMap(MapType type) { - return delegate.visitMap(type); - } - - @Override - public TypeName visitOptional(OptionalType type) { - if (type.getItemType().accept(TypeVisitor.IS_PRIMITIVE) - && type.getItemType().accept(TypeVisitor.PRIMITIVE).equals(PrimitiveType.BINARY)) { - return optionalBinaryTypeName; - } - return delegate.visitOptional(type); - } - - @Override - public TypeName visitPrimitive(PrimitiveType type) { - if (type.get() == PrimitiveType.Value.BINARY) { - return binaryClassName; - } else { - return delegate.visitPrimitive(type); - } - } - - @Override - public TypeName visitReference(com.palantir.conjure.spec.TypeName type) { - if (!types.containsKey(type)) { - throw new IllegalStateException("Unknown LocalReferenceType type: " + type); - } - - TypeDefinition def = types.get(type); - if (def.accept(TypeDefinitionVisitor.IS_ALIAS)) { - Type aliasType = def.accept(TypeDefinitionVisitor.ALIAS).getAlias(); - TypeName aliasTypeName = aliasType.accept(this); - if (aliasTypeName.equals(binaryClassName)) { - return aliasTypeName; - } - } - - return delegate.visitReference(type); - } - - @Override - public TypeName visitExternal(ExternalReference type) { - return delegate.visitExternal(type); - } - - @Override - public TypeName visitSet(SetType type) { - return delegate.visitSet(type); - } -} diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/SpecializeBinaryClassNameVisitor.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/SpecializeBinaryClassNameVisitor.java index a0ce6ce7f..eddb83ebc 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/SpecializeBinaryClassNameVisitor.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/SpecializeBinaryClassNameVisitor.java @@ -1,5 +1,5 @@ /* - * (c) Copyright 2019 Palantir Technologies Inc. All rights reserved. + * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,60 +16,99 @@ package com.palantir.conjure.java.types; +import com.palantir.conjure.java.util.TypeFunctions; import com.palantir.conjure.spec.ExternalReference; import com.palantir.conjure.spec.ListType; import com.palantir.conjure.spec.MapType; import com.palantir.conjure.spec.OptionalType; import com.palantir.conjure.spec.PrimitiveType; import com.palantir.conjure.spec.SetType; +import com.palantir.conjure.spec.Type; +import com.palantir.conjure.spec.TypeDefinition; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; +import java.util.Map; +import java.util.Optional; public final class SpecializeBinaryClassNameVisitor implements ClassNameVisitor { private final ClassNameVisitor delegate; - private final TypeName binaryClassName; + private final Map types; + private final ClassName binaryClassName; + private final TypeName optionalBinaryTypeName; - public SpecializeBinaryClassNameVisitor(ClassNameVisitor delegate, TypeName binaryClassName) { + public SpecializeBinaryClassNameVisitor( + ClassNameVisitor delegate, + Map types, + ClassName binaryClassName) { + this( + delegate, + types, + binaryClassName, + ParameterizedTypeName.get(ClassName.get(Optional.class), binaryClassName)); + } + + public SpecializeBinaryClassNameVisitor( + ClassNameVisitor delegate, + Map types, + ClassName binaryClassName, + TypeName optionalBinaryTypeName) { this.delegate = delegate; + this.types = types; this.binaryClassName = binaryClassName; + this.optionalBinaryTypeName = optionalBinaryTypeName; } @Override - public TypeName visitPrimitive(PrimitiveType value) { - if (value.get() == PrimitiveType.Value.BINARY) { - return binaryClassName; - } else { - return delegate.visitPrimitive(value); - } + public TypeName visitList(ListType type) { + return delegate.visitList(type); } @Override - public TypeName visitOptional(OptionalType value) { - return delegate.visitOptional(value); + public TypeName visitMap(MapType type) { + return delegate.visitMap(type); } @Override - public TypeName visitList(ListType value) { - return delegate.visitList(value); + public TypeName visitOptional(OptionalType type) { + return dealiasBinary(type.getItemType()) + .map(_ignored -> optionalBinaryTypeName) + .orElseGet(() -> delegate.visitOptional(type)); } @Override - public TypeName visitSet(SetType value) { - return delegate.visitSet(value); + public TypeName visitPrimitive(PrimitiveType type) { + if (type.get() == PrimitiveType.Value.BINARY) { + return binaryClassName; + } else { + return delegate.visitPrimitive(type); + } } @Override - public TypeName visitMap(MapType value) { - return delegate.visitMap(value); + public TypeName visitReference(com.palantir.conjure.spec.TypeName typeName) { + return TypeFunctions.getReferencedType(typeName, types) + .flatMap(this::dealiasBinary) + .map(value -> value.accept(SpecializeBinaryClassNameVisitor.this)) + .orElseGet(() -> delegate.visitReference(typeName)); } @Override - public TypeName visitReference(com.palantir.conjure.spec.TypeName value) { - return delegate.visitReference(value); + public TypeName visitExternal(ExternalReference type) { + return delegate.visitExternal(type); } @Override - public TypeName visitExternal(ExternalReference value) { - return delegate.visitExternal(value); + public TypeName visitSet(SetType type) { + return delegate.visitSet(type); + } + + private Optional dealiasBinary(Type input) { + Type dealiased = TypeFunctions.toConjureTypeWithoutAliases(input, types); + if (TypeFunctions.isBinaryOrOptionalBinary(dealiased)) { + return Optional.of(dealiased); + } + return Optional.empty(); } } diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeGenerator.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeGenerator.java index 80848e6e6..0e7485105 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeGenerator.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeGenerator.java @@ -24,14 +24,12 @@ import java.io.File; import java.nio.file.Path; import java.util.ArrayList; -import java.util.LinkedHashSet; import java.util.List; -import java.util.Set; public interface TypeGenerator { - default Set generate(ConjureDefinition conjureDefinition) { - Set files = new LinkedHashSet<>(); + default List generate(ConjureDefinition conjureDefinition) { + List files = new ArrayList<>(conjureDefinition.getTypes().size()); // Generate java files for type definitions generateTypes(conjureDefinition.getTypes()).forEach(files::add); @@ -56,7 +54,7 @@ default List emit(ConjureDefinition conjureDefinition, File outputDir) { return emittedPaths; } - Set generateTypes(List types); + List generateTypes(List types); - Set generateErrors(List types, List errors); + List generateErrors(List types, List errors); } diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeMapper.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeMapper.java index 9eb536a11..edc43eb6e 100644 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeMapper.java +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/types/TypeMapper.java @@ -19,26 +19,22 @@ import com.palantir.conjure.java.Options; import com.palantir.conjure.spec.Type; import com.palantir.conjure.spec.TypeDefinition; -import com.palantir.conjure.visitor.TypeDefinitionVisitor; import com.squareup.javapoet.TypeName; -import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Collectors; public final class TypeMapper { private final Map types; private final ClassNameVisitor classNameVisitor; - public TypeMapper(List types, Options options) { - this(types, new DefaultClassNameVisitor(types, options)); + public TypeMapper(Map types, Options options) { + this(types, new DefaultClassNameVisitor(types.keySet(), options)); } - public TypeMapper(List types, ClassNameVisitor classNameVisitor) { - this.types = types.stream() - .collect(Collectors.toMap(t -> t.accept(TypeDefinitionVisitor.TYPE_NAME), Function.identity())); + public TypeMapper( + Map types, ClassNameVisitor classNameVisitor) { + this.types = types; this.classNameVisitor = classNameVisitor; } diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/util/TypeFunctions.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/util/TypeFunctions.java new file mode 100644 index 000000000..b4ec7092e --- /dev/null +++ b/conjure-java-core/src/main/java/com/palantir/conjure/java/util/TypeFunctions.java @@ -0,0 +1,221 @@ +/* + * (c) Copyright 2020 Palantir Technologies Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.palantir.conjure.java.util; + +import com.google.common.collect.ImmutableMap; +import com.palantir.conjure.java.visitor.DefaultTypeVisitor; +import com.palantir.conjure.spec.AliasDefinition; +import com.palantir.conjure.spec.ConjureDefinition; +import com.palantir.conjure.spec.ExternalReference; +import com.palantir.conjure.spec.ListType; +import com.palantir.conjure.spec.MapType; +import com.palantir.conjure.spec.OptionalType; +import com.palantir.conjure.spec.PrimitiveType; +import com.palantir.conjure.spec.SetType; +import com.palantir.conjure.spec.Type; +import com.palantir.conjure.spec.TypeDefinition; +import com.palantir.conjure.spec.TypeName; +import com.palantir.conjure.visitor.TypeDefinitionVisitor; +import com.palantir.conjure.visitor.TypeVisitor; +import com.palantir.logsafe.SafeArg; +import com.palantir.logsafe.exceptions.SafeIllegalStateException; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public final class TypeFunctions { + + private static final ImmutableMap PRIMITIVE_TO_TYPE_NAME = new ImmutableMap.Builder< + PrimitiveType.Value, String>() + .put(PrimitiveType.Value.BEARERTOKEN, "BearerToken") + .put(PrimitiveType.Value.BOOLEAN, "Boolean") + .put(PrimitiveType.Value.DATETIME, "DateTime") + .put(PrimitiveType.Value.DOUBLE, "Double") + .put(PrimitiveType.Value.INTEGER, "Integer") + .put(PrimitiveType.Value.RID, "Rid") + .put(PrimitiveType.Value.SAFELONG, "SafeLong") + .put(PrimitiveType.Value.STRING, "String") + .put(PrimitiveType.Value.UUID, "Uuid") + .build(); + + public static boolean isReferenceType(Type type) { + return type.accept(IS_REFERENCE_VISITOR); + } + + public static boolean isOptionalBinary(Type type) { + return type.accept(IS_OPTIONAL_BINARY_VISITOR); + } + + public static boolean isBinaryOrOptionalBinary(Type type) { + return type.accept(TypeVisitor.IS_BINARY) || isOptionalBinary(type); + } + + public static boolean isListOrSet(Type type) { + return type.accept(TypeVisitor.IS_LIST) || type.accept(TypeVisitor.IS_SET); + } + + // Returns the type that the given reference type refers to. For example, if the input type is defined as + // "alias: integer", the returned type will be the type for "integer". The provided type must be an alias + // (reference) type. + public static Type getReferencedType(Type type, Map typeDefinitions) { + com.palantir.logsafe.Preconditions.checkArgument( + isReferenceType(type), "Expected a reference", SafeArg.of("type", type)); + return getReferencedType( + type.accept(new AbstractTypeVisitor() { + @Override + public TypeName visitReference(TypeName value) { + return value; + } + }), + typeDefinitions) + .get(); + } + + public static Optional getReferencedType(TypeName typeName, Map typeDefinitions) { + // return type definition for the provided alias type + TypeDefinition typeDefinition = typeDefinitions.get(typeName); + if (typeDefinition == null) { + throw new SafeIllegalStateException("Failed to find definition for type", SafeArg.of("name", typeName)); + } + if (typeDefinition.accept(TypeDefinitionVisitor.IS_ALIAS)) { + AliasDefinition aliasDefinition = typeDefinition.accept(TypeDefinitionVisitor.ALIAS); + return Optional.of(aliasDefinition.getAlias()); + } + return Optional.empty(); + } + + public static String primitiveTypeName(PrimitiveType in) { + String typeName = PRIMITIVE_TO_TYPE_NAME.get(in.get()); + if (typeName == null) { + throw new IllegalStateException("unrecognized primitive type: " + in); + } + return typeName; + } + + public static Type toConjureTypeWithoutAliases( + final Type in, final Map typeDefinitions) { + return in.accept(new Type.Visitor() { + @Override + public Type visitPrimitive(PrimitiveType _value) { + return in; + } + + @Override + public Type visitOptional(OptionalType value) { + return Type.optional( + OptionalType.of(toConjureTypeWithoutAliases(value.getItemType(), typeDefinitions))); + } + + @Override + public Type visitList(ListType value) { + return Type.list(ListType.of(toConjureTypeWithoutAliases(value.getItemType(), typeDefinitions))); + } + + @Override + public Type visitSet(SetType value) { + return Type.set(SetType.of(toConjureTypeWithoutAliases(value.getItemType(), typeDefinitions))); + } + + @Override + public Type visitMap(MapType value) { + return Type.map(MapType.of( + toConjureTypeWithoutAliases(value.getKeyType(), typeDefinitions), + toConjureTypeWithoutAliases(value.getValueType(), typeDefinitions))); + } + + @Override + public Type visitReference(TypeName value) { + return getReferencedType(value, typeDefinitions) + .map(aliasedType -> toConjureTypeWithoutAliases(aliasedType, typeDefinitions)) + .orElse(in); + } + + @Override + public Type visitExternal(ExternalReference _value) { + return in; + } + + @Override + public Type visitUnknown(String _unknownType) { + return in; + } + }); + } + + public static Map toTypesMap(ConjureDefinition definition) { + return toTypesMap(definition.getTypes()); + } + + public static Map toTypesMap( + List typeDefinitions) { + ImmutableMap.Builder builder = + ImmutableMap.builderWithExpectedSize(typeDefinitions.size()); + typeDefinitions.forEach(def -> builder.put(def.accept(TypeDefinitionVisitor.TYPE_NAME), def)); + return builder.build(); + } + + public static final GetTypeVisitor PRIMITIVE_VISITOR = new GetTypeVisitor() { + @Override + public PrimitiveType visitPrimitive(PrimitiveType value) { + return value; + } + }; + + public static final GetTypeVisitor OPTIONAL_VISITOR = new GetTypeVisitor() { + @Override + public OptionalType visitOptional(OptionalType value) { + return value; + } + }; + + public static final IsTypeVisitor IS_REFERENCE_VISITOR = new IsTypeVisitor() { + @Override + public Boolean visitReference(TypeName _value) { + return true; + } + }; + + public static final IsTypeVisitor IS_OPTIONAL_BINARY_VISITOR = new IsTypeVisitor() { + @Override + public Boolean visitOptional(OptionalType value) { + return value.getItemType().accept(TypeVisitor.IS_BINARY); + } + }; + + private abstract static class GetTypeVisitor extends DefaultTypeVisitor { + @Override + public T visitUnknown(String _unknownType) { + throw new UnsupportedOperationException(); + } + } + + private abstract static class AbstractTypeVisitor extends DefaultTypeVisitor { + @Override + public T visitDefault() { + throw new UnsupportedOperationException(); + } + } + + private abstract static class IsTypeVisitor extends DefaultTypeVisitor { + @Override + public final Boolean visitDefault() { + return false; + } + } + + private TypeFunctions() {} +} diff --git a/conjure-java-core/src/main/java/com/palantir/conjure/java/visitor/DialogueClassVisitor.java b/conjure-java-core/src/main/java/com/palantir/conjure/java/visitor/DialogueClassVisitor.java deleted file mode 100644 index b4b6c9a45..000000000 --- a/conjure-java-core/src/main/java/com/palantir/conjure/java/visitor/DialogueClassVisitor.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.palantir.conjure.java.visitor; - -import com.palantir.conjure.java.Options; -import com.palantir.conjure.java.types.ClassNameVisitor; -import com.palantir.conjure.java.types.DefaultClassNameVisitor; -import com.palantir.conjure.spec.ExternalReference; -import com.palantir.conjure.spec.ListType; -import com.palantir.conjure.spec.MapType; -import com.palantir.conjure.spec.OptionalType; -import com.palantir.conjure.spec.PrimitiveType; -import com.palantir.conjure.spec.SetType; -import com.palantir.conjure.spec.Type; -import com.palantir.conjure.spec.TypeDefinition; -import com.palantir.conjure.visitor.TypeDefinitionVisitor; -import com.palantir.conjure.visitor.TypeVisitor; -import com.palantir.dialogue.BinaryRequestBody; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.ParameterizedTypeName; -import com.squareup.javapoet.TypeName; -import java.io.InputStream; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.function.Function; -import java.util.stream.Collectors; - -public final class DialogueClassVisitor implements ClassNameVisitor { - - public enum Mode { - RETURN_VALUE, - PARAMETER - } - - private final DefaultClassNameVisitor delegate; - private final Mode mode; - private final Map types; - - public DialogueClassVisitor(List types, Options options, Mode mode) { - this.delegate = new DefaultClassNameVisitor(types, options); - this.mode = mode; - this.types = types.stream() - .collect(Collectors.toMap(t -> t.accept(TypeDefinitionVisitor.TYPE_NAME), Function.identity())); - } - - @Override - public TypeName visitPrimitive(PrimitiveType value) { - if (!value.equals(PrimitiveType.BINARY)) { - return delegate.visitPrimitive(value); - } - - if (mode == Mode.RETURN_VALUE) { - return TypeName.get(InputStream.class); - } else { - return TypeName.get(BinaryRequestBody.class); - } - } - - @Override - public TypeName visitOptional(OptionalType value) { - Type itemType = value.getItemType(); - if (itemType.accept(TypeVisitor.IS_BINARY) || itemType.accept(TypeVisitor.IS_REFERENCE)) { - return ParameterizedTypeName.get(ClassName.get(Optional.class), box(itemType.accept(this))); - } - return delegate.visitOptional(value); - } - - private static TypeName box(TypeName input) { - return input.isPrimitive() ? input.box() : input; - } - - @Override - public TypeName visitList(ListType value) { - return delegate.visitList(value); - } - - @Override - public TypeName visitSet(SetType value) { - return delegate.visitSet(value); - } - - @Override - public TypeName visitMap(MapType value) { - return delegate.visitMap(value); - } - - @Override - public TypeName visitReference(com.palantir.conjure.spec.TypeName type) { - if (!types.containsKey(type)) { - throw new IllegalStateException("Unknown LocalReferenceType type: " + type); - } - - TypeDefinition def = types.get(type); - if (def.accept(TypeDefinitionVisitor.IS_ALIAS)) { - Type aliasType = def.accept(TypeDefinitionVisitor.ALIAS).getAlias(); - TypeName aliasTypeName = aliasType.accept(this); - if (aliasTypeName.equals(visitPrimitive(PrimitiveType.BINARY))) { - return aliasTypeName; - } - } - - return delegate.visitReference(type); - } - - @Override - public TypeName visitExternal(ExternalReference value) { - return delegate.visitExternal(value); - } -} diff --git a/conjure-java-core/src/test/java/com/palantir/conjure/java/EteBinaryResource.java b/conjure-java-core/src/test/java/com/palantir/conjure/java/EteBinaryResource.java index 9059b9f52..49c1e9bb6 100644 --- a/conjure-java-core/src/test/java/com/palantir/conjure/java/EteBinaryResource.java +++ b/conjure-java-core/src/test/java/com/palantir/conjure/java/EteBinaryResource.java @@ -71,4 +71,9 @@ public StreamingOutput getBinaryFailure(AuthHeader _authHeader, int numBytes) { throw new SafeRuntimeException("failure"); }; } + + @Override + public Optional getAliased(@NotNull AuthHeader authHeader) { + return Optional.empty(); + } } diff --git a/conjure-java-core/src/test/java/com/palantir/conjure/java/UndertowBinaryResource.java b/conjure-java-core/src/test/java/com/palantir/conjure/java/UndertowBinaryResource.java index 2eef7934e..e1599a5ff 100644 --- a/conjure-java-core/src/test/java/com/palantir/conjure/java/UndertowBinaryResource.java +++ b/conjure-java-core/src/test/java/com/palantir/conjure/java/UndertowBinaryResource.java @@ -71,4 +71,9 @@ public BinaryResponseBody getBinaryFailure(AuthHeader _authHeader, int numBytes) throw new SafeRuntimeException("failure"); }; } + + @Override + public Optional getAliased(AuthHeader _authHeader) { + return Optional.empty(); + } } diff --git a/conjure-java-core/src/test/resources/ete-binary.yml b/conjure-java-core/src/test/resources/ete-binary.yml index 0a65850cc..c89b7fac7 100644 --- a/conjure-java-core/src/test/resources/ete-binary.yml +++ b/conjure-java-core/src/test/resources/ete-binary.yml @@ -1,3 +1,14 @@ +types: + definitions: + default-package: com.palantir.product + objects: + AliasedBinaryResult: + alias: binary + DoubleAliasedBinaryResult: + alias: AliasedBinaryResult + AliasOptionalDoubleAliasedBinaryResult: + alias: optional + services: EteBinaryService: default-auth: header @@ -32,3 +43,6 @@ services: param-type: query docs: Throws an exception after partially writing a binary response. returns: binary + getAliased: + http: GET /aliased + returns: AliasOptionalDoubleAliasedBinaryResult diff --git a/conjure-java-core/src/test/resources/test/api/TestService.java.jersey b/conjure-java-core/src/test/resources/test/api/TestService.java.jersey index 368353564..ea54fffc9 100644 --- a/conjure-java-core/src/test/resources/test/api/TestService.java.jersey +++ b/conjure-java-core/src/test/resources/test/api/TestService.java.jersey @@ -2,7 +2,6 @@ package com.palantir.another; import com.palantir.product.AliasedString; import com.palantir.product.CreateDatasetRequest; -import com.palantir.product.NestedAliasedBinary; import com.palantir.product.datasets.BackingFileSystem; import com.palantir.product.datasets.Dataset; import com.palantir.redaction.Safe; @@ -94,8 +93,8 @@ public interface TestService { @POST @Path("catalog/datasets/upload-raw-aliased") - void uploadAliasedRawData( - @HeaderParam("Authorization") @NotNull AuthHeader authHeader, @NotNull NestedAliasedBinary input); + @Consumes(MediaType.APPLICATION_OCTET_STREAM) + void uploadAliasedRawData(@HeaderParam("Authorization") @NotNull AuthHeader authHeader, @NotNull InputStream input); /** * @param datasetRid A valid dataset resource identifier. diff --git a/conjure-java-core/src/test/resources/test/api/TestService.java.jersey.prefix b/conjure-java-core/src/test/resources/test/api/TestService.java.jersey.prefix index ff81acf98..574d1b333 100644 --- a/conjure-java-core/src/test/resources/test/api/TestService.java.jersey.prefix +++ b/conjure-java-core/src/test/resources/test/api/TestService.java.jersey.prefix @@ -24,7 +24,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.StreamingOutput; import test.prefix.com.palantir.product.AliasedString; import test.prefix.com.palantir.product.CreateDatasetRequest; -import test.prefix.com.palantir.product.NestedAliasedBinary; import test.prefix.com.palantir.product.datasets.BackingFileSystem; import test.prefix.com.palantir.product.datasets.Dataset; @@ -93,7 +92,8 @@ public interface TestService { @POST @Path("catalog/datasets/upload-raw-aliased") - void uploadAliasedRawData(@HeaderParam("Authorization") AuthHeader authHeader, NestedAliasedBinary input); + @Consumes(MediaType.APPLICATION_OCTET_STREAM) + void uploadAliasedRawData(@HeaderParam("Authorization") AuthHeader authHeader, InputStream input); /** * @param datasetRid A valid dataset resource identifier. diff --git a/conjure-java-core/src/test/resources/test/api/TestService.java.jersey_require_not_null b/conjure-java-core/src/test/resources/test/api/TestService.java.jersey_require_not_null index 368353564..ea54fffc9 100644 --- a/conjure-java-core/src/test/resources/test/api/TestService.java.jersey_require_not_null +++ b/conjure-java-core/src/test/resources/test/api/TestService.java.jersey_require_not_null @@ -2,7 +2,6 @@ package com.palantir.another; import com.palantir.product.AliasedString; import com.palantir.product.CreateDatasetRequest; -import com.palantir.product.NestedAliasedBinary; import com.palantir.product.datasets.BackingFileSystem; import com.palantir.product.datasets.Dataset; import com.palantir.redaction.Safe; @@ -94,8 +93,8 @@ public interface TestService { @POST @Path("catalog/datasets/upload-raw-aliased") - void uploadAliasedRawData( - @HeaderParam("Authorization") @NotNull AuthHeader authHeader, @NotNull NestedAliasedBinary input); + @Consumes(MediaType.APPLICATION_OCTET_STREAM) + void uploadAliasedRawData(@HeaderParam("Authorization") @NotNull AuthHeader authHeader, @NotNull InputStream input); /** * @param datasetRid A valid dataset resource identifier. diff --git a/conjure-java-core/src/test/resources/test/api/TestService.java.undertow b/conjure-java-core/src/test/resources/test/api/TestService.java.undertow index dab8d4890..829a824ae 100644 --- a/conjure-java-core/src/test/resources/test/api/TestService.java.undertow +++ b/conjure-java-core/src/test/resources/test/api/TestService.java.undertow @@ -3,7 +3,6 @@ package com.palantir.another; import com.palantir.conjure.java.undertow.lib.BinaryResponseBody; import com.palantir.product.AliasedString; import com.palantir.product.CreateDatasetRequest; -import com.palantir.product.NestedAliasedBinary; import com.palantir.product.datasets.BackingFileSystem; import com.palantir.product.datasets.Dataset; import com.palantir.ri.ResourceIdentifier; @@ -46,7 +45,7 @@ public interface TestService { /** * @apiNote {@code GET /catalog/datasets/{datasetRid}/raw-aliased} */ - NestedAliasedBinary getAliasedRawData(AuthHeader authHeader, ResourceIdentifier datasetRid); + BinaryResponseBody getAliasedRawData(AuthHeader authHeader, ResourceIdentifier datasetRid); /** * @apiNote {@code GET /catalog/datasets/{datasetRid}/raw-maybe} @@ -66,7 +65,7 @@ public interface TestService { /** * @apiNote {@code POST /catalog/datasets/upload-raw-aliased} */ - void uploadAliasedRawData(AuthHeader authHeader, NestedAliasedBinary input); + void uploadAliasedRawData(AuthHeader authHeader, InputStream input); /** * @apiNote {@code GET /catalog/datasets/{datasetRid}/branches} diff --git a/conjure-java-core/src/test/resources/test/api/TestService.java.undertow.prefix b/conjure-java-core/src/test/resources/test/api/TestService.java.undertow.prefix index bd7a298c1..7836eefbd 100644 --- a/conjure-java-core/src/test/resources/test/api/TestService.java.undertow.prefix +++ b/conjure-java-core/src/test/resources/test/api/TestService.java.undertow.prefix @@ -12,7 +12,6 @@ import java.util.Set; import javax.annotation.Generated; import test.prefix.com.palantir.product.AliasedString; import test.prefix.com.palantir.product.CreateDatasetRequest; -import test.prefix.com.palantir.product.NestedAliasedBinary; import test.prefix.com.palantir.product.datasets.BackingFileSystem; import test.prefix.com.palantir.product.datasets.Dataset; @@ -46,7 +45,7 @@ public interface TestService { /** * @apiNote {@code GET /catalog/datasets/{datasetRid}/raw-aliased} */ - NestedAliasedBinary getAliasedRawData(AuthHeader authHeader, ResourceIdentifier datasetRid); + BinaryResponseBody getAliasedRawData(AuthHeader authHeader, ResourceIdentifier datasetRid); /** * @apiNote {@code GET /catalog/datasets/{datasetRid}/raw-maybe} @@ -66,7 +65,7 @@ public interface TestService { /** * @apiNote {@code POST /catalog/datasets/upload-raw-aliased} */ - void uploadAliasedRawData(AuthHeader authHeader, NestedAliasedBinary input); + void uploadAliasedRawData(AuthHeader authHeader, InputStream input); /** * @apiNote {@code GET /catalog/datasets/{datasetRid}/branches} diff --git a/conjure-java-core/src/test/resources/test/api/TestServiceEndpoints.java.undertow b/conjure-java-core/src/test/resources/test/api/TestServiceEndpoints.java.undertow index 91b04eda9..23b4e5a1a 100644 --- a/conjure-java-core/src/test/resources/test/api/TestServiceEndpoints.java.undertow +++ b/conjure-java-core/src/test/resources/test/api/TestServiceEndpoints.java.undertow @@ -9,7 +9,6 @@ import com.palantir.conjure.java.undertow.lib.UndertowRuntime; import com.palantir.conjure.java.undertow.lib.UndertowService; import com.palantir.product.AliasedString; import com.palantir.product.CreateDatasetRequest; -import com.palantir.product.NestedAliasedBinary; import com.palantir.product.datasets.BackingFileSystem; import com.palantir.product.datasets.Dataset; import com.palantir.ri.ResourceIdentifier; @@ -277,12 +276,9 @@ public final class TestServiceEndpoints implements UndertowService { private final TestService delegate; - private final Serializer serializer; - GetAliasedRawDataEndpoint(UndertowRuntime runtime, TestService delegate) { this.runtime = runtime; this.delegate = delegate; - this.serializer = runtime.bodySerDe().serializer(new TypeMarker() {}); } @Override @@ -292,8 +288,8 @@ public final class TestServiceEndpoints implements UndertowService { exchange.getAttachment(PathTemplateMatch.ATTACHMENT_KEY).getParameters(); ResourceIdentifier datasetRid = runtime.plainSerDe().deserializeRid(pathParams.get("datasetRid")); runtime.markers().param("com.palantir.redaction.Safe", "datasetRid", datasetRid, exchange); - NestedAliasedBinary result = delegate.getAliasedRawData(authHeader, datasetRid); - serializer.serialize(result, exchange); + BinaryResponseBody result = delegate.getAliasedRawData(authHeader, datasetRid); + runtime.bodySerDe().serialize(result, exchange); } @Override @@ -474,18 +470,15 @@ public final class TestServiceEndpoints implements UndertowService { private final TestService delegate; - private final Deserializer deserializer; - UploadAliasedRawDataEndpoint(UndertowRuntime runtime, TestService delegate) { this.runtime = runtime; this.delegate = delegate; - this.deserializer = runtime.bodySerDe().deserializer(new TypeMarker() {}); } @Override public void handleRequest(HttpServerExchange exchange) throws IOException { AuthHeader authHeader = runtime.auth().header(exchange); - NestedAliasedBinary input = deserializer.deserialize(exchange); + InputStream input = runtime.bodySerDe().deserializeInputStream(exchange); delegate.uploadAliasedRawData(authHeader, input); exchange.setStatusCode(StatusCodes.NO_CONTENT); } diff --git a/conjure-java-core/src/test/resources/test/api/TestServiceEndpoints.java.undertow.prefix b/conjure-java-core/src/test/resources/test/api/TestServiceEndpoints.java.undertow.prefix index fdf398b5b..40c0e2e3f 100644 --- a/conjure-java-core/src/test/resources/test/api/TestServiceEndpoints.java.undertow.prefix +++ b/conjure-java-core/src/test/resources/test/api/TestServiceEndpoints.java.undertow.prefix @@ -30,7 +30,6 @@ import java.util.Set; import javax.annotation.Generated; import test.prefix.com.palantir.product.AliasedString; import test.prefix.com.palantir.product.CreateDatasetRequest; -import test.prefix.com.palantir.product.NestedAliasedBinary; import test.prefix.com.palantir.product.datasets.BackingFileSystem; import test.prefix.com.palantir.product.datasets.Dataset; @@ -277,12 +276,9 @@ public final class TestServiceEndpoints implements UndertowService { private final TestService delegate; - private final Serializer serializer; - GetAliasedRawDataEndpoint(UndertowRuntime runtime, TestService delegate) { this.runtime = runtime; this.delegate = delegate; - this.serializer = runtime.bodySerDe().serializer(new TypeMarker() {}); } @Override @@ -292,8 +288,8 @@ public final class TestServiceEndpoints implements UndertowService { exchange.getAttachment(PathTemplateMatch.ATTACHMENT_KEY).getParameters(); ResourceIdentifier datasetRid = runtime.plainSerDe().deserializeRid(pathParams.get("datasetRid")); runtime.markers().param("com.palantir.redaction.Safe", "datasetRid", datasetRid, exchange); - NestedAliasedBinary result = delegate.getAliasedRawData(authHeader, datasetRid); - serializer.serialize(result, exchange); + BinaryResponseBody result = delegate.getAliasedRawData(authHeader, datasetRid); + runtime.bodySerDe().serialize(result, exchange); } @Override @@ -474,18 +470,15 @@ public final class TestServiceEndpoints implements UndertowService { private final TestService delegate; - private final Deserializer deserializer; - UploadAliasedRawDataEndpoint(UndertowRuntime runtime, TestService delegate) { this.runtime = runtime; this.delegate = delegate; - this.deserializer = runtime.bodySerDe().deserializer(new TypeMarker() {}); } @Override public void handleRequest(HttpServerExchange exchange) throws IOException { AuthHeader authHeader = runtime.auth().header(exchange); - NestedAliasedBinary input = deserializer.deserialize(exchange); + InputStream input = runtime.bodySerDe().deserializeInputStream(exchange); delegate.uploadAliasedRawData(authHeader, input); exchange.setStatusCode(StatusCodes.NO_CONTENT); } diff --git a/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit b/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit index e1f7a727e..fda7a406c 100644 --- a/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit +++ b/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit @@ -3,7 +3,6 @@ package com.palantir.another; import com.google.common.util.concurrent.ListenableFuture; import com.palantir.product.AliasedString; import com.palantir.product.CreateDatasetRequest; -import com.palantir.product.NestedAliasedBinary; import com.palantir.product.datasets.BackingFileSystem; import com.palantir.product.datasets.Dataset; import com.palantir.ri.ResourceIdentifier; @@ -83,7 +82,7 @@ public interface TestServiceRetrofit { @POST("./catalog/datasets/upload-raw-aliased") @Headers({"hr-path-template: /catalog/datasets/upload-raw-aliased", "Accept: application/json"}) ListenableFuture uploadAliasedRawData( - @Header("Authorization") AuthHeader authHeader, @Body NestedAliasedBinary input); + @Header("Authorization") AuthHeader authHeader, @Body RequestBody input); /** * @param datasetRid A valid dataset resource identifier. diff --git a/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit.prefix b/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit.prefix index 05f5dc190..8c54e2590 100644 --- a/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit.prefix +++ b/conjure-java-core/src/test/resources/test/api/TestServiceRetrofit.java.retrofit.prefix @@ -22,7 +22,6 @@ import retrofit2.http.Query; import retrofit2.http.Streaming; import test.prefix.com.palantir.product.AliasedString; import test.prefix.com.palantir.product.CreateDatasetRequest; -import test.prefix.com.palantir.product.NestedAliasedBinary; import test.prefix.com.palantir.product.datasets.BackingFileSystem; import test.prefix.com.palantir.product.datasets.Dataset; @@ -83,7 +82,7 @@ public interface TestServiceRetrofit { @POST("./catalog/datasets/upload-raw-aliased") @Headers({"hr-path-template: /catalog/datasets/upload-raw-aliased", "Accept: application/json"}) ListenableFuture uploadAliasedRawData( - @Header("Authorization") AuthHeader authHeader, @Body NestedAliasedBinary input); + @Header("Authorization") AuthHeader authHeader, @Body RequestBody input); /** * @param datasetRid A valid dataset resource identifier.