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

SOF-1670 Expose Endpoint To Reload Rundown #88

Merged
merged 10 commits into from
Nov 3, 2023

Conversation

RasmusAlbrektsen
Copy link
Contributor

This PR uses Koa to create a standalone endpoint that can be used to reload the iNews data for a given rundown, without going through Core. This is simplified by retrieving only a rundownName (the iNews path) rather than using a new property in sofie-server for this purpose. This did, however, require a suffix (_1) to be used with the current implementation of the gateway.

Copy link
Contributor

@LindvedKrvang LindvedKrvang left a comment

Choose a reason for hiding this comment

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

Nice and simple :)

src/connector.ts Outdated
if (!this.iNewsFTPHandler.iNewsWatcher) {
return
}
this.iNewsFTPHandler.iNewsWatcher?.ResyncRundown(ctx.params.rundownName + RUNDOWN_EXTERNAL_ID_SUFFIX)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you need the ?? You just checked that you had an iNewsWatcher on line 149.
If you still need it, then you shouldn't need the if-statement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A mistake on my part, i must have forgot to remove it after i made the guard for that very purpose :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have changed it!

src/connector.ts Outdated

this.koaApp.use(this.koaRouter.routes()).use(this.koaRouter.allowedMethods())

this.koaApp.listen(3007, () => {})
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be nice if the port was also in a constant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved into a constant KOA_PORT.

src/connector.ts Outdated
const KOA_PORT: number = 3007
const RUNDOWN_EXTERNAL_ID_SUFFIX: string = '_1'

this.koaRouter.get('/reloadData/:rundownName', async (ctx, next): Promise<void> => {
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. I guess ctx stands for context?
  2. Do we have types for ctx and next?
  3. What is the response, when calling this endpoint? And is it formatted such that the caller can, in a structured way, decipher it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. True, it is short for context.
  2. We do have types, which is e.g. next: Koa.next and that would be nice to add but i decided not to since the type for context: ctx: Koa.ParameterizedContext<any, KoaRouter.IRouterParamContext<any, {}>, any>.
  3. I guess there really shouldn't be a specific response other than maybe success or "failure".

Copy link
Contributor

Choose a reason for hiding this comment

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

You could use a custom type that encapsulates the data that you need from the koa context.

src/connector.ts Outdated
const KOA_PORT: number = 3007
const RUNDOWN_EXTERNAL_ID_SUFFIX: string = '_1'

this.koaRouter.get('/reloadData/:rundownName', async (ctx, next): Promise<void> => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps another method than GET should be used, since we are not reading the data out, but triggering a computation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did think about this, what is more correct in this scenario? POST and PUT, for instance, would signify that the we actually submit something rather than trigger a computation, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For now it has been changed to a POST.

src/connector.ts Outdated
Comment on lines 151 to 153
if (!this.iNewsFTPHandler.iNewsWatcher) {
return
}
Copy link
Contributor

Choose a reason for hiding this comment

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

In the case where we can't reload the data, wouldn't the caller be interested in knowing that the rundown has not been reloaded?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added more handling towards this purpose!

src/connector.ts Outdated
const KOA_PORT: number = 3007
const RUNDOWN_EXTERNAL_ID_SUFFIX: string = '_1'

this.koaRouter.post('/reloadData/:rundownName', async (context, next): Promise<void> => {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not following REST standards (maybe that is fine).
If we want this URL to follow REST standards, it should be changed to do so.

Personally, I would prefer it, but I can see arguments for not doing it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see your point, and on Sofie Server i'd say it makes a lot of sense. Here, however, i might counter argue that because of the setup where we both actually work on playlists and rundowns to do this operation, it's difficult to just use e.g. rundowns/reloadData/:rundownName since it is used for both playlists and rundowns.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On another note, this is tied to our implementation of Sofie Server alone, so i will name it to fit the standard it follows!

src/connector.ts Outdated
await next()
try {
context.response.body = `Attempting to reload rundown with name ${rundownName}`
await this.iNewsFTPHandler.iNewsWatcher.ResyncRundown( rundownName + RUNDOWN_EXTERNAL_ID_SUFFIX)
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you running lint?
A lot of your PRs (not just this one) has small syntax 'issues'. Here it is an extra space before rundownName.
In your PR for SofieServer for this it appears random whether your imports have spaces or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've never had this issue before with linting, i will be sure to check and do it.

Copy link
Contributor

@KvelaGorrrrnio KvelaGorrrrnio left a comment

Choose a reason for hiding this comment

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

Requesting changes due to two approvals :D

src/connector.ts Outdated
const RUNDOWN_EXTERNAL_ID_SUFFIX: string = '_1'

this.koaRouter.post(
'/reloadData/rundowns/:rundownName',
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of defining the resource on the action, the action should be defined on the resource as /rundowns/:rundownName/reload-data.

I have changed reloadData to reload-data to avoid clash between case-sensitive and case-insensitive systems (https://blog.restcase.com/5-basic-rest-api-design-guidelines/, see spinal-case).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the read, that helped!
I changed it to fit the suggestion, although it is reingest-data instead to follow the instructions provided for the frontend.

src/connector.ts Outdated
const KOA_PORT: number = 3007
const RUNDOWN_EXTERNAL_ID_SUFFIX: string = '_1'

this.koaRouter.get('/reloadData/:rundownName', async (ctx, next): Promise<void> => {
Copy link
Contributor

Choose a reason for hiding this comment

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

You could use a custom type that encapsulates the data that you need from the koa context.

src/connector.ts Outdated
}

try {
context.response.body = `Attempting to reload rundown with name ${rundownName}`
Copy link
Contributor

Choose a reason for hiding this comment

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

The state that is send back should represent the end state of the action. This should be set after the resync action is called.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now correctly does so!

src/connector.ts Outdated
try {
context.response.body = `Attempting to reload rundown with name ${rundownName}`
await this.iNewsFTPHandler.iNewsWatcher.ResyncRundown(rundownName + RUNDOWN_EXTERNAL_ID_SUFFIX)
await next()
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't next be called before the logic of the endpoint? That way, if there is other middleware, e.g. authentication, it is called before applying the business logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Next has been removed since you are absolutely right.

@RasmusAlbrektsen RasmusAlbrektsen merged commit a9c49b5 into develop Nov 3, 2023
5 checks passed
@RasmusAlbrektsen RasmusAlbrektsen deleted the SOF-1670/ExposeEndpointToReloadRundown branch November 3, 2023 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants