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

refactor: add models for server object #497

Merged
merged 17 commits into from
Mar 25, 2022

Conversation

Souvikns
Copy link
Member

Description

  • add server model
  • add unit tests

Related issue(s)

Part of #482

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome to AsyncAPI. Thanks a lot for creating your first pull request. Please check out our contributors guide useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

@Souvikns
Copy link
Member Author

I am opening this for review, I think I am done with most of the work, will be adding tests now.

@Souvikns Souvikns marked this pull request as ready for review March 17, 2022 12:33
Copy link
Member

@magicmatatjahu magicmatatjahu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, but we need some improvements. Please @smoya look at my comments, because we probably should change Parser API.

Comment on lines 13 to 16
servers(): Record<string, ServerInterface>;
hasServers(): boolean;
serverNames(): Array<string>;
server(name: string): ServerInterface;
Copy link
Member

@magicmatatjahu magicmatatjahu Mar 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First one, we don't have such a hasServers method in the https://github.com/asyncapi/parser-api/blob/master/docs/v1.md#asyncapidocument API.

Also I think that we should go with direction like in mixins with rest of methods:

hasServer(name: string): boolean;

servers(): ServerInterface[];
servers(name: string): ServerInterface | undefined;

you can check at example https://github.com/asyncapi/parser-js/blob/next-major/src/models/mixins/bindings.ts#L24

@smoya What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We did an initial implementation in plain JS in this PR #453.
Btw, that PR is like a first implementation draft on the parser-api and we should stick as much as we can with it.

In particular, this is how we solve all the collection of models:

We create an intermediate model, in this case servers which has some methods on it, like isEmpty().
You can see: https://github.com/asyncapi/parser-js/pull/453/files#diff-e871b9dd78d395cf3023273d1db969ee7638c3f5079fb1ac9323a921f46d6016

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I didn't know about that 😆

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, my bad. I created a new issue in parser-api to let parser-api to keep up with that implementation: asyncapi/parser-api#53

Comment on lines 1 to 5
import { BaseModel } from "./base";

export interface ServerSecurityRequirementInterface extends BaseModel {

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServerSecurityRequirementInterface is unnecessary because it should not be a model, but only type https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#securityRequirementObject

Comment on lines 7 to 13
url(): string;
protocol(): string;
protocolVersion(): string
variables(): Record<string, ServerVariableInterface>;
variable(name: string): ServerVariableInterface;
hasVariables(): boolean;
security(): [ServerSecurityRequirementInterface] | undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

url and protocol are required, rest of fields are optional, so they should return ... | undefined.

Also I opt to have methods like:

hasVariables(): boolean;
hasVariables(name: string): boolean;

variables(): Record<string, ServerVariableInterface> | undefined;
variables(name: string): ServerVariableInterface | undefined;

cc @smoya

also type like [ServerSecurityRequirementInterface] is a tuple, not array of the items.

Copy link
Member

@smoya smoya Mar 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also read #497 (comment).

Intermediate models are the preferred solution (unless better alternative).

test/models/v2/server.spec.ts Outdated Show resolved Hide resolved
src/models/server.ts Outdated Show resolved Hide resolved
src/models/asyncapi.ts Outdated Show resolved Hide resolved
@smoya
Copy link
Member

smoya commented Mar 18, 2022

@Souvikns I'm not sure if I mentioned already, if not I'm so sorry, but @jonaslagoni and me did an initial implementation of the new Intent API but in the current plain javascript parser. It is here and has been through several iterations getting feedback: #453

So we would need to port that to TS "mainly".

@magicmatatjahu
Copy link
Member

@smoya I didn't know about that 😆

@Souvikns
Copy link
Member Author

I have a question @smoya

In operations.js file here https://github.com/jonaslagoni/parser-js/blob/259446323a31786a867f3714457445278eecbf45/lib/models/operations.js#L26 we have operations.type() but I don't see any implementation of it in https://github.com/jonaslagoni/parser-js/blob/feature%2Fmock_implementation/lib/models/operation.js also I can't find any definition of type in operation object in spec - https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#operationObject

Can you give me some insight on this?

@magicmatatjahu
Copy link
Member

@Souvikns type is type of operation. In 2.x.x it will be publish/subscribe, in the 3.x.x it will be send/receive :) You must treat the operation key as a type.

@Souvikns
Copy link
Member Author

@magicmatatjahu I read asyncapi/spec#618 now this kind of makes sense, so are we following this proposal for v3 completely (I didn't read all the 77 comments kinda hard to track 😄 ).

The Doubt I have

why does the server have operations? what I get from reading asyncapi/spec#618 is operations is going to reuse channels how does server object has a relation to operation object is there another proposal for this?

@magicmatatjahu
Copy link
Member

@Souvikns At the moment you should only focus on 2.x.x not on 3.x.x (we don't have any merged PR for 3.x.x yet), so in the ^2.2.x versions you have servers field in the ChannelObjects so you should retrieve all operations defined for given server. Empty servers field means that all operations defined in all channels belong to the server, and vice versa, defined servers means that given channel belongs only to the given server(s) :)

@magicmatatjahu
Copy link
Member

@Souvikns But atm we don't have implemented operations and other needed models so please skip methods (create only signature) related to them, ok?

@Souvikns
Copy link
Member Author

@magicmatatjahu should I be waiting for this #499 since I think I need to use the collection class for the servers class?

@magicmatatjahu
Copy link
Member

@Souvikns As I know Sergio now is making review, so yes, please wait :)

