Openapi operationid is repeated - java

I'm using Open-API to generate java class using yaml file. when i run
mvn clean install
i'm getting this error :
unexpected error in Open-API generation
org.openapitools.codegen.SpecValidationException: There were issues with the specification. The option can be disabled via validateSpec (Maven/Gradle) or --skip-validate-spec (CLI).
| Error count: 3, Warning count: 6
Errors:
-attribute paths.'/path/{id}'(delete).operationId is repeated
-attribute paths.'/path/name'(get).operationId is repeated
How can i skeep this validation ?

Try this:
Within your POM.xml -> Plugin -> Find openAPI generation plug-in -> configuration -> configOptions ->
<validateSpec>false</validateSpec>
This should work hopefully ! :)

For me, the correct place of validateSpec was configuration instead of configOptions
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>6.2.1</version>
<executions>
<execution>
<id>abc-api</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
...
<validateSpec>false</validateSpec>
<skipValidateSpec>true</skipValidateSpec>
<configOptions>
<developerOrganization>ABC</developerOrganization>
...
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
Note: I have to add both validateSpec and skipValidateSpec for version 6.2.1 as per suggestion in an open bug https://github.com/OpenAPITools/openapi-generator/issues/9815

Try to add syntax "schema": {"type": "string"} to *.Json file.
I aslo got the error with respose like that:
There were issues with the specification. The option can be disabled via validateSpec (Maven/Gradle) or --skip-validate-spec (CLI).
| Error count: 12, Warning count: 20
Errors:
-attribute paths.'/.../items'(get).responses.304.ETag.type is unexpected
-attribute paths.'/.../items'(get).responses.304.Last-Modified.type is unexpected
-attribute paths.'/.../items'(get).responses.200.ETag.type is unexpected
This is my fix:
enter image description here
enter image description here
"headers": {
"ETag": {
"description": "Used as caching key for future requests.",
"schema": {
"type": "string",
"example": "33a64df551425fcc55e4d42a1466666666666666666"
}
},
"Cache-Control": {
"description": "The Cache-Control header.",
"schema": {
"type": "string",
"example": "max-age=1000000"
}
},
"Last-Modified": {
"description": "The last modified the response.",
"schema": {
"type": "string",
"example": "Sun, 11 Nov 2021 15:30:51 ICT"
}
}
}
I hope this one can help you. You cant read more document with response header here: https://swagger.io/docs/specification/describing-responses/

Related

Use OpenAPI to generate Java APIs that don't return ResponseEntity

