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

Make sure responses other than 20x are also handled! #24

Closed
isc-tstolker opened this issue Oct 13, 2023 · 3 comments
Closed

Make sure responses other than 20x are also handled! #24

isc-tstolker opened this issue Oct 13, 2023 · 3 comments

Comments

@isc-tstolker
Copy link
Collaborator

isc-tstolker commented Oct 13, 2023

Right now, if a service responds with an http status code other than 20x, the reply gets lost, given that the ..Adapter.SendFormDataArray() returns a $$$EnsErrHTTPStatus status, causing the client to abort.

In a case where the openapi specification specified non-20x status codes, this should not happen:

        "responses":{
          "200":{
            "description":"The posted JWT is valid. Responds with access token",
            "content":{
              "application/json":{
                "schema":{
                  "$ref":"#/components/schemas/AccessTokenResponse"
                }
              }
            }
          },
          "400":{
            "description":"The posted JWT is invalid.",
            "content":{
              "application/json":{
                "schema":{
                  "$ref":"#/components/schemas/AccessTokenRequestFailedResponse"
                }
              }
            }
          }

The LoadFromResponse is well-genarated:

/// http status code = 400 content-type = application/json
/// 
Property AccessTokenRequestFailedResponse As Nuts.Api.Auth.model.AccessTokenRequestFailedResponse;

/// http status code = 200 content-type = application/json
/// 
Property AccessTokenResponse As Nuts.Api.Auth.model.AccessTokenResponse;

/// Implement operationId : createAccessToken
/// post /n2n/auth/v1/accesstoken
Method LoadFromResponse(httpResponse As %Net.HttpResponse, caller As %String = "") As %Status
{
	Set sc = $$$OK
	Do ##super(httpResponse, caller)
	If $$$LOWER($Piece(httpResponse.ContentType,";",1))="application/json",httpResponse.StatusCode = "200" {
		Set ..AccessTokenResponse = ##class(Nuts.Api.Auth.model.AccessTokenResponse).%New()
		Do ..AccessTokenResponse.%JSONImport(httpResponse.Data)
		Return sc
	}
	If $$$LOWER($Piece(httpResponse.ContentType,";",1))="application/json",httpResponse.StatusCode = "400" {
		Set ..AccessTokenRequestFailedResponse = ##class(Nuts.Api.Auth.model.AccessTokenRequestFailedResponse).%New()
		Do ..AccessTokenRequestFailedResponse.%JSONImport(httpResponse.Data)
		Return sc
	}
	Quit sc
}

Buth the 400-code path is never executed!

To properly handle the non-20x codes, the code generation must be changed for BO

For the BO, I propose the following new code:

/// Create an access token using a JWT as authorization grant
/// Implement operationId : createAccessToken
/// post /n2n/auth/v1/accesstoken
Method createAccessToken(requestMessage As Nuts.Api.Auth.requests.createAccessToken, Output responseMessage As Nuts.Api.Auth.responses.createAccessToken) As %Status
{
	set responseMessage = ##class(Nuts.Api.Auth.responses.createAccessToken).%New()
	return ..HandleRequest(requestMessage, "createAccessToken", responseMessage)
}

Where handlerequest is a common method that has the following code:

/// Common request handler
Method HandleRequest(requestMessage As Ens.Request, name As %String, responseMessage As Nuts.Api.Common.responses.GenericResponse) As %Status
{
	Set sc = $$$OK, pHttpRequestIn = ##class(%Net.HttpRequest).%New()
	$$$QuitOnError(requestMessage.LoadHttpRequestObject(pHttpRequestIn))
	set sc = ..Adapter.SendFormDataArray(.pHttpResponse, "post", pHttpRequestIn, , , ..Adapter.URL_requestMessage.%URL)

	if $$$ISERR(sc) && ($SYSTEM.Status.GetErrorCodes(sc) '= $$$EnsErrHTTPStatus)
	{
		return sc
	}

	if $ISOBJECT(pHttpResponse)
	{
		$$$TRACE(name _" returned " _ pHttpResponse.StatusCode)

		$$$QuitOnError(responseMessage.LoadFromResponse(pHttpResponse, name))
	}

	return sc
}

This is an issue only for the BusinessOperation, the HttpClient works as expected

@isc-tstolker
Copy link
Collaborator Author

Hi @lscalese , see PR #30

lscalese added a commit that referenced this issue Oct 16, 2023
@lscalese
Copy link
Owner

Merged!
Thank you

@isc-tstolker
Copy link
Collaborator Author

Thanks Lorenzo!

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

No branches or pull requests

2 participants