I want to use typemappings from the openapi-generator-maven-plugin. My openapi spec file looks like the following:
paths:
/maintenance-windows-avr/{day}:
get:
summary: "Get active maintenance windows for day"
tags:
- Maintenance Windows AVR
operationId: getMaintenanceWindows
parameters:
- in: path
name: day
required: true
schema:
type: string
format: date
description: day to return active maintenance windows
responses:
"200":
description: "Success"
content:
application/json:
schema:
type: object
items:
$ref: "#/components/schemas/ResponseListMaintenanceWindowAVRDto"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorDto"
components:
schemas:
ErrorDto:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
MaintenanceWindowAVRDto:
type: object
required:
- id
- start
- end
- hosts
properties:
id:
type: string
format: uuid
description: id of maintenance window
start:
type: string
format: date-time
description: when the maintenance window is going to start
end:
type: string
format: date-time
description: when the maintenance is going to end
hosts:
type: array
items:
type: long
format: int64
description: list of host ids
ResponseListMaintenanceWindowAVRDto:
type: object
properties:
data:
type: array
items:
$ref: "#/components/schemas/MaintenanceWindowAVRDto"
Which generates me the files MaintenanceWindowsAvrApi and MaintenanceWindowAVRDto which look like the following:
package eu.nts.nmp.csm.mac.api.generated.endpoint.avl;
import eu.nts.nmp.csm.mac.api.generated.model.avl.ErrorDto;
import java.time.LocalDate;
import eu.nts.nmp.csm.mac.api.generated.model.avl.ResponseListMaintenanceWindowAVRDto;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.Map;
import java.util.List;
import javax.validation.constraints.*;
import javax.validation.Valid;
@Path("/maintenance-windows-avr/{day}")
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaJAXRSSpecServerCodegen", date = "2023-03-14T16:46:37.723499+01:00[Europe/Vienna]")public interface MaintenanceWindowsAvrApi {
@GET
@Produces({ "application/json" })
Response getMaintenanceWindows(@PathParam("day") LocalDate day);
}
package eu.nts.nmp.csm.mac.api.generated.model.avl;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.validation.constraints.*;
import javax.validation.Valid;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaJAXRSSpecServerCodegen", date = "2023-03-14T16:46:37.723499+01:00[Europe/Vienna]")public class MaintenanceWindowAVRDto {
private @Valid UUID id;
private @Valid OffsetDateTime start;
private @Valid OffsetDateTime end;
private @Valid List<Long> hosts = new ArrayList<>();
/**
* id of maintenance window
**/
public MaintenanceWindowAVRDto id(UUID id) {
this.id = id;
return this;
}
@JsonProperty("id")
@NotNull
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
/**
* when the maintenance window is going to start
**/
public MaintenanceWindowAVRDto start(OffsetDateTime start) {
this.start = start;
return this;
}
@JsonProperty("start")
@NotNull
public OffsetDateTime getStart() {
return start;
}
public void setStart(OffsetDateTime start) {
this.start = start;
}
/**
* when the maintenance is going to end
**/
public MaintenanceWindowAVRDto end(OffsetDateTime end) {
this.end = end;
return this;
}
@JsonProperty("end")
@NotNull
public OffsetDateTime getEnd() {
return end;
}
public void setEnd(OffsetDateTime end) {
this.end = end;
}
/**
**/
public MaintenanceWindowAVRDto hosts(List<Long> hosts) {
this.hosts = hosts;
return this;
}
@JsonProperty("hosts")
@NotNull
public List<Long> getHosts() {
return hosts;
}
public void setHosts(List<Long> hosts) {
this.hosts = hosts;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MaintenanceWindowAVRDto maintenanceWindowAVRDto = (MaintenanceWindowAVRDto) o;
return Objects.equals(this.id, maintenanceWindowAVRDto.id) &&
Objects.equals(this.start, maintenanceWindowAVRDto.start) &&
Objects.equals(this.end, maintenanceWindowAVRDto.end) &&
Objects.equals(this.hosts, maintenanceWindowAVRDto.hosts);
}
@Override
public int hashCode() {
return Objects.hash(id, start, end, hosts);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class MaintenanceWindowAVRDto {\n");
sb.append(" id: ").append(toIndentedString(id)).append("\n");
sb.append(" start: ").append(toIndentedString(start)).append("\n");
sb.append(" end: ").append(toIndentedString(end)).append("\n");
sb.append(" hosts: ").append(toIndentedString(hosts)).append("\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}
I want to map the LocalDate parameter in MaintenanceWindowsAvrApi file and the two OffsetDateTime fields start and end from the MaintenanceWindowAVRDto file to an Instant (java.time.Instant).
I have tried so many options but nothing gives me the result I want. My api pom file:
<inputSpec>${project.basedir}/src/main/resources/META-INF/openapi-avr.yaml</inputSpec>
<generatorName>jaxrs-spec</generatorName>
<configOptions>
<useSwaggerAnnotations>false</useSwaggerAnnotations>
<interfaceOnly>true</interfaceOnly>
<generatePom>false</generatePom>
<returnResponse>true</returnResponse>
<dateLibrary>java8</dateLibrary>
<java8>true</java8>
<useFlags>true</useFlags>
<sourceFolder>src/gen/java/main</sourceFolder>
</configOptions>
How can I use the typeMappings to resolve my problem?
Solution
Add typeMappings configuration like this:
This will replace every occurence of
LocalDateTimeandOffsetDateTimein the generated code byjava.time.Instant. The import sections will not change. I.e. they will still contain andimport java.time.LocalDate;andimport java.time.OffsetDateTime;, even though these imports are not used anymore.Documentation about typeMappings can be found here and here.
OpenAPI Generator Bug
The intended usage of OpenAPI Generator would be to set
and
(And likewise for OffsetDateTime.)
Then imports of
LocalDateandOffsetDateTimewould be replaced byimport java.time.Instant;andInstantwould be used in the code instead ofjava.time.Instant.However, there is a bug in OpenAPI Generator that prevents the usage of
importMappingin Java-based generators. Therefore we currently need to configure the type mappings as shown in my solution above.unknown config option
By the way, I think the
useFlagssetting in your code can be removed, because this is not a valid config option for OpenAPI Generator.