Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues #5: CADL Generated Code Issue in EventGrid SDK #1851

Open
sarangan12 opened this issue May 17, 2023 · 1 comment
Open

Issues #5: CADL Generated Code Issue in EventGrid SDK #1851

sarangan12 opened this issue May 17, 2023 · 1 comment
Assignees
Labels

Comments

@sarangan12
Copy link
Member

While working on the EventGrid SDK, generated from the CADL files, I have noticed the following.

In CADL, we have the following CloudEvent Model:

@doc("Properties of an event published to an Azure Messaging EventGrid Namespace topic using the CloudEvent 1.0 Schema.")
model CloudEvent {
    @doc("An identifier for the event. The combination of id and source must be unique for each distinct event.")
    id: string;

    @doc("Identifies the context in which an event happened. The combination of id and source must be unique for each distinct event.")
    source: string;

    @doc("Event data specific to the event type.")
    data?: unknown;

    @doc("Event data specific to the event type, encoded as a base64 string.")
    data_base64?: bytes;
    
    @doc("Type of event related to the originating occurrence.")
    type: string;

    @doc("The time (in UTC) the event was generated, in RFC3339 format.")
    time?: utcDateTime;

    @doc("The version of the CloudEvents specification which the event uses.")
    specversion: string;

    @doc("Identifies the schema that data adheres to.")
    dataschema?: string;

    @doc("Content type of data value.")
    datacontenttype?: string;

    @doc("This describes the subject of the event in the context of the event producer (identified by source).")
    subject?: string;
}

Now, we have 2 APIs, publishCloudEvent & publishCloudEvents apis:

@doc("Publish Single Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which indicates quota exceeded or message is too large, 410: which indicates that specific topic is not found, 400: for bad request, and 500: for internal server error. ")
  @route("/topics/{topicName}:publish", {shared: true})
  @post op PublishCloudEvent is Azure.Core.RpcOperation<{
    @doc("content type")
    @header("content-type")
    contentType: "application/cloudevents+json; charset=utf-8";

    @doc("Topic Name.")
    @path
    topicName: string;

    @doc("Single Cloud Event being published.")
    @body 
    event: CloudEvent;
  }, PublishResult>;

@doc("Publish Batch Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which indicates quota exceeded or message is too large, 410: which indicates that specific topic is not found, 400: for bad request, and 500: for internal server error. ")  
  @route("/topics/{topicName}:publish", {shared: true})
  @post op PublishCloudEvents is Azure.Core.RpcOperation<{
    @doc("content type")
    @header("content-type")
    contentType: "application/cloudevents-batch+json; charset=utf-8";

    @doc("Topic Name.")
    @path
    topicName: string;

    @doc("Array of Cloud Events being published.")
    @body
    events: CloudEvent[];
}, PublishResult>;

Now, if you look at the generated SDK code, it looks like the following:

publishCloudEvent(
    id: string,
    source: string,
    type: string,
    specversion: string,
    topicName: string,
    options: PublishCloudEventOptions = { requestOptions: {} }
  ): Promise<Record<string, any>> {
    return publishCloudEvent(this._client, event, topicName, options);
  }

  publishCloudEvents(
    events: CloudEvent[],
    topicName: string,
    options: PublishCloudEventsOptions = { requestOptions: {} }
  ): Promise<Record<string, any>> {
    return publishCloudEvents(this._client, events, topicName, options);
  }

Now, this is unexpected. Look at the parameters of the publishCloudEvent API. the CloudEvent object is flattened and the mandatory parameters of CloudEvent object are pulled outside and made individual parameters which is not the expected output. The expected output is:

publishCloudEvent(
    event: CloudEvent,
    topicName: string,
    options: PublishCloudEventOptions = { requestOptions: {} }
  ): Promise<Record<string, any>> {
    return publishCloudEvent(this._client, event, topicName, options);
}

Currently, per Jose's suggestion, I am using the following workaround in CADL as:

