public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Chang, Abner" <abner.chang@amd.com>
To: Igor Kulchytskyy <igork@ami.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "nickle.wang@hpe.com" <nickle.wang@hpe.com>
Subject: Re: [PATCH V4 3/3] RedfishPkg: Redfish functions for REST requests are not fully spec complied
Date: Fri, 19 Aug 2022 07:52:07 +0000	[thread overview]
Message-ID: <MN2PR12MB3966B8FE16C12F79FBA8A13DEA6C9@MN2PR12MB3966.namprd12.prod.outlook.com> (raw)
In-Reply-To: <1660851683-3680-1-git-send-email-igork@ami.com>

[AMD Official Use Only - General]

Reviewed-by: Abner Chang <abner.chang@amd.com>

Thanks!

> -----Original Message-----
> From: Igor Kulchytskyy <igork@ami.com>
> Sent: Friday, August 19, 2022 3:41 AM
> To: devel@edk2.groups.io
> Cc: Chang, Abner <Abner.Chang@amd.com>; nickle.wang@hpe.com; Igor
> Kulchytskyy <igork@ami.com>; Chang, Abner <Abner.Chang@amd.com>
> Subject: [PATCH V4 3/3] RedfishPkg: Redfish functions for REST requests are
> not fully spec complied
> 
> [CAUTION: External Email]
> 
> There is no function to send POST request with the ContentType different
> from "application\json".
> There is no function to send DELETE request with the body.
> 
> Cc: Abner Chang <abner.chang@amd.com>
> Cc: Nickle Wang <nickle.wang@hpe.com>
> Signed-off-by: Igor Kulchytskyy <igork@ami.com>
> ---
>  RedfishPkg/Include/Library/RedfishLib.h                                      |  80 +++++++++
>  RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.c                            | 189
> ++++++++++++++++++++
> 
> RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfishService.
> h |   8 +
>  RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/service.c            |  41
> ++++-
>  4 files changed, 316 insertions(+), 2 deletions(-)
> 
> diff --git a/RedfishPkg/Include/Library/RedfishLib.h
> b/RedfishPkg/Include/Library/RedfishLib.h
> index b2488ab..ce39ce3 100644
> --- a/RedfishPkg/Include/Library/RedfishLib.h
> +++ b/RedfishPkg/Include/Library/RedfishLib.h
> @@ -380,6 +380,49 @@ RedfishPatchToPayload (
>    OUT    REDFISH_RESPONSE  *RedResponse
>    );
> 
> +
> +/**
> +  Use HTTP POST to create new Redfish resource in the Resource Collection.
> +
> +  The POST request should be submitted to the Resource Collection in
> + which the new resource  is to belong. The Resource Collection is
> + addressed by URI. The Redfish may  ignore any service controlled
> + properties. The corresponding redfish response will returned,  including
> HTTP StatusCode, Headers and Payload which record any HTTP response
> messages.
> +
> +  Callers are responsible for freeing the HTTP StatusCode, Headers and
> + Payload returned in  redfish response data.
> +
> +  @param[in]    RedfishService        The Service to access the Redfish
> resources.
> +  @param[in]    Uri                   Relative path to address the resource.
> +  @param[in]    Content               JSON represented properties to be update.
> +  @param[in]    ContentSize           Size of the Content to be send to Redfish
> service
> +  @param[in]    ContentType           Type of the Content to be send to Redfish
> service
> +  @param[out]   RedResponse           Pointer to the Redfish response data.
> +
> +  @retval EFI_SUCCESS             The opeartion is successful, indicates the HTTP
> StatusCode is not
> +                                  NULL and the value is 2XX. The Redfish resource will be
> returned
> +                                  in Payload within RedResponse if server send it back in the
> HTTP
> +                                  response message body.
> +  @retval EFI_INVALID_PARAMETER   RedfishService, Uri, Content, or
> RedResponse is NULL.
> +  @retval EFI_DEVICE_ERROR        An unexpected system or network error
> occurred. Callers can get
> +                                  more error info from returned HTTP StatusCode, Headers
> and Payload
> +                                  within RedResponse:
> +                                  1. If the returned StatusCode is NULL, indicates any error
> happen.
> +                                  2. If the returned StatusCode is not NULL and the value is
> not 2XX,
> +                                     indicates any error happen.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPostToUri (
> +  IN     REDFISH_SERVICE   RedfishService,
> +  IN     CONST CHAR8       *Uri,
> +  IN     CONST CHAR8       *Content,
> +  IN     UINTN             ContentSize,
> +  IN     CONST CHAR8       *ContentType,
> +  OUT    REDFISH_RESPONSE  *RedResponse
> +  );
> +
> +
>  /**
>    Use HTTP POST to create a new resource in target payload.
> 
> @@ -451,6 +494,43 @@ RedfishDeleteByUri (
>    );
> 
>  /**
> +  Use HTTP DELETE to remove a resource.
> +
> +  This function uses the RedfishService to remove a Redfish resource
> + which is addressed  by input Uri (only the relative path is required).
> + The corresponding redfish response will  returned, including HTTP
> + StatusCode, Headers and Payload which record any HTTP response
> messages.
> +
> +  Callers are responsible for freeing the HTTP StatusCode, Headers and
> + Payload returned in  redfish response data.
> +
> +  @param[in]    RedfishService        The Service to access the Redfish
> resources.
> +  @param[in]    Uri                   Relative path to address the resource.
> +  @param[in]    Content               JSON represented properties to be deleted.
> +  @param[out]   RedResponse           Pointer to the Redfish response data.
> +
> +  @retval EFI_SUCCESS             The opeartion is successful, indicates the HTTP
> StatusCode is not
> +                                  NULL and the value is 2XX, the Redfish resource has been
> removed.
> +                                  If there is any message returned from server, it will be
> returned
> +                                  in Payload within RedResponse.
> +  @retval EFI_INVALID_PARAMETER   RedfishService, Uri, or RedResponse is
> NULL.
> +  @retval EFI_DEVICE_ERROR        An unexpected system or network error
> occurred. Callers can get
> +                                  more error info from returned HTTP StatusCode, Headers
> and Payload
> +                                  within RedResponse:
> +                                  1. If the returned StatusCode is NULL, indicates any error
> happen.
> +                                  2. If the returned StatusCode is not NULL and the value is
> not 2XX,
> +                                     indicates any error happen.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishDeleteByUriEx (
> +  IN     REDFISH_SERVICE   RedfishService,
> +  IN     CONST CHAR8       *Uri,
> +  IN     CONST CHAR8       *Content,
> +  OUT    REDFISH_RESPONSE  *RedResponse
> +  );
> +
> +/**
>    Dump text in fractions.
> 
>    @param[in]  String   ASCII string to dump.
> diff --git a/RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.c
> b/RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.c
> index 9f9d377..6c0f426 100644
> --- a/RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.c
> +++ b/RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.c
> @@ -583,6 +583,104 @@ RedfishPatchToPayload (
>    return EFI_SUCCESS;
>  }
> 
> +
> +/**
> +  Use HTTP POST to create new Redfish resource in the Resource Collection.
> +
> +  The POST request should be submitted to the Resource Collection in
> + which the new resource  is to belong. The Resource Collection is
> + addressed by URI. The Redfish may  ignore any service controlled
> + properties. The corresponding redfish response will returned,  including
> HTTP StatusCode, Headers and Payload which record any HTTP response
> messages.
> +
> +  Callers are responsible for freeing the HTTP StatusCode, Headers and
> + Payload returned in  redfish response data.
> +
> +  @param[in]    RedfishService        The Service to access the Redfish
> resources.
> +  @param[in]    Uri                   Relative path to address the resource.
> +  @param[in]    Content               JSON represented properties to be update.
> +  @param[in]    ContentSize           Size of the Content to be send to Redfish
> service
> +  @param[in]    ContentType           Type of the Content to be send to Redfish
> service
> +  @param[out]   RedResponse           Pointer to the Redfish response data.
> +
> +  @retval EFI_SUCCESS             The opeartion is successful, indicates the HTTP
> StatusCode is not
> +                                  NULL and the value is 2XX. The Redfish resource will be
> returned
> +                                  in Payload within RedResponse if server send it back in the
> HTTP
> +                                  response message body.
> +  @retval EFI_INVALID_PARAMETER   RedfishService, Uri, Content, or
> RedResponse is NULL.
> +  @retval EFI_DEVICE_ERROR        An unexpected system or network error
> occurred. Callers can get
> +                                  more error info from returned HTTP StatusCode, Headers
> and Payload
> +                                  within RedResponse:
> +                                  1. If the returned StatusCode is NULL, indicates any error
> happen.
> +                                  2. If the returned StatusCode is not NULL and the value is
> not 2XX,
> +                                     indicates any error happen.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishPostToUri (
> +  IN     REDFISH_SERVICE   RedfishService,
> +  IN     CONST CHAR8       *Uri,
> +  IN     CONST CHAR8       *Content,
> +  IN     UINTN             ContentSize,
> +  IN     CONST CHAR8       *ContentType,
> +  OUT    REDFISH_RESPONSE  *RedResponse
> +  )
> +{
> +  EFI_STATUS        Status;
> +  EDKII_JSON_VALUE  JsonValue;
> +
> +  Status    = EFI_SUCCESS;
> +  JsonValue = NULL;
> +
> +  if ((RedfishService == NULL) || (Uri == NULL) || (Content == NULL) ||
> (RedResponse == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE));
> +
> +  JsonValue = (EDKII_JSON_VALUE)postUriFromService (
> +                                  RedfishService,
> +                                  Uri,
> +                                  Content,
> +                                  ContentSize,
> +                                  ContentType,
> +                                  &(RedResponse->StatusCode)
> +                                  );
> +
> +  //
> +  // 1. If the returned StatusCode is NULL, indicates any error happen.
> +  //
> +  if (RedResponse->StatusCode == NULL) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto ON_EXIT;
> +  }
> +
> +  //
> +  // 2. If the returned StatusCode is not NULL and the value is not 2XX,
> indicates any error happen.
> +  //    NOTE: If there is any error message returned from server, it will be
> returned in
> +  //          Payload within RedResponse.
> +  //
> +  if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \
> +      (*(RedResponse->StatusCode) >
> HTTP_STATUS_206_PARTIAL_CONTENT))
> + {
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +ON_EXIT:
> +  if (JsonValue != NULL) {
> +    RedResponse->Payload = createRedfishPayload (JsonValue,
> RedfishService);
> +    if (RedResponse->Payload == NULL) {
> +      //
> +      // Ignore the error when create RedfishPayload, just free the JsonValue
> since it's not what
> +      // we care about if the returned StatusCode is 2XX.
> +      //
> +      JsonValueFree (JsonValue);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +
>  /**
>    Use HTTP POST to create a new resource in target payload.
> 
> @@ -738,6 +836,97 @@ ON_EXIT:
>    return Status;
>  }
> 
> +
> +/**
> +  Use HTTP DELETE to remove a resource.
> +
> +  This function uses the RedfishService to remove a Redfish resource
> + which is addressed  by input Uri (only the relative path is required).
> + The corresponding redfish response will  returned, including HTTP
> + StatusCode, Headers and Payload which record any HTTP response
> messages.
> +
> +  Callers are responsible for freeing the HTTP StatusCode, Headers and
> + Payload returned in  redfish response data.
> +
> +  @param[in]    RedfishService        The Service to access the Redfish
> resources.
> +  @param[in]    Uri                   Relative path to address the resource.
> +  @param[in]    Content               JSON represented properties to be deleted.
> +  @param[out]   RedResponse           Pointer to the Redfish response data.
> +
> +  @retval EFI_SUCCESS             The opeartion is successful, indicates the HTTP
> StatusCode is not
> +                                  NULL and the value is 2XX, the Redfish resource has been
> removed.
> +                                  If there is any message returned from server, it will be
> returned
> +                                  in Payload within RedResponse.
> +  @retval EFI_INVALID_PARAMETER   RedfishService, Uri, or RedResponse is
> NULL.
> +  @retval EFI_DEVICE_ERROR        An unexpected system or network error
> occurred. Callers can get
> +                                  more error info from returned HTTP StatusCode, Headers
> and Payload
> +                                  within RedResponse:
> +                                  1. If the returned StatusCode is NULL, indicates any error
> happen.
> +                                  2. If the returned StatusCode is not NULL and the value is
> not 2XX,
> +                                     indicates any error happen.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishDeleteByUriEx (
> +  IN     REDFISH_SERVICE   RedfishService,
> +  IN     CONST CHAR8       *Uri,
> +  IN     CONST CHAR8       *Content,
> +  OUT    REDFISH_RESPONSE  *RedResponse
> +  )
> +{
> +  EFI_STATUS        Status;
> +  EDKII_JSON_VALUE  JsonValue;
> +
> +  Status    = EFI_SUCCESS;
> +  JsonValue = NULL;
> +
> +  if ((RedfishService == NULL) || (Content == NULL) || (Uri == NULL) ||
> (RedResponse == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE));
> +
> +  JsonValue = (EDKII_JSON_VALUE)deleteUriFromServiceEx (
> +                                  RedfishService,
> +                                  Uri,
> +                                  Content,
> +                                  &(RedResponse->StatusCode)
> +                                  );
> +
> +  //
> +  // 1. If the returned StatusCode is NULL, indicates any error happen.
> +  //
> +  if (RedResponse->StatusCode == NULL) {
> +    Status = EFI_DEVICE_ERROR;
> +    goto ON_EXIT;
> +  }
> +
> +  //
> +  // 2. If the returned StatusCode is not NULL and the value is not 2XX,
> indicates any error happen.
> +  //    NOTE: If there is any error message returned from server, it will be
> returned in
> +  //          Payload within RedResponse.
> +  //
> +  if ((*(RedResponse->StatusCode) < HTTP_STATUS_200_OK) || \
> +      (*(RedResponse->StatusCode) >
> HTTP_STATUS_206_PARTIAL_CONTENT))
> + {
> +    Status = EFI_DEVICE_ERROR;
> +  }
> +
> +ON_EXIT:
> +  if (JsonValue != NULL) {
> +    RedResponse->Payload = createRedfishPayload (JsonValue,
> RedfishService);
> +    if (RedResponse->Payload == NULL) {
> +      //
> +      // Ignore the error when create RedfishPayload, just free the JsonValue
> since it's not what
> +      // we care about if the returned StatusCode is 2XX.
> +      //
> +      JsonValueFree (JsonValue);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
>  /**
>    Dump text in fractions.
> 
> diff --git
> a/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfishServic
> e.h
> b/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfishServic
> e.h
> index 5c13b68..75afadc 100644
> ---
> a/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfishServic
> e.h
> +++ b/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfis
> +++ hService.h
> @@ -129,6 +129,14 @@ deleteUriFromService (
>    EFI_HTTP_STATUS_CODE  **StatusCode
>    );
> 
> +json_t *
> +deleteUriFromServiceEx (
> +  redfishService        *service,
> +  const char            *uri,
> +  const char            *content,
> +  EFI_HTTP_STATUS_CODE  **StatusCode
> +  );
> +
>  redfishPayload *
>  getRedfishServiceRoot (
>    redfishService        *service,
> diff --git a/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/service.c
> b/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/service.c
> index afa172b..086e04a 100644
> --- a/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/service.c
> +++ b/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/service.c
> @@ -923,10 +923,12 @@ ON_EXIT:
>    return ret;
>  }
> 
> +
>  json_t *
> -deleteUriFromService (
> +deleteUriFromServiceEx (
>    redfishService        *service,
>    const char            *uri,
> +  const char            *content,
>    EFI_HTTP_STATUS_CODE  **StatusCode
>    )
>  {
> @@ -937,6 +939,8 @@ deleteUriFromService (
>    EFI_HTTP_REQUEST_DATA  *RequestData = NULL;
>    EFI_HTTP_MESSAGE       *RequestMsg  = NULL;
>    EFI_HTTP_MESSAGE       ResponseMsg;
> +  CHAR8                  ContentLengthStr[80];
> +  size_t                 contentLength;
> 
>    ret = NULL;
> 
> @@ -956,7 +960,7 @@ deleteUriFromService (
>    //
>    // Step 1: Create HTTP request message with 4 headers:
>    //
> -  HttpIoHeader = HttpIoCreateHeader ((service->sessionToken || service-
> >basicAuthStr) ? 5 : 4);
> +  HttpIoHeader = HttpIoCreateHeader ((service->sessionToken ||
> + service->basicAuthStr) ? 8 : 7);
>    if (HttpIoHeader == NULL) {
>      ret = NULL;
>      goto ON_EXIT;
> @@ -979,6 +983,23 @@ deleteUriFromService (
>    Status = HttpIoSetHeader (HttpIoHeader, "Connection", "Keep-Alive");
>    ASSERT_EFI_ERROR (Status);
> 
> +  Status = HttpIoSetHeader (HttpIoHeader, "Content-Type",
> + "application/json");  ASSERT_EFI_ERROR (Status);
> +
> +  if(content != NULL){
> +      contentLength = strlen (content);
> +      AsciiSPrint (
> +        ContentLengthStr,
> +        sizeof (ContentLengthStr),
> +        "%lu",
> +        (UINT64)contentLength
> +        );
> +      Status = HttpIoSetHeader (HttpIoHeader, "Content-Length",
> ContentLengthStr);
> +      ASSERT_EFI_ERROR (Status);
> +      Status = HttpIoSetHeader (HttpIoHeader, "OData-Version", "4.0");
> +      ASSERT_EFI_ERROR (Status);
> +  }
> +
>    //
>    // Step 2: build the rest of HTTP request info.
>    //
> @@ -1004,6 +1025,11 @@ deleteUriFromService (
>    RequestMsg->HeaderCount  = HttpIoHeader->HeaderCount;
>    RequestMsg->Headers      = HttpIoHeader->Headers;
> 
> +  if(content != NULL){
> +      RequestMsg->BodyLength   = contentLength;
> +      RequestMsg->Body         = (VOID *)content;
> +  }
> +
>    ZeroMem (&ResponseMsg, sizeof (ResponseMsg));
> 
>    //
> @@ -1057,6 +1083,17 @@ ON_EXIT:
>    return ret;
>  }
> 
> +json_t *
> +deleteUriFromService (
> +  redfishService        *service,
> +  const char            *uri,
> +  EFI_HTTP_STATUS_CODE  **StatusCode
> +  )
> +{
> +  return deleteUriFromServiceEx(service, uri, NULL, StatusCode); }
> +
> +
>  redfishPayload *
>  getRedfishServiceRoot (
>    redfishService        *service,
> --
> 2.6.1.windows.1
> -The information contained in this message may be confidential and
> proprietary to American Megatrends (AMI). This communication is intended
> to be read only by the individual or entity to whom it is addressed or by their
> designee. If the reader of this message is not the intended recipient, you are
> on notice that any distribution of this message, in any form, is strictly
> prohibited. Please promptly notify the sender by reply e-mail or by
> telephone at 770-246-8600, and then delete or destroy all copies of the
> transmission.

      reply	other threads:[~2022-08-19  7:52 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-18 19:41 [PATCH V4 3/3] RedfishPkg: Redfish functions for REST requests are not fully spec complied Igor Kulchytskyy
2022-08-19  7:52 ` Chang, Abner [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=MN2PR12MB3966B8FE16C12F79FBA8A13DEA6C9@MN2PR12MB3966.namprd12.prod.outlook.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox