github.com/phrase/openapi@v0.0.0-20240514140800-49e8a106740e/openapi-generator/templates/java/libraries/feign/ApiClient.mustache (about)

     1  package {{invokerPackage}};
     2  
     3  import java.util.LinkedHashMap;
     4  import java.util.Map;
     5  
     6  {{#hasOAuthMethods}}
     7  import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
     8  import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
     9  {{/hasOAuthMethods}}
    10  
    11  {{#threetenbp}}
    12  import org.threeten.bp.*;
    13  {{/threetenbp}}
    14  
    15  import com.fasterxml.jackson.databind.DeserializationFeature;
    16  import com.fasterxml.jackson.databind.ObjectMapper;
    17  import com.fasterxml.jackson.databind.SerializationFeature;
    18  import org.openapitools.jackson.nullable.JsonNullableModule;
    19  {{#joda}}
    20  import com.fasterxml.jackson.datatype.joda.JodaModule;
    21  {{/joda}}
    22  {{#java8}}
    23  import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
    24  {{/java8}}
    25  {{#threetenbp}}
    26  import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule;
    27  {{/threetenbp}}
    28  
    29  import feign.Feign;
    30  import feign.RequestInterceptor;
    31  import feign.form.FormEncoder;
    32  import feign.jackson.JacksonDecoder;
    33  import feign.jackson.JacksonEncoder;
    34  import feign.slf4j.Slf4jLogger;
    35  import {{invokerPackage}}.auth.*;
    36  {{#hasOAuthMethods}}
    37  import {{invokerPackage}}.auth.OAuth.AccessTokenListener;
    38  {{/hasOAuthMethods}}
    39  
    40  {{>generatedAnnotation}}
    41  public class ApiClient {
    42    public interface Api {}
    43  
    44    protected ObjectMapper objectMapper;
    45    private String basePath = "{{{basePath}}}";
    46    private Map<String, RequestInterceptor> apiAuthorizations;
    47    private Feign.Builder feignBuilder;
    48  
    49    public ApiClient() {
    50      objectMapper = createObjectMapper();
    51      apiAuthorizations = new LinkedHashMap<String, RequestInterceptor>();
    52      feignBuilder = Feign.builder()
    53                  .encoder(new FormEncoder(new JacksonEncoder(objectMapper)))
    54                  .decoder(new JacksonDecoder(objectMapper))
    55                  .logger(new Slf4jLogger());
    56    }
    57  
    58    public ApiClient(String[] authNames) {
    59      this();
    60      for(String authName : authNames) {
    61        {{#hasAuthMethods}}
    62        RequestInterceptor auth;
    63        {{#authMethods}}if ("{{name}}".equals(authName)) {
    64        {{#isBasic}}
    65        {{#isBasicBasic}}
    66          auth = new HttpBasicAuth();
    67        {{/isBasicBasic}}
    68        {{^isBasicBasic}}
    69          auth = new HttpBearerAuth("{{scheme}}");
    70        {{/isBasicBasic}}
    71        {{/isBasic}}
    72        {{#isApiKey}}
    73          auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{#isKeyInQuery}}"query"{{/isKeyInQuery}}{{#isKeyInCookie}}"cookie"{{/isKeyInCookie}}, "{{keyParamName}}");
    74        {{/isApiKey}}
    75        {{#isOAuth}}
    76          auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{^-last}}, {{/-last}}{{/scopes}}");
    77        {{/isOAuth}}
    78        } else {{/authMethods}}{
    79          throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
    80        }
    81        addAuthorization(authName, auth);
    82        {{/hasAuthMethods}}
    83        {{^hasAuthMethods}}
    84        throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
    85        {{/hasAuthMethods}}
    86      }
    87    }
    88  
    89    /**
    90     * Basic constructor for single auth name
    91     * @param authName
    92     */
    93    public ApiClient(String authName) {
    94      this(new String[]{authName});
    95    }
    96  
    97    /**
    98     * Helper constructor for single api key
    99     * @param authName
   100     * @param apiKey
   101     */
   102    public ApiClient(String authName, String apiKey) {
   103      this(authName);
   104      this.setApiKey(apiKey);
   105    }
   106  
   107    /**
   108     * Helper constructor for single basic auth or password oauth2
   109     * @param authName
   110     * @param username
   111     * @param password
   112     */
   113    public ApiClient(String authName, String username, String password) {
   114      this(authName);
   115      this.setCredentials(username,  password);
   116    }
   117  
   118    {{#hasOAuthMethods}}
   119    /**
   120     * Helper constructor for single password oauth2
   121     * @param authName
   122     * @param clientId
   123     * @param secret
   124     * @param username
   125     * @param password
   126     */
   127    public ApiClient(String authName, String clientId, String secret, String username, String password) {
   128      this(authName);
   129      this.getTokenEndPoint()
   130             .setClientId(clientId)
   131             .setClientSecret(secret)
   132             .setUsername(username)
   133             .setPassword(password);
   134    }
   135  
   136    {{/hasOAuthMethods}}
   137    public String getBasePath() {
   138      return basePath;
   139    }
   140  
   141    public ApiClient setBasePath(String basePath) {
   142      this.basePath = basePath;
   143      return this;
   144    }
   145  
   146    public Map<String, RequestInterceptor> getApiAuthorizations() {
   147      return apiAuthorizations;
   148    }
   149  
   150    public void setApiAuthorizations(Map<String, RequestInterceptor> apiAuthorizations) {
   151      this.apiAuthorizations = apiAuthorizations;
   152    }
   153  
   154    public Feign.Builder getFeignBuilder() {
   155      return feignBuilder;
   156    }
   157  
   158    public ApiClient setFeignBuilder(Feign.Builder feignBuilder) {
   159      this.feignBuilder = feignBuilder;
   160      return this;
   161    }
   162  
   163    private ObjectMapper createObjectMapper() {
   164      ObjectMapper objectMapper = new ObjectMapper();
   165      objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
   166      objectMapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
   167      objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
   168      objectMapper.disable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE);
   169      objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
   170      objectMapper.setDateFormat(new RFC3339DateFormat());
   171      {{#joda}}
   172      objectMapper.registerModule(new JodaModule());
   173      {{/joda}}
   174      {{#java8}}
   175      objectMapper.registerModule(new JavaTimeModule());
   176      {{/java8}}
   177      {{#threetenbp}}
   178      ThreeTenModule module = new ThreeTenModule();
   179      module.addDeserializer(Instant.class, CustomInstantDeserializer.INSTANT);
   180      module.addDeserializer(OffsetDateTime.class, CustomInstantDeserializer.OFFSET_DATE_TIME);
   181      module.addDeserializer(ZonedDateTime.class, CustomInstantDeserializer.ZONED_DATE_TIME);
   182      objectMapper.registerModule(module);
   183      {{/threetenbp}}
   184      JsonNullableModule jnm = new JsonNullableModule();
   185      objectMapper.registerModule(jnm);
   186      return objectMapper;
   187    }
   188  
   189    public ObjectMapper getObjectMapper(){
   190      return objectMapper;
   191    }
   192  
   193    /**
   194     * Creates a feign client for given API interface.
   195     *
   196     * Usage:
   197     *    ApiClient apiClient = new ApiClient();
   198     *    apiClient.setBasePath("http://localhost:8080");
   199     *    XYZApi api = apiClient.buildClient(XYZApi.class);
   200     *    XYZResponse response = api.someMethod(...);
   201     * @param <T> Type
   202     * @param clientClass Client class
   203     * @return The Client
   204     */
   205    public <T extends Api> T buildClient(Class<T> clientClass) {
   206      return feignBuilder.target(clientClass, basePath);
   207    }
   208  
   209    /**
   210     * Select the Accept header's value from the given accepts array:
   211     *   if JSON exists in the given array, use it;
   212     *   otherwise use all of them (joining into a string)
   213     *
   214     * @param accepts The accepts array to select from
   215     * @return The Accept header to use. If the given array is empty,
   216     *   null will be returned (not to set the Accept header explicitly).
   217     */
   218    public String selectHeaderAccept(String[] accepts) {
   219      if (accepts.length == 0) return null;
   220      if (StringUtil.containsIgnoreCase(accepts, "application/json")) return "application/json";
   221      return StringUtil.join(accepts, ",");
   222    }
   223  
   224    /**
   225     * Select the Content-Type header's value from the given array:
   226     *   if JSON exists in the given array, use it;
   227     *   otherwise use the first one of the array.
   228     *
   229     * @param contentTypes The Content-Type array to select from
   230     * @return The Content-Type header to use. If the given array is empty,
   231     *   JSON will be used.
   232     */
   233    public String selectHeaderContentType(String[] contentTypes) {
   234      if (contentTypes.length == 0) return "application/json";
   235      if (StringUtil.containsIgnoreCase(contentTypes, "application/json")) return "application/json";
   236      return contentTypes[0];
   237    }
   238  
   239  
   240    /**
   241     * Helper method to configure the bearer token.
   242     * @param bearerToken the bearer token.
   243     */
   244    public void setBearerToken(String bearerToken) {
   245      for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
   246        if (apiAuthorization instanceof HttpBearerAuth) {
   247          ((HttpBearerAuth) apiAuthorization).setBearerToken(bearerToken);
   248          return;
   249        }
   250      }
   251      throw new RuntimeException("No Bearer authentication configured!");
   252    }
   253  
   254    /**
   255     * Helper method to configure the first api key found
   256     * @param apiKey API key
   257     */
   258    public void setApiKey(String apiKey) {
   259      for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
   260        if (apiAuthorization instanceof ApiKeyAuth) {
   261          ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization;
   262          keyAuth.setApiKey(apiKey);
   263          return ;
   264        }
   265      }
   266      throw new RuntimeException("No API key authentication configured!");
   267    }
   268  
   269    /**
   270     * Helper method to configure the username/password for basic auth or password OAuth
   271     * @param username Username
   272     * @param password Password
   273     */
   274    public void setCredentials(String username, String password) {
   275      for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
   276        if (apiAuthorization instanceof HttpBasicAuth) {
   277          HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization;
   278          basicAuth.setCredentials(username, password);
   279          return;
   280        }
   281        {{#hasOAuthMethods}}
   282        if (apiAuthorization instanceof OAuth) {
   283          OAuth oauth = (OAuth) apiAuthorization;
   284          oauth.getTokenRequestBuilder().setUsername(username).setPassword(password);
   285          return;
   286        }
   287        {{/hasOAuthMethods}}
   288      }
   289      throw new RuntimeException("No Basic authentication or OAuth configured!");
   290    }
   291  
   292    {{#hasOAuthMethods}}
   293    /**
   294     * Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
   295     * @return Token request builder
   296     */
   297    public TokenRequestBuilder getTokenEndPoint() {
   298      for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
   299        if (apiAuthorization instanceof OAuth) {
   300          OAuth oauth = (OAuth) apiAuthorization;
   301          return oauth.getTokenRequestBuilder();
   302        }
   303      }
   304      return null;
   305    }
   306  
   307    /**
   308     * Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
   309     * @return Authentication request builder
   310     */
   311    public AuthenticationRequestBuilder getAuthorizationEndPoint() {
   312      for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
   313        if (apiAuthorization instanceof OAuth) {
   314          OAuth oauth = (OAuth) apiAuthorization;
   315          return oauth.getAuthenticationRequestBuilder();
   316        }
   317      }
   318      return null;
   319    }
   320  
   321    /**
   322     * Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one)
   323     * @param accessToken Access Token
   324     * @param expiresIn Validity period in seconds
   325     */
   326    public void setAccessToken(String accessToken, Long expiresIn) {
   327      for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
   328        if (apiAuthorization instanceof OAuth) {
   329          OAuth oauth = (OAuth) apiAuthorization;
   330          oauth.setAccessToken(accessToken, expiresIn);
   331          return;
   332        }
   333      }
   334    }
   335  
   336    /**
   337     * Helper method to configure the oauth accessCode/implicit flow parameters
   338     * @param clientId Client ID
   339     * @param clientSecret Client secret
   340     * @param redirectURI Redirect URI
   341     */
   342    public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
   343      for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
   344        if (apiAuthorization instanceof OAuth) {
   345          OAuth oauth = (OAuth) apiAuthorization;
   346          oauth.getTokenRequestBuilder()
   347                  .setClientId(clientId)
   348                  .setClientSecret(clientSecret)
   349                  .setRedirectURI(redirectURI);
   350          oauth.getAuthenticationRequestBuilder()
   351                  .setClientId(clientId)
   352                  .setRedirectURI(redirectURI);
   353          return;
   354        }
   355      }
   356    }
   357  
   358    /**
   359     * Configures a listener which is notified when a new access token is received.
   360     * @param accessTokenListener Acesss token listener
   361     */
   362    public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
   363      for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
   364        if (apiAuthorization instanceof OAuth) {
   365          OAuth oauth = (OAuth) apiAuthorization;
   366          oauth.registerAccessTokenListener(accessTokenListener);
   367          return;
   368        }
   369      }
   370    }
   371  
   372    {{/hasOAuthMethods}}
   373    /**
   374     * Gets request interceptor based on authentication name
   375     * @param authName Authentiation name
   376     * @return Request Interceptor
   377     */
   378    public RequestInterceptor getAuthorization(String authName) {
   379      return apiAuthorizations.get(authName);
   380    }
   381  
   382    /**
   383     * Adds an authorization to be used by the client
   384     * @param authName Authentication name
   385     * @param authorization Request interceptor
   386     */
   387    public void addAuthorization(String authName, RequestInterceptor authorization) {
   388      if (apiAuthorizations.containsKey(authName)) {
   389        throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations");
   390      }
   391      apiAuthorizations.put(authName, authorization);
   392      feignBuilder.requestInterceptor(authorization);
   393    }
   394  
   395  }