title: Swagger Codegen CLI Java Client - How to use it right
body: <p>I'm currently playing around with my jersey2 rest service. For a better overview of the given service (description, types and so on) I make heavily use of swagger (swagger-jersey2-jaxrs). 
  So I'm able to genereate my service description (swagger.json) and I can view and explore them via swagger ui.</p>
  
  <p>Now I'm at the point that I need to create some clients to make use of these services. I came across swagger codegen cli which is a nice tool to generate your client and many different languages (java in my case). I'm able to generate the api client and the model in use.</p>
  
  <p>Here I face the first problem. The REST services and the swagger description are http basic auth protected. I read the <a href="https://github.com/swagger-api/swagger-codegen" rel="noreferrer">documentation</a>  which gave me some hint that there is a possibility to use basic auth. At this point I have to mention that from my point of view the documentation is very poor. It says:</p>
  
  <p>-a , --auth 
  adds authorization headers when fetching the swagger definitions remotely. Pass in a URL-encoded string of name:header with a comma separating multiple values.</p>
  
  <p>First thing I thought of is to pass a string like in an http header but that doesn't work and even googling how to use basic auth with swagger cli didn't result in some clear answer. After a lot of try and errors I (I'm using CLI 2.1.2) I finally came across the right format:</p>
  
  <p>java -jar swagger-codegen-cli-2.1.2.jar generate -a "Authorization: Basic YWRtaW46YWRtaW4=" -i <a href="http://localhost:8080/webproject/restapi/swagger.json" rel="noreferrer">http://localhost:8080/webproject/restapi/swagger.json</a> -l java -o restclient</p>
  
  <p>where YWRtaW46YWRtaW4= is the the base64 encoded value of admin:admin in my case.</p>
  
  <p>So far so good. The generated java client have to make use of basic auth as well. I took a look at the methods from the ApiClient and found setUsername and setPassword. I thought that this methods empowers the client to use basic auth but no luck. </p>
  
  <p>So I took a deeper look at the generated classes especially the ApiClient and the several generated ApiService Classes.
  I found out that the setUsername and setPassword have no effect because of the following:</p>
  
  <pre><code>/**
     * Helper method to set username for the first HTTP basic authentication.
     */
    public void setUsername(String username) {
      for (Authentication auth : authentications.values()) {
        if (auth instanceof HttpBasicAuth) {
          ((HttpBasicAuth) auth).setUsername(username);
          return;
        }
      }
      throw new RuntimeException("No HTTP basic authentication configured!");
    }
  </code></pre>
  
  <p>where at the same time the HashMap is defined as the following:</p>
  
  <pre><code>// Setup authentications (key: authentication name, value: authentication).
  authentications = new HashMap&lt;String, Authentication&gt;();
  // Prevent the authentications from being modified.
  authentications = Collections.unmodifiableMap(authentications);
  </code></pre>
  
  <p>The authentication hashmap becomes immutable, but why? What is the purpose? Furthermore there are no helper methods inside the ApiClinet which generates the needed auth object so I did the following:</p>
  
  <p>1) comment out the line authentications Collections.unmodifiableMap(authentications) so the hashmap becomes     modifiable again</p>
  
  <p>2) create needed auth object manually</p>
  
  <pre><code>HttpBasicAuth authentication = new HttpBasicAuth(); 
  authentication.setUsername("admin");
  authentication.setPassword("admin");
  </code></pre>
  
  <p>3) add the auth object to the apiClients authentication hashmap:</p>
  
  <pre><code>ApiClient apiClient = new ApiClient();
  apiClient.setBasePath(basePath);
  apiClient.getAuthentications().put("basic", authentication);
  </code></pre>
  
  <p>4) modifying invokeApi Method (ApiClient.java)</p>
  
  <pre><code>public String invokeAPI(String path, String method, Map&lt;String, String&gt; queryParams, Object body, Map&lt;String, String&gt; headerParams, Map&lt;String, String&gt; formParams, String accept, String contentType, String[] authNames) throws ApiException {
  String authNames2[] = {"basic"};
  updateParamsForAuth(authNames2, queryParams, headerParams);
  //updateParamsForAuth(authNames, queryParams, headerParams);
  ...
  </code></pre>
  
  <p>Step 4 is necessary because the ApiServices invoke the apiClient method like the following:</p>
  
  <pre><code>String[] authNames = new String[] {  };
  String response = apiClient.invokeAPI(path, "POST", queryParams, postBody, headerParams, formParams, accept, contentType, authNames);
  </code></pre>
  
  <p>An other possible solution would be to define the Key of the authentications hashmap in every apiService like:</p>
  
  <pre><code>String[] authNames = new String[] { "basic" };
  </code></pre>
  
  <p>After doing all the modifications everything works as expected but I cant think that this is the idea behind an autogenerated rest client. 
  So my question is: Am I missing some point or should I think of the swagger generated client (java in this case) more of a beta solution which is under development?
  Please get me right, I think the whole swagger framework (jersey2 support, openapi, swaggerui, codegen) is a great thing and I appreciate the developers effort but I want to use the codegen right and I don't think that the idea behind is so have to customize the generated ApiClient and ApiServices in such a way.</p>