Skip to content

Commit

Permalink
Fix NPE with Haskell client generator with OAS3 spec (#334)
Browse files Browse the repository at this point in the history
* fix NPE with haskell client oas3, better type check

* better unknown type check
  • Loading branch information
wing328 committed May 6, 2018
1 parent d99f46c commit e45b378
Show file tree
Hide file tree
Showing 22 changed files with 677 additions and 729 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1233,7 +1233,7 @@ public String getSchemaType(Schema schema) {
}
}

if (StringUtils.isNotBlank(schema.get$ref())) { // object
if (StringUtils.isNotBlank(schema.get$ref())) { // reference to another definition/schema
// get the schema/model name from $ref
String schemaName = ModelUtils.getSimpleRef(schema.get$ref());
if (StringUtils.isNotEmpty(schemaName)) {
Expand All @@ -1242,7 +1242,7 @@ public String getSchemaType(Schema schema) {
LOGGER.warn("Error obtaining the datatype from ref:" + schema.get$ref() + ". Default to 'object'");
return "object";
}
} else { // primitive type (non-model)
} else { // primitive type or model
return getAlias(getPrimitiveType(schema));
}
}
Expand All @@ -1255,7 +1255,9 @@ public String getSchemaType(Schema schema) {
* @return type
*/
private static String getPrimitiveType(Schema schema) {
if (ModelUtils.isStringSchema(schema) && "number".equals(schema.getFormat())) {
if (schema == null) {
throw new RuntimeException("schema cannnot be null in getPrimitiveType");
} else if (ModelUtils.isStringSchema(schema) && "number".equals(schema.getFormat())) {
// special handle of type: string, format: number
return "BigDecimal";
} else if (ModelUtils.isByteArraySchema(schema)) {
Expand Down Expand Up @@ -1294,16 +1296,13 @@ private static String getPrimitiveType(Schema schema) {
return "UUID";
} else if (ModelUtils.isStringSchema(schema)) {
return "string";
} else {
if (schema != null) {
// TODO the following check should be covered by ModelUtils.isMapSchema(schema) above so can be removed
if (SchemaTypeUtil.OBJECT_TYPE.equals(schema.getType()) && schema.getAdditionalProperties() != null) {
return "map";
} else {
return schema.getType();
}
}
} else if (schema.getProperties() != null && !schema.getProperties().isEmpty()) { // having property implies it's a model
return "object";
} else if (StringUtils.isNotEmpty(schema.getType())) {
LOGGER.warn("Unknown type found in the schema: " + schema.getType());
return schema.getType();
}

return "object";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -954,8 +954,8 @@ private void processPathExpr(CodegenOperation op) {
String xPath = "[\"" + escapeText(op.path) + "\"]";
if (op.getHasPathParams()) {
for (CodegenParameter param : op.allParams) {
if(param.isPathParam) {
xPath = xPath.replaceAll("\\{" + param.baseName + "\\}", "\",toPath " + param.paramName + ",\"");
if (param.isPathParam) {
xPath = xPath.replaceAll("\\{" + param.baseName + "\\}", "\",toPath " + param.paramName + ",\"");
}
}
xPath = xPath.replaceAll(",\"\",", ",");
Expand Down Expand Up @@ -1195,8 +1195,8 @@ public Map<String, Object> postProcessModels(Map<String, Object> objs) {
cm.isEnum = genEnums && cm.isEnum;
if (cm.isAlias) {
String dataType = cm.dataType;
if(dataType == null && cm.isArrayModel) { // isAlias + arrayModelType missing "datatype"
dataType = "[" + cm.arrayModelType +"]" ;
if (dataType == null && cm.isArrayModel) { // isAlias + arrayModelType missing "datatype"
dataType = "[" + cm.arrayModelType + "]";
}
cm.vendorExtensions.put(X_DATA_TYPE, dataType);
}
Expand Down
36 changes: 18 additions & 18 deletions samples/client/petstore/haskell-http-client/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
## Swagger Auto-Generated [http-client](https://www.stackage.org/lts-10.0/package/http-client-0.5.7.1) Bindings to `Swagger Petstore`
## OpenAPI Auto-Generated [http-client](https://www.stackage.org/lts-10.0/package/http-client-0.5.7.1) Bindings to `Swagger Petstore`

The library in `lib` provides auto-generated-from-Swagger [http-client](https://www.stackage.org/lts-10.0/package/http-client-0.5.7.1) bindings to the Swagger Petstore API.
The library in `lib` provides auto-generated-from-OpenAPI [http-client](https://www.stackage.org/lts-10.0/package/http-client-0.5.7.1) bindings to the Swagger Petstore API.

OpenApi Version: 3.0.1
OpenApi Version: 3.0.0

## Installation

Expand All @@ -29,20 +29,20 @@ from the stack.yaml file and run `stack haddock` again.
stack test
```

## Swagger-Codegen
## OpenAPI-Generator

The code generator that produced this library, and which explains how
to obtain and use the swagger-codegen cli tool lives at
to obtain and use the openapi-generator cli tool lives at

https://github.com/swagger-api/swagger-codegen
https://openapi-generator.tech

The _language_ argument (`--lang`) passed to the cli tool used should be

```
haskell-http-client
```

### Unsupported Swagger Features
### Unsupported OpenAPI Features

* Model Inheritance

Expand All @@ -65,7 +65,7 @@ These options allow some customization of the code generation process.
| configType | Set the name of the type used for configuration | | SwaggerPetstoreConfig |
| dateFormat | format string used to parse/render a date | %Y-%m-%d | %Y-%m-%d |
| dateTimeFormat | format string used to parse/render a datetime. (Defaults to [formatISO8601Millis][1] when not provided) | | |
| generateEnums | Generate specific datatypes for swagger enums | true | true |
| generateEnums | Generate specific datatypes for OpenAPI enums | true | true |
| generateFormUrlEncodedInstances | Generate FromForm/ToForm instances for models used by x-www-form-urlencoded operations (model fields must be primitive types) | true | true |
| generateLenses | Generate Lens optics for Models | true | true |
| generateModelConstructors | Generate smart constructors (only supply required fields) for models | true | true |
Expand All @@ -80,28 +80,28 @@ These options allow some customization of the code generation process.
An example setting _strictFields_ and _dateTimeFormat_:

```
java -jar swagger-codegen-cli.jar generate -i petstore.yaml -l haskell-http-client -o output/haskell-http-client -DstrictFields=true -DdateTimeFormat="%Y-%m-%dT%H:%M:%S%Q%z"
java -jar openapi-generator-cli.jar generate -i petstore.yaml -l haskell-http-client -o output/haskell-http-client -DstrictFields=true -DdateTimeFormat="%Y-%m-%dT%H:%M:%S%Q%z"
```

View the full list of Codegen "config option" parameters with the command:

```
java -jar swagger-codegen-cli.jar config-help -l haskell-http-client
java -jar openapi-generator-cli.jar config-help -l haskell-http-client
```

## Usage Notes

### Example SwaggerPetstore Haddock documentation
### Example Petstore Haddock documentation

An example of the generated haddock documentation targeting the server http://petstore.swagger.io/ (SwaggerPetstore) can be found [here][2]
An example of the generated haddock documentation targeting the server http://petstore.swagger.io/ (Petstore) can be found [here][2]

[2]: https://hackage.haskell.org/package/swagger-petstore

### Example SwaggerPetstore App
### Example Petstore App

An example application using the auto-generated haskell-http-client bindings for the server http://petstore.swagger.io/ can be found [here][3]

[3]: https://github.com/swagger-api/swagger-codegen/tree/master/samples/client/petstore/haskell-http-client/example-app
[3]: https://github.com/openapitools/openapi-generator/master/samples/client/petstore/haskell-http-client/example-app

This library is intended to be imported qualified.

Expand All @@ -120,7 +120,7 @@ This library is intended to be imported qualified.

### MimeTypes

This library adds type safety around what swagger specifies as
This library adds type safety around what OpenAPI specifies as
Produces and Consumes for each Operation (e.g. the list of MIME types an
Operation can Produce (using 'accept' headers) and Consume (using 'content-type' headers).

Expand Down Expand Up @@ -153,10 +153,10 @@ this would indicate that:
* the _addFoo_ operation can set it's body param of _FooModel_ via `setBodyParam`
* the _addFoo_ operation can set 2 different optional parameters via `applyOptionalParam`

If the swagger spec doesn't declare it can accept or produce a certain
If the OpenAPI spec doesn't declare it can accept or produce a certain
MIME type for a given Operation, you should either add a Produces or
Consumes instance for the desired MIME types (assuming the server
supports it), use `dispatchLbsUnsafe` or modify the swagger spec and
supports it), use `dispatchLbsUnsafe` or modify the OpenAPI spec and
run the generator again.

New MIME type instances can be added via MimeType/MimeRender/MimeUnrender
Expand All @@ -168,7 +168,7 @@ Operations using x-www-form-urlencoded which use those models.

### Authentication

A haskell data type will be generated for each swagger authentication type.
A haskell data type will be generated for each OpenAPI authentication type.

If for example the AuthMethod `AuthOAuthFoo` is generated for OAuth operations, then
`addAuthMethod` should be used to add the AuthMethod config.
Expand Down
2 changes: 1 addition & 1 deletion samples/client/petstore/haskell-http-client/git_push.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
#
# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update"
# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update"

git_user_id=$1
git_repo_id=$2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
OpenAPI Version: 3.0.1
OpenAPI Version: 3.0.0
Swagger Petstore API version: 1.0.0
Contact: [email protected]
Generated by Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
Generated by OpenAPI Generator (https://openapi-generator.tech)
-}

{-|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
OpenAPI Version: 3.0.1
OpenAPI Version: 3.0.0
Swagger Petstore API version: 1.0.0
Contact: [email protected]
Generated by Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
Generated by OpenAPI Generator (https://openapi-generator.tech)
-}

{-|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
OpenAPI Version: 3.0.1
OpenAPI Version: 3.0.0
Swagger Petstore API version: 1.0.0
Contact: [email protected]
Generated by Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
Generated by OpenAPI Generator (https://openapi-generator.tech)
-}

{-|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
OpenAPI Version: 3.0.1
OpenAPI Version: 3.0.0
Swagger Petstore API version: 1.0.0
Contact: [email protected]
Generated by Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
Generated by OpenAPI Generator (https://openapi-generator.tech)
-}

{-|
Expand Down Expand Up @@ -65,17 +65,19 @@ import qualified Prelude as P
-- Test serialization of outer boolean types
--
fakeOuterBooleanSerialize
:: (Consumes FakeOuterBooleanSerialize contentType)
=> ContentType contentType -- ^ request content-type ('MimeType')
-> Accept accept -- ^ request accept ('MimeType')
-> SwaggerPetstoreRequest FakeOuterBooleanSerialize contentType OuterBoolean accept
fakeOuterBooleanSerialize _ _ =
:: (Consumes FakeOuterBooleanSerialize MimeJSON)
=> Accept accept -- ^ request accept ('MimeType')
-> SwaggerPetstoreRequest FakeOuterBooleanSerialize MimeJSON Bool accept
fakeOuterBooleanSerialize _ =
_mkRequest "POST" ["/fake/outer/boolean"]

data FakeOuterBooleanSerialize

-- | /Body Param/ "boolean_post_body" - Input boolean as post body
instance HasBodyParam FakeOuterBooleanSerialize BooleanPostBody
-- | /Body Param/ "body" - Input boolean as post body
instance HasBodyParam FakeOuterBooleanSerialize BodyBool

-- | @application/json@
instance Consumes FakeOuterBooleanSerialize MimeJSON

-- | @*/*@
instance MimeType mtype => Produces FakeOuterBooleanSerialize mtype
Expand All @@ -88,18 +90,20 @@ instance MimeType mtype => Produces FakeOuterBooleanSerialize mtype
-- Test serialization of object with outer number type
--
fakeOuterCompositeSerialize
:: (Consumes FakeOuterCompositeSerialize contentType)
=> ContentType contentType -- ^ request content-type ('MimeType')
-> Accept accept -- ^ request accept ('MimeType')
-> SwaggerPetstoreRequest FakeOuterCompositeSerialize contentType OuterComposite accept
fakeOuterCompositeSerialize _ _ =
:: (Consumes FakeOuterCompositeSerialize MimeJSON)
=> Accept accept -- ^ request accept ('MimeType')
-> SwaggerPetstoreRequest FakeOuterCompositeSerialize MimeJSON OuterComposite accept
fakeOuterCompositeSerialize _ =
_mkRequest "POST" ["/fake/outer/composite"]

data FakeOuterCompositeSerialize

-- | /Body Param/ "OuterComposite" - Input composite as post body
instance HasBodyParam FakeOuterCompositeSerialize OuterComposite

-- | @application/json@
instance Consumes FakeOuterCompositeSerialize MimeJSON

-- | @*/*@
instance MimeType mtype => Produces FakeOuterCompositeSerialize mtype

Expand All @@ -111,18 +115,20 @@ instance MimeType mtype => Produces FakeOuterCompositeSerialize mtype
-- Test serialization of outer number types
--
fakeOuterNumberSerialize
:: (Consumes FakeOuterNumberSerialize contentType)
=> ContentType contentType -- ^ request content-type ('MimeType')
-> Accept accept -- ^ request accept ('MimeType')
-> SwaggerPetstoreRequest FakeOuterNumberSerialize contentType OuterNumber accept
fakeOuterNumberSerialize _ _ =
:: (Consumes FakeOuterNumberSerialize MimeJSON)
=> Accept accept -- ^ request accept ('MimeType')
-> SwaggerPetstoreRequest FakeOuterNumberSerialize MimeJSON Double accept
fakeOuterNumberSerialize _ =
_mkRequest "POST" ["/fake/outer/number"]

data FakeOuterNumberSerialize

-- | /Body Param/ "body" - Input number as post body
instance HasBodyParam FakeOuterNumberSerialize Body

-- | @application/json@
instance Consumes FakeOuterNumberSerialize MimeJSON

-- | @*/*@
instance MimeType mtype => Produces FakeOuterNumberSerialize mtype

Expand All @@ -134,43 +140,22 @@ instance MimeType mtype => Produces FakeOuterNumberSerialize mtype
-- Test serialization of outer string types
--
fakeOuterStringSerialize
:: (Consumes FakeOuterStringSerialize contentType)
=> ContentType contentType -- ^ request content-type ('MimeType')
-> Accept accept -- ^ request accept ('MimeType')
-> SwaggerPetstoreRequest FakeOuterStringSerialize contentType OuterString accept
fakeOuterStringSerialize _ _ =
:: (Consumes FakeOuterStringSerialize MimeJSON)
=> Accept accept -- ^ request accept ('MimeType')
-> SwaggerPetstoreRequest FakeOuterStringSerialize MimeJSON Text accept
fakeOuterStringSerialize _ =
_mkRequest "POST" ["/fake/outer/string"]

data FakeOuterStringSerialize

-- | /Body Param/ "body" - Input string as post body
instance HasBodyParam FakeOuterStringSerialize BodyText

-- | @*/*@
instance MimeType mtype => Produces FakeOuterStringSerialize mtype


-- *** testBodyWithQueryParams

-- | @PUT \/fake\/body-with-query-params@
--
testBodyWithQueryParams
:: (Consumes TestBodyWithQueryParams MimeJSON, MimeRender MimeJSON User)
=> User -- ^ "user"
-> Query -- ^ "query"
-> SwaggerPetstoreRequest TestBodyWithQueryParams MimeJSON NoContent MimeNoContent
testBodyWithQueryParams user (Query query) =
_mkRequest "PUT" ["/fake/body-with-query-params"]
`setBodyParam` user
`setQuery` toQuery ("query", Just query)

data TestBodyWithQueryParams
instance HasBodyParam TestBodyWithQueryParams User

-- | @application/json@
instance Consumes TestBodyWithQueryParams MimeJSON
instance Consumes FakeOuterStringSerialize MimeJSON

instance Produces TestBodyWithQueryParams MimeNoContent
-- | @*/*@
instance MimeType mtype => Produces FakeOuterStringSerialize mtype


-- *** testClientModel
Expand Down Expand Up @@ -323,7 +308,7 @@ instance HasOptionalParam TestEnumParameters EnumHeaderString where
-- | /Optional Param/ "enum_query_string_array" - Query parameter enum test (string array)
instance HasOptionalParam TestEnumParameters EnumQueryStringArray where
applyOptionalParam req (EnumQueryStringArray xs) =
req `setQuery` toQueryColl CommaSeparated ("enum_query_string_array", Just xs)
req `setQuery` toQueryColl MultiParamArray ("enum_query_string_array", Just xs)

-- | /Optional Param/ "enum_query_string" - Query parameter enum test (string)
instance HasOptionalParam TestEnumParameters EnumQueryString where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\
OpenAPI Version: 3.0.1
OpenAPI Version: 3.0.0
Swagger Petstore API version: 1.0.0
Contact: [email protected]
Generated by Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
Generated by OpenAPI Generator (https://openapi-generator.tech)
-}

{-|
Expand Down
Loading

0 comments on commit e45b378

Please sign in to comment.