@smoya
Copy link
Member

smoya commented Mar 21, 2022

@Souvikns As I know Sergio now is making review, so yes, please wait :)

It is done, and there is no blocker for merging (there is one thing we can change later after merging). So it's just a fact of merging it now 🚀

@magicmatatjahu
Copy link
Member

Merged :)

@Souvikns Souvikns requested a review from magicmatatjahu March 24, 2022 08:46
Copy link
Member

@magicmatatjahu magicmatatjahu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good, but some things don't work at all and need to be improved and some methods removed because they are unnecessary. I know, ParserAPI says something different, but ParserAPI needs to be changed in several places.

Comment on lines 8 to 10
id(): string {
return this.json('id');
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had discussion in Slack that id should not be a part of _json :) I also gave you example how it should work - https://github.com/asyncapi/parser-js/blob/next-major/src/models/v2/mixins/extensions.ts#L11

Suggested change
id(): string {
return this.json('id');
}
constructor(
private readonly _id: string,
_json: Record<string, any>,
) {
super(_json);
}
id(): string {
return this._id;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this because I modeled the utils function to convert object to array something like this

export function createArrayFromMap(json: Record<string,any>){
  const ArrayObject = [];
  for (const [key, value] of Object.entries(json)) {
    value['id'] = key;
    ArrayObject.push(value);
  };

  return ArrayObject;
}

so I thought maybe I don't need the add a separate id variable can just get it to format it. Main reason was so that the v2 and v3 have minimal changes, because to add seperate _id parameter now we have to pass something like new Servers(id, this._json)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v3 changes may be much bigger than they are now (to be honest we don't have anything approved so v3=v2 now), so please don't look at this proposal from Fran as something final.

About id. Have in mind that if someone will run json() should get the value that is defined for the object in the specification (not including traits because we have to combine them) without any additional fields that are not defined in the object, so what you want to get with adding the id field is nothing more than changing the original json. I know that adding an id as an argument to a constructor can be weird, but in this case the id is outside the object, and in v3 it can be part of the object and it will be easier to handle.

src/models/v2/server.ts Outdated Show resolved Hide resolved
Comment on lines 12 to 18
hasName(): boolean {
return !!this.json('name');
}

name(): string | undefined {
return this.json('name');
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@smoya smoya Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name is the key in the map of servers. But I think we can change it to ID to be consistent?

Copy link
Member

@magicmatatjahu magicmatatjahu Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is id then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the key in the map of servers

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, so name and hasName is out @Souvikns

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So then what is id? I was thinking that id is the key

Copy link
Member

@smoya smoya Mar 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to use id() for all objects like Channel, Server, Operation, etc, instead of path() for Channels, name for Servers, etc
If we add a ID method for all of those models, no matter if we later change the source of them between versions.
I know the parser-api doesn’t reflect that but we learnt a lot during the last few months :)

src/models/v2/asyncapi.ts Outdated Show resolved Hide resolved
src/models/v3/asyncapi.ts Outdated Show resolved Hide resolved
src/models/v3/server.ts Show resolved Hide resolved
@Souvikns
Copy link
Member Author

I am getting code smell warnings from sonarcloud for semicolons what should I do?

@magicmatatjahu
Copy link
Member

magicmatatjahu commented Mar 24, 2022

I am getting code smell warnings from sonarcloud for semicolons what should I do?

as I see, it's from my PR (weird that sonarcloud didn't check it on my PR). I will remove smells from my next PR, no worries.

@Souvikns Souvikns requested a review from magicmatatjahu March 25, 2022 08:55
Copy link
Member

@magicmatatjahu magicmatatjahu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall good, but I see that we have redundant unit tests and also in v2 version we have unnecessary methods. I create suggestions :)

src/models/v2/server.ts Outdated Show resolved Hide resolved
test/models/v2/server.spec.ts Outdated Show resolved Hide resolved
test/models/v2/server.spec.ts Outdated Show resolved Hide resolved
test/models/v2/server.spec.ts Outdated Show resolved Hide resolved
test/models/v2/server.spec.ts Outdated Show resolved Hide resolved
test/models/v2/server.spec.ts Outdated Show resolved Hide resolved
@magicmatatjahu
Copy link
Member

@Souvikns Good, last thing because I see that sonarcloud fails on duplicated code - please create .sonarcloud.properties file in the root with content:

# Disable specific duplicate code since it would introduce more complexity to reduce it.
sonar.cpd.exclusions=src/models/**/*.ts

and we can merge :)

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 27 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

Copy link
Member

@magicmatatjahu magicmatatjahu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for contribution! :)

@magicmatatjahu magicmatatjahu changed the title feat: add models for server object refactor: add models for server object Mar 25, 2022
@magicmatatjahu
Copy link
Member

/rtm

@asyncapi-bot asyncapi-bot merged commit 875354f into asyncapi:next-major Mar 25, 2022
magicmatatjahu pushed a commit to magicmatatjahu/parser-js that referenced this pull request Oct 3, 2022
derberg pushed a commit that referenced this pull request Oct 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants