swagger-api / swagger-api/swagger-codegen
Swagger 2 Feign client code oAuth flow throwing error url values must be not be absolute
Nobody has claimed this yet.
- Dominant language
- Mustache
- Stars
- 17.8k
- Forks
- 6k
- PR merge metrics
- No merged PRs in 30d
Description
Description
I exposed Rest APIs, and I generated client code using Swagger 2 Java language with Feign library. The code gen generated the below OAuth RequestInterceptor. I am getting the below error when I use the oAuth as auth
Swagger-codegen version
swagger-codegen-maven-plugin v2.4.28
Dependencies used
swagger-codegen-maven-plugin v2.4.28
feign-version 11.6
feign-form-version 3.8.0
oltu-version 1.0.1
Java 8
Swagger declaration file
{
"swagger": "2.0",
"info": {
"description": "app API Custom documentation",
"version": "1.0.1",
"title": "app API Custom"
},
"host": "localhost:8080",
"basePath": "/app",
"tags": [
{
"name": "user-resource",
"description": "User Resource"
}
],
"paths": {
"/api/users": {
"get": {
"tags": [
"user"
],
"summary": "get all user information",
"operationId": "getAllUsers",
"produces": [
"*/*"
],
"parameters": [
{
"name": "page",
"in": "query",
"description": "Page number of the requested page",
"required": false,
"type": "integer",
"format": "int32"
},
{
"name": "size",
"in": "query",
"description": "Size of a page",
"required": false,
"type": "integer",
"format": "int32"
},
{
"name": "sort",
"in": "query",
"description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.",
"required": false,
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "multi"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/UserDTO"
}
}
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"security": [
{
"password-oauth2": [
"openid"
]
}
],
"deprecated": false
},
"post": {
"tags": [
"user"
],
"summary": "create user information",
"operationId": "createUser",
"consumes": [
"application/json"
],
"produces": [
"*/*"
],
"parameters": [
{
"in": "body",
"name": "userDTO",
"description": "userDTO",
"required": true,
"schema": {
"$ref": "#/definitions/UserDTO"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/UserDTO"
}
},
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"security": [
{
"client-credentils-oauth2": [
"user.create"
]
}
],
"deprecated": false
},
"put": {
"tags": [
"user"
],
"summary": "update user information",
"operationId": "updateUser",
"consumes": [
"application/json"
],
"produces": [
"*/*"
],
"parameters": [
{
"in": "body",
"name": "userDTO",
"description": "userDTO",
"required": true,
"schema": {
"$ref": "#/definitions/UserDTO"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/UserDTO"
}
},
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"404": {
"description": "Not Found"
}
},
"security": [
{
"password-oauth2": [
"openid"
],
"client-credentils-oauth2": [
"user.create"
]
}
],
"deprecated": false
}
}
},
"securityDefinitions": {
"client-credentils-oauth2": {
"type": "oauth2",
"tokenUrl": "http://localhost:8080/app/oauth/token",
"flow": "application",
"scopes": {
"user.create": "for admin operations"
}
},
"password-oauth2": {
"type": "oauth2",
"tokenUrl": "http://localhost:8080/app/oauth/token",
"flow": "password",
"scopes": {
"openid": "for user operations"
}
}
},
"definitions": {
"UserDTO": {
"type": "object",
"properties": {
"activated": {
"type": "boolean"
},
"authorities": {
"type": "array",
"items": {
"type": "string"
}
},
"createdBy": {
"type": "string"
},
"createdDate": {
"type": "string",
"format": "date-time"
},
"email": {
"type": "string",
"minLength": 5,
"maxLength": 100
},
"firstName": {
"type": "string",
"minLength": 0,
"maxLength": 50
},
"id": {
"type": "integer",
"format": "int64"
},
"imageUrl": {
"type": "string",
"minLength": 0,
"maxLength": 256
},
"langKey": {
"type": "string",
"minLength": 2,
"maxLength": 6
},
"lastModifiedBy": {
"type": "string"
},
"lastModifiedDate": {
"type": "string",
"format": "date-time"
},
"lastName": {
"type": "string",
"minLength": 0,
"maxLength": 50
},
"login": {
"type": "string",
"minLength": 1,
"maxLength": 50,
"pattern": "^[_'.@A-Za-z0-9-]*$"
},
"password": {
"type": "string"
}
},
"title": "UserDTO"
}
}
}
Steps to reproduce
- Generate swagger client code using swagger-codegen-maven-plugin v2.4.28
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>2.4.28</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<!-- specify the swagger yaml -->
<inputSpec>http://localhost:8080/app/v2/api-docs</inputSpec>
<language>java</language>
<!-- hint: if you want to generate java server code, e.g. based on
Spring Boot, you can use the following target: <language>spring</language> -->
<!-- pass any necessary config options -->
<configOptions>
<dateLibrary>legacy</dateLibrary>
</configOptions>
<!-- override the default library to jersey2 -->
<library>feign</library>
<apiPackage>com.sam.feign.clients</apiPackage>
<modelPackage>com.sam.feign.dto</modelPackage>
</configuration>
</execution>
</executions>
</plugin>
- Run the unit test using below code
UserApi api = new ApiClient("client-credentils-oauth2","admin", "admin", null, null).buildClient(UserApi.class);
api.getUser(login, tenant)
Error trace
feign.RetryableException: url values must be not be absolute.
at com.sam.feign.auth.OAuth.updateAccessToken(OAuth.java:95)
at com.sam.feign.auth.OAuth.apply(OAuth.java:83)
at feign.SynchronousMethodHandler.targetRequest(SynchronousMethodHandler.java:161)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:110)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89)
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)
at com.sun.proxy.$Proxy9.getUser(Unknown Source)
at com.sam.feign.clients.UserApiTest.getUserTest(UserApiTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: java.lang.IllegalArgumentException: url values must be not be absolute.
at feign.RequestTemplate.uri(RequestTemplate.java:434)
at feign.RequestTemplate.uri(RequestTemplate.java:421)
at feign.RequestTemplate.append(RequestTemplate.java:388)
at com.sam.feign.auth.OAuth$OAuthFeignClient.execute(OAuth.java:163)
at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:65)
at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:55)
at org.apache.oltu.oauth2.client.OAuthClient.accessToken(OAuthClient.java:71)
at com.sam.feign.auth.OAuth.updateAccessToken(OAuth.java:93)
... 34 more
Suggest a fix/enhancement
I made the few changes in the oAuth template file to make it work.
public <T extends OAuthClientResponse> T execute(OAuthClientRequest request, Map<String, String> headers,
String requestMethod, Class<T> responseClass)
throws OAuthSystemException, OAuthProblemException {
// Added the below 3 lines
URI targetUri = URI.create(uri);
String target = targetUri.getScheme() + "://" + targetUri.getAuthority() ;
String path = targetUri.getPath();
RequestTemplate req = new RequestTemplate()
.uri(path)
.method(requestMethod)
.body(request.getBody())
.target(target); // Added this line
for (Entry<String, String> entry : headers.entrySet()) {
req.header(entry.getKey(), entry.getValue());
}
req = req.resolve(new HashMap<String, Object>()); // Added this line
Response feignResponse;
String body = "";
try {
feignResponse = client.execute(req.request(), new Options());
body = Util.toString(feignResponse.body().asReader());
} catch (IOException e) {
throw new OAuthSystemException(e);
}
String contentType = null;
Collection<String> contentTypeHeader = feignResponse.headers().get("Content-Type");
if(contentTypeHeader != null) {
contentType = StringUtil.join(contentTypeHeader.toArray(new String[0]), ";");
}
return OAuthClientResponseFactory.createCustomResponse(
body,
contentType,
feignResponse.status(),
responseClass
);
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the generated com.sam.feign.auth.OAuth.updateAccessToken method at OAuth.java:95 and the Feign 11.6 URL error. Reproduce the client generation using the swagger-codegen Maven plugin v2.4.28, the provided Swagger definition, and the Feign library configuration. Done means the generated client obtains an OAuth token and calls UserApi without the absolute-URL exception.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100