I want to generate a Java API using OpenAPI 3.0, but I don't want any return type to be a ResponseEntity.
I have a small .yaml file that generates APIs that look like this (I've removed lots of annotations for brevity):
#GetMapping(value = "/student", produces = { "application/json" })
ResponseEntity<List<Student>> getAllStudents();
It's very straightforward, but my employer wants an API like this:
#GetMapping(value = "/student")
List<Student> getAllStudents();
The trouble is that I can't find a configuration option that would make the code generator dispense with the ResponseEntities.
Is there any way to configure the OpenAPI generator to not use ResponseEntities?
—
Details:
I build with Maven, and I configure my code generation in my pom file like this:
<build>
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>5.0.0-SNAPSHOT</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<!--See https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-maven-plugin-->
<inputSpec>${project.basedir}/OpenApi.yaml</inputSpec>
<generatorName>spring</generatorName>
<groupId>com.dummy.example</groupId>
<artifactId>dummy</artifactId>
<artifactVersion>2.0</artifactVersion>
<library>spring-boot</library>
<packageName>com.neptunedreams.configuration</packageName>
<apiPackage>com.neptunedreams.api</apiPackage>
<invokerPackage>com.neptunedreams</invokerPackage>
<modelPackage>com.neptunedreams.model</modelPackage>
<configOptions>
<!--See https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/spring.md -->
<sourceFolder>src/main/java</sourceFolder>
<bigDecimalAsString>true</bigDecimalAsString>
<dateLibrary>java8</dateLibrary>
<interfaceOnly>true</interfaceOnly>
<library>spring-boot</library>
<skipDefaultInterface>true</skipDefaultInterface>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
My yaml file is very basic, if you need to see it:
openapi: 3.0.0
info:
description: StackOverflow ResponseEntity Question
version: 1.0.0
title: ResponseEntity Question
paths:
/student:
get:
summary: Get all students
operationId: getAllStudents
responses:
200:
description: Get all students
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Student'
components:
schemas:
Student:
type: object
properties:
name:
type: string
id:
type: integer
format: int64
required:
- name
- id
Like here How to prevent Mono Request body generation when generating the API interfaces for spring-webflux with open api code generator?
You can override/customize the api.mustache from swagger-codegen template.
Here you can find the original template https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/JavaSpring/api.mustache
So you can put your own template inside src/main/java/resource.
openApiGenerate {
generatorName = "spring"
library = "spring-boot"
...
configOptions = [
...
templateDirectory: "src/main/resources/openapi-templates"
...
]
}
Here is the documentation about template https://github.com/OpenAPITools/openapi-generator/blob/master/docs/templating.md

Importing OpenTelemetry trace data from Spring Boot application to Elastic APM - views are missing data

I have a Spring Boot application with Spring Cloud Sleuth, OpenTelemetry instrumentation and OpenTelemetry exporter OTLP.
This is a gist of dependencies:
spring-cloud-starter-sleuth without Brave, because we are using OpenTelemetry instrumentation
spring-cloud-sleuth-otel-autoconfigure which introduces OpenTelemetry instrumentation libs and provides Spring autoconfiguration
opentelemetry-exporter-otlp for sending data to apm server
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/io.grpc/grpc-netty -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.43.0</version>
</dependency>
I have only basic configuration in my application.yml:
spring:
sleuth:
enabled: true
otel:
config:
trace-id-ratio-based: 1.0
exporter:
otlp:
endpoint: http://localhost:8200
With this setup I successfully see some data in APM. Example screens:
However if I look into Elastic documentation, I see that their screens have additional data present: Traces.
To me, it looks like span and transaction names are missing (I only see HTTP GET instead of a name), at least they are present in the documentation images.
Anyone has an idea why is this happening and how to fix this?
This is example trace document in Elastic:
const EXAMPLE = {
"_index": "apm-7.15.2-metric-000001",
"_type": "_doc",
"_id": "AYVKCH8BxjGANUnHPDgq",
"_version": 1,
"_score": 1,
"_source": {
"_doc_count": 2,
"agent": {
"name": "opentelemetry/java"
},
"processor": {
"name": "metric",
"event": "metric"
},
"transaction.duration.histogram": {
"counts": [
1,
1
],
"values": [
1439,
10495
]
},
"metricset.name": "transaction",
"observer": {
"hostname": "0798ff612508",
"id": "6a12bcef-5e7e-45b3-aee6-f2af4e175c3f",
"ephemeral_id": "389ee9b1-d4c4-4d67-b46a-bfcaa77b7b79",
"type": "apm-server",
"version": "7.15.2",
"version_major": 7
},
"#timestamp": "2022-02-17T15:25:56.160Z",
"timeseries": {
"instance": "summary-service:HTTP GET:11ed2dc65a946e45"
},
"ecs": {
"version": "1.11.0"
},
"service": {
"name": "summary-service"
},
"event": {
"ingested": "2022-02-17T15:25:57.161730700Z",
"outcome": "success"
},
"transaction": {
"result": "HTTP 2xx",
"root": true,
"name": "HTTP GET",
"type": "request"
}
},
"fields": {
"transaction.name.text": [
"HTTP GET"
],
"_doc_count": [
2
],
"service.name": [
"summary-service"
],
"processor.name": [
"metric"
],
"observer.version_major": [
7
],
"observer.hostname": [
"0798ff612508"
],
"transaction.result": [
"HTTP 2xx"
],
"transaction.duration.histogram": [
{
"counts": [
1,
1
],
"values": [
1439,
10495
]
}
],
"transaction.type": [
"request"
],
"metricset.name": [
"transaction"
],
"observer.id": [
"6a12bcef-5e7e-45b3-aee6-f2af4e175c3f"
],
"event.ingested": [
"2022-02-17T15:25:57.161Z"
],
"#timestamp": [
"2022-02-17T15:25:56.160Z"
],
"observer.ephemeral_id": [
"389ee9b1-d4c4-4d67-b46a-bfcaa77b7b79"
],
"timeseries.instance": [
"summary-service:HTTP GET:11ed2dc65a946e45"
],
"observer.version": [
"7.15.2"
],
"ecs.version": [
"1.11.0"
],
"observer.type": [
"apm-server"
],
"transaction.root": [
true
],
"processor.event": [
"metric"
],
"transaction.name": [
"HTTP GET"
],
"agent.name": [
"opentelemetry/java"
],
"event.outcome": [
"success"
]
}
}
To me, it looks like span and transaction names are missing (I only see HTTP GET instead of a name)
No, they are not missing. The reason you are seeing name as HTTP GET is due to preference for less cardinal names and the semantic conventions for tracing data. There is a detailed explanation about the naming conventions for the HTTP spans here https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#name. Any data generated by auto-instrumentation libraries will adhere to the semantic conventions specification. I am guessing the visualisation from the linked vendor is coming from manual instrumentation where you as an end user can give any name (although it is recommended everyone uses less cardinal values but there is not enforcement there). I don't think there is anything you can "fix" here.

OpenApi generator Failed to get the schema name

I have openapi contract:
openapi: 3.0.1
info:
version: 1.0.0
paths:
/getInteractions:
post:
requestBody:
content:
application/json:
schema:
$ref: scheme/interactionsRq.json
required: true
responses:
"200":
content:
application/json:
schema:
$ref: scheme/mainRs.json
in this structure:
-resources
--GetInteractionController.yaml
--scheme
----interactionsRq.json
----interactionsRs.json
----mainRs.json
In mainRs.json i have some ref to another json like this:
"resultApi": {
"title": "result",
"type": "object",
"properties": {
"interactionList": {
"type": "array",
"minItems": 0,
"maxItems": 100,
"items": {
"$ref": "interactionsRs.json#/definitions/interactionApi"
}
}
}
And when i try to package this with openapi-generator-maven-plugin:
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>5.3.1</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/GetInteractionController.yaml</inputSpec>
<generatorName>spring</generatorName>
<apiPackage>some.api.package</apiPackage>
<modelPackage>some.dto.package</modelPackage>
<supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate>
<configOptions>
<delegatePattern>true</delegatePattern>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
I get a warning and build error:
[WARNING] Failed to get the schema name: ./scheme/interactionsRs.json#/definitions/interactionApi
Can openapi generate code with refs like i have? Or i need to refactor json schemas and delete this refs? Maybe concatenate this in one file or something like this
Now i understand, that this is an issue with my JSON scheme, but not with openapi-generator.
In JSON scheme i've used an jsonschema2pojo feature "customDateTimePattern" : "yyyy-MM-dd'T'HH:mm:ssZ" and it gives me an error.
When i deleted it everything become fine

Handling UUID in Avro java

I want to store a uuid using avro.
below is the schema i am using
{
"namespace": "somethingImportant",
"type": "record",
"name": "GoodObject",
"fields": [
{
"name": "pk",
"type": {"type": "string", "logicalType": "uuid"}
}
]
}
i am using maven plugin 1.10.2 plugin with the below config
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.10.2</version>
<executions>
<execution>
<id>schemas</id>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
<goal>protocol</goal>
<goal>idl-protocol</goal>
</goals>
<configuration>
<stringType>String</stringType>
<customConversions>org.apache.avro.Conversions$UUIDConversion</customConversions>
<enableDecimalLogicalType>true</enableDecimalLogicalType>
<sourceDirectory>${project.basedir}/src/main/resources/</sourceDirectory>
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
the generated class the id field is generated as UUID, and i can do a get and set of uuid.
But uuid is stored as a string(36 bytes) which defeats the purpose. I came across another solution to define seomthing like
{
"namespace": "somethingImportant",
"type": "record",
"name": "GoodObject",
"fields": [
{
"name": "pk",
"type": {"type": "string", "logicalType": "uuid", "CustomEncoding":"UUIDAsBytesEncoding"}
}
]
}
but this does not do anything on its own. This stackoverflow answer talks about implementation, but i am not sure how we can make it work with maven plugin. This blog also talks about similar thing but i could not generate #AvroEncode(using = InstantAsStringAvroEncoding.class).
Has someone used uuid with avro so that
we can set a uuid
it gets stored as byte array
The Get method returns a uuid
I don't want to do the marshelling and unmarshelling by myself obviously because that is a custom code to maintain

Apache Avro Maven Plugin generate UUID field instead of String

Given the following Avro Schema:
{
"namespace": "ro.dspr.coreentities",
"type": "record",
"name": "Organization",
"fields": [
{
"name": "id",
"type": "string",
"logicalType": "uuid"
},
{
"name": "name",
"type": "string"
},
{
"name": "description",
"type": "string"
}
]
}
Running avro-maven-plugin 1.9.0 goal schema, I get:
#org.apache.avro.specific.AvroGenerated
public class Organization extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"Organization\",\"namespace\":\"ro.dspr.coreentities\",\"fields\":[{\"name\":\"id\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"},\"logicalType\":\"uuid\"},{\"name\":\"name\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"description\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}}]}");
// truncated
#Deprecated public java.lang.String id;
#Deprecated public java.lang.String name;
#Deprecated public java.lang.String description;
// truncated
}
I want the generated POJO for Organization to have id UUID, not String (what I have now).
Links I looked at:
I do see the logical type def from Avro and there is the Conversion class I am actually trying to trigger, but I cannot connect the dots.
Other
Relevant Maven pom parts
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>${avro.version}</version>
<configuration>
<sourceDirectory>${avro-files-path}</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
<stringType>String</stringType>
</configuration>
<executions>
<execution>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>${avro-files-path}</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Extra info
I actually trying to use Avro to give my Kafka messages a structure. I am also using Confluent Schema Registry and Confluent Avro Kafka Serializer. Nevertheless, I thought I would only have the id as String, but if I try to send messages to Kafka as something non-UUID, it will fail later. However, I found out that there is actually no constraint, and I managed to send any String to Kafka. So, the "logicalType" in Avro is not enforced at all.
The Question
How can I generate Organization.class#id as UUID?
If there is no Avro-support in doing this, what would be the workaround (preferably reusing the org.apache.avro.Conversions.UUIDConversion) ?
Here is a functional example:
Schema:
{
"name": "pk",
"type": {"type": "string", "logicalType": "uuid"}
},
Maven config:
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/../avro/schemas/commands</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources/java</outputDirectory>
<!-- TODO Enable this string type once we have 1.10.0 release, or 1.9.2-->
<!--<stringType>String</stringType>-->
<fieldVisibility>PRIVATE</fieldVisibility>
<customConversions>org.apache.avro.Conversions$UUIDConversion</customConversions>
<imports>
<import>${project.basedir}/../avro/schemas/common</import>
<import>${project.basedir}/../avro/schemas/commands/account</import>
<import>${project.basedir}/../avro/schemas/commands/rec</import>
</imports>
</configuration>
</execution>
</executions>
</plugin>
The important thing to note is that there is a conflict between the UUIDConversion and String in the current release of the plugin, as such you either need to choose which is more important, or use 1.10.0-SNAPSHOT which has a fix merged, but not yet released.

Categories