You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by zr...@apache.org on 2018/04/05 11:42:11 UTC
[camel] 02/02: CAMEL-12420: Swagger enums for array types
This is an automated email from the ASF dual-hosted git repository.
zregvart pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 6c260ab0510ab3485c6d8e68b56a6b75b1ff27e8
Author: Zoran Regvart <zr...@apache.org>
AuthorDate: Thu Apr 5 13:24:04 2018 +0200
CAMEL-12420: Swagger enums for array types
When specifying the parameter of an `array` type, the `enum` property
needs to be set on the `items` property. So instead of:
```json
{
"name": "...",
"type": "array",
"items": {
"type": "..."
},
"enum": [...]
```
We should define as:
```json
{
"name": "...",
"type": "array",
"items": {
"type": "...",
"enum": [...]
}
```
---
components/camel-swagger-java/pom.xml | 6 ++
.../apache/camel/swagger/RestSwaggerReader.java | 64 ++++++++++--
.../org/apache/camel/swagger/ParameterAssert.java | 114 +++++++++++++++++++++
.../camel/swagger/RestSwaggerArrayEnumTest.java | 91 ++++++++++++++++
4 files changed, 266 insertions(+), 9 deletions(-)
diff --git a/components/camel-swagger-java/pom.xml b/components/camel-swagger-java/pom.xml
index 4437637..98454f5 100644
--- a/components/camel-swagger-java/pom.xml
+++ b/components/camel-swagger-java/pom.xml
@@ -154,6 +154,12 @@
<artifactId>log4j-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>${assertj-version}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java
index 0cabb1c..b7aa89e 100644
--- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java
+++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerReader.java
@@ -16,6 +16,8 @@
*/
package org.apache.camel.swagger;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -25,6 +27,9 @@ import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.lang.invoke.MethodHandles.publicLookup;
import io.swagger.jaxrs.config.BeanConfig;
import io.swagger.models.ArrayModel;
@@ -260,30 +265,33 @@ public class RestSwaggerReader {
if (parameter instanceof SerializableParameter) {
SerializableParameter serializableParameter = (SerializableParameter) parameter;
+ final boolean isArray = param.getDataType().equalsIgnoreCase("array");
+ final List<String> allowableValues = param.getAllowableValues();
+ final boolean hasAllowableValues = allowableValues != null && !allowableValues.isEmpty();
if (param.getDataType() != null) {
serializableParameter.setType(param.getDataType());
if (param.getDataFormat() != null) {
serializableParameter.setFormat(param.getDataFormat());
}
- if (param.getDataType().equalsIgnoreCase("array")) {
+ if (isArray) {
if (param.getArrayType() != null) {
if (param.getArrayType().equalsIgnoreCase("string")) {
- serializableParameter.setItems(new StringProperty());
+ defineItems(serializableParameter, allowableValues, new StringProperty(), String.class);
}
if (param.getArrayType().equalsIgnoreCase("int") || param.getArrayType().equalsIgnoreCase("integer")) {
- serializableParameter.setItems(new IntegerProperty());
+ defineItems(serializableParameter, allowableValues, new IntegerProperty(), Integer.class);
}
if (param.getArrayType().equalsIgnoreCase("long")) {
- serializableParameter.setItems(new LongProperty());
+ defineItems(serializableParameter, allowableValues, new LongProperty(), Long.class);
}
if (param.getArrayType().equalsIgnoreCase("float")) {
- serializableParameter.setItems(new FloatProperty());
+ defineItems(serializableParameter, allowableValues, new FloatProperty(), Float.class);
}
if (param.getArrayType().equalsIgnoreCase("double")) {
- serializableParameter.setItems(new DoubleProperty());
+ defineItems(serializableParameter, allowableValues, new DoubleProperty(), Double.class);
}
if (param.getArrayType().equalsIgnoreCase("boolean")) {
- serializableParameter.setItems(new BooleanProperty());
+ defineItems(serializableParameter, allowableValues, new BooleanProperty(), Boolean.class);
}
}
}
@@ -291,8 +299,8 @@ public class RestSwaggerReader {
if (param.getCollectionFormat() != null) {
serializableParameter.setCollectionFormat(param.getCollectionFormat().name());
}
- if (param.getAllowableValues() != null && !param.getAllowableValues().isEmpty()) {
- serializableParameter.setEnum(param.getAllowableValues());
+ if (hasAllowableValues && !isArray) {
+ serializableParameter.setEnum(allowableValues);
}
}
@@ -372,6 +380,44 @@ public class RestSwaggerReader {
}
}
+ private static void defineItems(final SerializableParameter serializableParameter,
+ final List<String> allowableValues, final Property items, final Class<?> type) {
+ serializableParameter.setItems(items);
+ if (allowableValues != null && !allowableValues.isEmpty()) {
+ if (String.class.equals(type)) {
+ ((StringProperty) items).setEnum(allowableValues);
+ } else {
+ convertAndSetItemsEnum(items, allowableValues, type);
+ }
+ }
+ }
+
+ private static void convertAndSetItemsEnum(final Property items, final List<String> allowableValues, final Class<?> type) {
+ try {
+ final MethodHandle valueOf = publicLookup().findStatic(type, "valueOf", MethodType.methodType(type, String.class));
+ final MethodHandle setEnum = publicLookup().bind(items, "setEnum",
+ MethodType.methodType(void.class, List.class));
+ final List<?> values = allowableValues.stream().map(v -> {
+ try {
+ return valueOf.invoke(v);
+ } catch (Throwable e) {
+ if (e instanceof RuntimeException) {
+ throw (RuntimeException) e;
+ }
+
+ throw new IllegalStateException(e);
+ }
+ }).collect(Collectors.toList());
+ setEnum.invoke(values);
+ } catch (Throwable e) {
+ if (e instanceof RuntimeException) {
+ throw (RuntimeException) e;
+ }
+
+ throw new IllegalStateException(e);
+ }
+ }
+
private void doParseResponseMessages(Swagger swagger, VerbDefinition verb, Operation op) {
for (RestOperationResponseMsgDefinition msg : verb.getResponseMsgs()) {
Response response = null;
diff --git a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/ParameterAssert.java b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/ParameterAssert.java
new file mode 100644
index 0000000..6c9cdb4
--- /dev/null
+++ b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/ParameterAssert.java
@@ -0,0 +1,114 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.camel.swagger;
+
+import java.lang.invoke.MethodType;
+import java.util.List;
+
+import static java.lang.invoke.MethodHandles.publicLookup;
+
+import io.swagger.models.parameters.Parameter;
+import io.swagger.models.parameters.SerializableParameter;
+import io.swagger.models.properties.Property;
+
+import org.assertj.core.api.Assertions;
+import org.assertj.core.api.ObjectAssert;
+
+public final class ParameterAssert extends ObjectAssert<Parameter> {
+
+ private ParameterAssert(final Parameter actual) {
+ super(actual);
+ }
+
+ public <T> ParameterAssert hasArrayEnumSpecifiedWith(@SuppressWarnings("unchecked") final T... values) {
+ isSerializable();
+
+ final SerializableParameter serializableParameter = (SerializableParameter) actual;
+ final Property items = serializableParameter.getItems();
+ final List<T> arrayItems = fetchEnums(items);
+ Assertions.assertThat(arrayItems).containsOnly(values);
+
+ return this;
+ }
+
+ public ParameterAssert hasEnumSpecifiedWith(final String... values) {
+ isSerializable();
+
+ final SerializableParameter serializableParameter = (SerializableParameter) actual;
+ final List<String> actualEnum = serializableParameter.getEnum();
+
+ Assertions.assertThat(actualEnum).containsOnly(values);
+
+ return this;
+ }
+
+ public ParameterAssert hasName(final String name) {
+ final String actualName = actual.getName();
+ Assertions.assertThat(actualName).as("Parameter name should equal %s, but it's %s", name, actualName);
+
+ return this;
+ }
+
+ public ParameterAssert isGivenIn(final String in) {
+ final String actualIn = actual.getIn();
+ Assertions.assertThat(actualIn).as("Parameter should be specified in %s, but it's in %s", in, actualIn)
+ .isEqualTo(in);
+
+ return this;
+ }
+
+ public ParameterAssert isOfArrayType(final String type) {
+ isSerializable();
+
+ final SerializableParameter serializableParameter = (SerializableParameter) actual;
+ final Property items = serializableParameter.getItems();
+ Assertions.assertThat(items).isNotNull();
+ final String actualArrayType = items.getType();
+ Assertions.assertThat(actualArrayType).as("Parameter array should be of %s type, but it's of %s", type,
+ actualArrayType);
+
+ return this;
+ }
+
+ public ParameterAssert isOfType(final String type) {
+ isSerializable();
+
+ final SerializableParameter serializableParameter = (SerializableParameter) actual;
+ final String actualType = serializableParameter.getType();
+ Assertions.assertThat(actualType).as("Parameter should be of %s type, but it's of %s", type, actualType);
+
+ return this;
+ }
+
+ public ParameterAssert isSerializable() {
+ isInstanceOf(SerializableParameter.class);
+
+ return this;
+ }
+
+ public static ParameterAssert assertThat(final Parameter actual) {
+ return new ParameterAssert(actual);
+ }
+
+ private static <T> List<T> fetchEnums(final Property items) {
+ try {
+ return (List<T>) publicLookup().bind(items, "getEnum", MethodType.methodType(List.class)).invoke();
+ } catch (final Throwable e) {
+ throw new AssertionError(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerArrayEnumTest.java b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerArrayEnumTest.java
new file mode 100644
index 0000000..e3276a0
--- /dev/null
+++ b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerArrayEnumTest.java
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.camel.swagger;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import io.swagger.jaxrs.config.BeanConfig;
+import io.swagger.models.Operation;
+import io.swagger.models.Path;
+import io.swagger.models.Swagger;
+import io.swagger.models.parameters.Parameter;
+
+import org.apache.camel.impl.DefaultClassResolver;
+import org.apache.camel.model.rest.RestDefinition;
+import org.apache.camel.model.rest.RestParamType;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class RestSwaggerArrayEnumTest {
+
+ @Test
+ public void shouldGenerateEnumValuesForArraysAndNonArrays() {
+ final RestSwaggerReader reader = new RestSwaggerReader();
+
+ final RestDefinition restDefinition = new RestDefinition();
+ restDefinition.get("/operation").param().name("pathParam").type(RestParamType.path).dataType("string")
+ .allowableValues("a", "b", "c").endParam()
+
+ .param().name("queryParam").type(RestParamType.query).dataType("int").allowableValues("1", "2", "3")
+ .endParam()
+
+ .param().name("headerParam").type(RestParamType.header).dataType("float")
+ .allowableValues("1.1", "2.2", "3.3").endParam()
+
+ .param().name("pathArrayParam").type(RestParamType.path).dataType("array").arrayType("string")
+ .allowableValues("a", "b", "c").endParam()
+
+ .param().name("queryArrayParam").type(RestParamType.query).dataType("array").arrayType("int")
+ .allowableValues("1", "2", "3").endParam()
+
+ .param().name("headerArrayParam").type(RestParamType.header).dataType("array").arrayType("float")
+ .allowableValues("1.1", "2.2", "3.3").endParam();
+
+ final Swagger swagger = reader.read(Collections.singletonList(restDefinition), null, new BeanConfig(),
+ "camel-1", new DefaultClassResolver());
+
+ assertThat(swagger).isNotNull();
+ final Map<String, Path> paths = swagger.getPaths();
+ assertThat(paths).containsKey("/operation");
+ final Operation getOperation = paths.get("/operation").getGet();
+ assertThat(getOperation).isNotNull();
+ final List<Parameter> parameters = getOperation.getParameters();
+ assertThat(parameters).hasSize(6);
+
+ ParameterAssert.assertThat(parameters.get(0)).hasName("pathParam").isGivenIn("path").isOfType("string")
+ .hasEnumSpecifiedWith("a", "b", "c");
+
+ ParameterAssert.assertThat(parameters.get(1)).hasName("queryParam").isGivenIn("query").isOfType("string")
+ .hasEnumSpecifiedWith("1", "2", "3");
+
+ ParameterAssert.assertThat(parameters.get(2)).hasName("headerParam").isGivenIn("header").isOfType("string")
+ .hasEnumSpecifiedWith("1.1", "2.2", "3.3");
+
+ ParameterAssert.assertThat(parameters.get(3)).hasName("pathArrayParam").isGivenIn("path").isOfType("array")
+ .isOfArrayType("string").hasArrayEnumSpecifiedWith("a", "b", "c");
+
+ ParameterAssert.assertThat(parameters.get(4)).hasName("queryParam").isGivenIn("query").isOfType("array")
+ .isOfArrayType("int").hasArrayEnumSpecifiedWith(1, 2, 3);
+
+ ParameterAssert.assertThat(parameters.get(5)).hasName("headerParam").isGivenIn("header").isOfType("array")
+ .isOfArrayType("float").hasArrayEnumSpecifiedWith(1.1f, 2.2f, 3.3f);
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
zregvart@apache.org.