quarkiverse / quarkus-asyncapi

AsyncAPI Quarkus configuration and metadata generator
https://www.asyncapi.com/
Apache License 2.0
11 stars 9 forks source link

The asyncapi.html endpoint returns the Error: Failed to fetch #112

Closed mosaic-aaron closed 1 year ago

mosaic-aaron commented 1 year ago

Hi, great to see that this extension has been created, however, I'm having trouble getting it to work.

Requests made to the Quarkus dev server path of /asyncapi.html results in a 200 response and the rendered text Error: Failed to fetch.

When inspecting the HTML rendered, I'm seeing an invalid schemaURL set as an attribute of the asyncapi-component:

    <asyncapi-component
      cssImportPath="https://unpkg.com/@asyncapi/react-component@1.0.0-next.48/styles/default.css"
      schemaUrl="//asyncapi.yaml"
    >
    </asyncapi-component>

After fixing this locally, I'm now seeing the following error text emitted as the response from the /asyncapi.html path:

Error: There were errors validating the AsyncAPI document. undefined./ should have required property 'channels'

It doesn't appear that the annotation scanning is working as expected. Here's the YAML returned from my application's /async-api.yaml endpoint:

---
asyncapi: "2.6.0"
id: "urn:com:kafka:server"
defaultContentType: "application/json"
info:
  title: "AsyncApi"
  version: "1.0.0"
  contact:
    email: "you@mail.org"
  license:
    name: "Commercial"
servers:
  local:
    url: "localhost:32807"
    protocol: "kafka"
components:
  schemas:
    DayOfWeek:
      type: "string"
      enum:
      - "MONDAY"
      - "TUESDAY"
      - "WEDNESDAY"
      - "THURSDAY"
      - "FRIDAY"
      - "SATURDAY"
      - "SUNDAY"
    Duration:
      examples:
      - "P1D"
      type: "string"
      format: "duration"
      externalDocs:
        description: "ISO-8601 representation of a duration"
        url: "https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#toString--"
    LocalTime:
      examples:
      - "13:45.30.123456789"
      type: "string"
      format: "local-time"
      externalDocs:
        description: "ISO-8601 representation of a extended local time"
        url: "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_LOCAL_TIME"
    OffsetDateTime:
      examples:
      - "2022-03-10T12:15:50-04:00"
      type: "string"
      format: "date-time"
      externalDocs:
        description: "A date-time with an offset from UTC/Greenwich in the ISO-8601\
          \ calendar system"
        url: "https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html"
    Quantity:
      type: "object"
      required:
      - "value"
      - "unit"
      properties:
        scale:
          default: "ABSOLUTE"
          $ref: "#/components/schemas/Scale"
        unit:
          description: "Symbol of unit."
          type: "string"
        value:
          type: "number"
    Scale:
      type: "string"
      enum:
      - "ABSOLUTE"
      - "RELATIVE"
    UUID:
      type: "string"
      pattern: "[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}"
      format: "uuid"

However, the application I'm developing has a working integration with three different Kafka topics.

Is there an example Quarkus project which demonstrates how this extension works? That will help me to find the root issue.

Dev environment details

quarkus-asyncapi: v0.2.0 Quarkus version: 3.2.2.Final Java version: JDK 17

Relevant extensions

ChMThiel commented 1 year ago

Hi @mosaic-aaron,

sorry for the late reply, i was on holiday for 3 weeks... There is no special demo-project, only the docu. But there is a Test-Project which demonstrates the usage.

May be you are missing some config-properties? Do you have at least following configs set:

quarkus.asyncapi.annotation.scanner.server.testServer.url=${kafka.bootstrap.servers}
quarkus.asyncapi.annotation.scanner.server.testServer.protocol=kafka

it sounds strange that your endpoint ends with aysnc-api.yaml. It should always be asyncapi.[html|yaml|json] (without the -) Do you have a small Test-project to reproduce the problem?

Krasobas commented 1 year ago

Hello, i have the same problem. I have set all variables in application.properties but i haveundefined./ should have required property 'channels' when i try to access asyncapi.html

and i don't undestand at all how to use quarkus-asyncapi, if you could give more information how to use your extension it will be fantastic)))

ChMThiel commented 1 year ago

@Krasobas do you have at least one method or property in your project annotated with @Channel, @Incoming or @Outgoing? It seems no such method or property is found, and so the required (by AsyncApi-spec) info channels is not set.

Krasobas commented 1 year ago

Thanks for answer, no I've not annotated my methods before test. Tell me please, does the scanner work only with kafka? I would like to use it for websockets and rest services. async api official docs tell that it's possible. and how to useio.quarkiverse.asyncapi:quarkus-asyncapi ? if I should create asyncapi.yaml to use this where sould I put it, will it generate the doc page in my project?

ChMThiel commented 1 year ago

there are two modes in this extension:

  1. use a given asyncapi-file and generate microprofile message-code
  2. scan current project for microprofile-messaging and generate a describing asyncApi-file for them

Depending of your architecture (asyncapi-definition-first or code-first) you have to choose 1 or 2.

I did the second part (code-first). Currently it describes Kafka-topics & messages only.

The first part is contributed by @fjtirado. Maybe he can help you, if you already have an asyncapi-file.

fjtirado commented 1 year ago

Following on @ChMThiel accurate description (thanks ;)) quarkus-asyncapi generates microprofile configuration given an existing async api file for kafka and http connectors. So basically it avoids manually writing the channel configuration on application.properties (which might be too verbose), you still need to write your annotated publishers and consumers

jogerj commented 10 months ago

This is still an issue, when the page is opened, it could not resolve http://asyncapi.yaml/ because the schemaUrl is incorrectly passed to the props. When I edit the web page to replace schemaUrl="//asyncapi.yaml" with schemaUrl="/asyncapi.yaml", the page is loaded correctly (albeit missing fonts).

From the code, schemaUrl is configured to ${quarkus.http.root-path}/asyncapi.yaml which appends the extra /

mosaic-aaron commented 1 month ago

@ChMThiel just to follow-up (one year later!), I was finally able to get this extension to work. The root issue is that I had a topic reference named incoming.foo.barz, which aligned with the actual topic name. After renaming the topic reference to incoming-foo-barz the microprofile annotation scanning process was able to produce the expected AsyncAPI specification.

Below is an example of what my original application.yaml configuration looked like:

mp:
  messaging:
    incoming:
      incoming.foo.barz:
        topic: incoming.foo.barz
        auto:
          offset:
            reset: latest
        connector: smallrye-kafka
    outgoing:
      outgoing.foo.barz:
        topic: outgoing.foo.barz
        connector: smallrye-kafka

If you would like, I can submit a PR for fixing this issue that comes up when the . character is within an incoming or outgoing topic reference.

ChMThiel commented 1 month ago

@mosaic-aaron feel free to submit an PR