@doc("Publish Cloud Event Body")
  model PublishCloudEventBody {
    @doc("content type")
    @header("content-type")
    contentType: "application/cloudevents+json; charset=utf-8";

    @doc("Topic Name.")
    @path
    topicName: string;

    @doc("Single Cloud Event being published.")
    @body 
    event: { event: CloudEvent };
  }

@doc("Publish Single Cloud Event to namespace topic. In case of success, the server responds with an HTTP 200 status code with an empty JSON object in response. Otherwise, the server can return various error codes. For example, 401: which indicates authorization failure, 403: which indicates quota exceeded or message is too large, 410: which indicates that specific topic is not found, 400: for bad request, and 500: for internal server error. ")
  @route("/topics/{topicName}:publish", {shared: true})
  @post op PublishCloudEvent is Azure.Core.RpcOperation<PublishCloudEventBody, PublishResult>;

This kind of solves the problem partially. It has other issues in the generated code which I have modified manually. So, we need to find a permanent fix for this issue.

@sarangan12
Copy link
Member Author

sarangan12 added a commit to Azure/azure-sdk-for-js that referenced this issue May 22, 2023
)

### Packages impacted by this PR
@Azure/eventgrid 

### Issues associated with this PR
NA

### Describe the problem that is addressed by this PR
1. The EventGrid Service team has introduced a new Client called
`EventGridClient` with 4 apis - `publishCloudEvent`,
`publishCloudEvents`, `receiveCloudEvents`, `acknowledgeCloudEvents`,
`releaseCloudEvents` and `rejectCloudEvents`. Now, the service is
represented using the [new CADL
specification](https://github.com/Azure/azure-rest-api-specs/tree/feature/eventgrid/typespec/specification/eventgrid/Azure.Messaging.EventGrid).
This SDK, in this PR, has been generated using the new [JS SDK CADL
Generator](https://github.com/Azure/autorest.typescript/tree/main/packages/typespec-ts).

2. During the generation process, I had a few issues in the generation
process. Seperate issues have been filed for the same and many of them
have already been resolved. For the remaining issues, I have provided
manual patches in this PR, so the release schedule will not be impacted.
Jose is already working on fixing any remaining issues. A complete list
of issues can be found in the related PRs/Issues section below.

3. This is a **beta** release. So, this code is not merged to the main
branch. The code changes are merged to a private branch
**feature/eventgrid/4_13_beta_1**.

**APIView To Approve** 

https://apiview.dev/Assemblies/Review/de09872b51a24f489981db711a73c430/2e0e731c80a840faab6df4c51acb6e95?diffRevisionId=2a4fb5a9265847c09428acb9b0581b0e&doc=False&diffOnly=True

### What are the possible designs available to address the problem? If
there are more than one possible design, why was the one in this PR
chosen?
No special design considerations for the generation process.

### Are there test cases added in this PR? _(If not, why?)_
This version of the eventgrid service has not been released to public
and not available through azure portal. So, the test cases are not added
to this PR for now. Locally, I have tested the code changes with private
test resources and confirmed that the apis are working fine.

### Provide a list of related PRs/Issues _(if any)_
1. Azure/autorest.typescript#1818
2. Azure/autorest.typescript#1819
3. Azure/autorest.typescript#1820
4. Azure/autorest.typescript#1821
5. Azure/autorest.typescript#1851
6. Azure/autorest.typescript#1852
7. Azure/autorest.typescript#1853

### Command used to generate this PR:**_(Applicable only to SDK release
request PRs)_
npx tsp compile main.tsp

### Checklists
- [X] Added impacted package name to the issue description
- [ ] Does this PR needs any fixes in the SDK Generator?** _(If so,
create an Issue in the
[Autorest/typescript](https://github.com/Azure/autorest.typescript)
repository and link it here)_
- [X] Added a changelog (if necessary)

@joheredi @ellismg Please review and approve the PR. 

@xirzec FYI....
@MaryGao MaryGao assigned MaryGao and unassigned joheredi May 31, 2023
@MaryGao MaryGao added RLC DPG/RLC v2.1 Gallium work labels May 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants