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

Optional status details #105

Merged
merged 2 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/doxygen/include/size_table.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
</tr>
<tr>
<td>jobs.c</td>
<td><center>2.8K</center></td>
<td><center>2.5K</center></td>
<td><center>2.9K</center></td>
<td><center>2.6K</center></td>
</tr>
<tr>
<td>job_parser.c</td>
Expand All @@ -29,7 +29,7 @@
</tr>
<tr>
<td><b>Total estimates</b></td>
<td><b><center>6.8K</center></b></td>
<td><b><center>6.0K</center></b></td>
<td><b><center>6.9K</center></b></td>
<td><b><center>6.1K</center></b></td>
</tr>
</table>
61 changes: 45 additions & 16 deletions source/include/jobs.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@
#define JOBS_API_EXPECTED_VERSION "\",\"expectedVersion\":\""
#define JOBS_API_EXPECTED_VERSION_LENGTH ( sizeof( JOBS_API_EXPECTED_VERSION ) - 1U )

#define JOBS_API_STATUS_DETAILS "\",\"statusDetails\":\""
#define JOBS_API_STATUS_DETAILS_LENGTH ( sizeof( JOBS_API_STATUS_DETAILS ) - 1U )

#define JOBS_API_COMMON_LENGTH( thingNameLength ) \
( JOBS_API_PREFIX_LENGTH + ( thingNameLength ) + JOBS_API_BRIDGE_LENGTH )

Expand Down Expand Up @@ -314,6 +317,32 @@ typedef enum
JobsMaxTopic
} JobsTopic_t;

/**
* @ingroup jobs_struct_types
* @brief Structure for Jobs_UpdateMsg request parameters.
*
* @note For optional fields setting a pointer to NULL or
* the length to 0U will disable this field from being used.
*
*
* @note Optional fields include:
* * expectedVersion
* * expectedVersionLength
* * statusDetails
* * statusDetailsLength
*
* @note The status details must be a JSON formatted key-value
* pair.
*/
typedef struct
{
JobCurrentStatus_t status; /**< Status to update the job to. */
const char * expectedVersion; /**< Expected version, optional. */
size_t expectedVersionLength; /**< Expected version length, optional. */
const char * statusDetails; /**< JSON key-value pair, optional. */
size_t statusDetailsLength; /**< JSON key-value pair length, optional. */
} JobsUpdateRequest_t;

/*-----------------------------------------------------------*/

/**
Expand Down Expand Up @@ -838,31 +867,33 @@ JobsStatus_t Jobs_Update( char * buffer,
/**
* @brief Populate a message string for an UpdateJobExecution request.
*
* @param status Current status of the job
* @param expectedVersion The version that is expected, NULL if no version is expected
* @param expectedVersionLength The length of the expectedVersion string, 0U if no version is expected
* @param buffer The buffer to be written to
* @param bufferSize the size of the buffer
* @param request A jobs update request structure.
* @param buffer The buffer to be written to.
* @param bufferSize the size of the buffer.
*
* @return 0 if write to buffer fails
* @return messageLength if the write is successful
* @return 0 if write to buffer fails.
* @return messageLength if the write is successful.
*
* <b>Example</b>
* @code{c}
*
* // The Following Example shows usage of the Jobs_UpdateMsg API to
* // generate a message string for the UpdateJobExecution API
* // of the AWS IoT Jobs Service
* // of the AWS IoT Jobs Service.
*
* const char * expectedVersion = "2";
* size_t expectedVersionLength = ( sizeof(expectedVersion ) - 1U );
* JobCurrentStatus_t status = Succeeded;
* const chat * statusDetails = "{\"key\":\"value\"}";
* char messageBuffer[ UPDATE_JOB_MSG_LENGTH ] = {0};
* size_t messageLength = 0U;
*
* messageLength = Jobs_UpdateMsg( status,
* expectedVersion,
* expectedVersionLength,
* JobsUpdateRequest_t request;
* request.status = Succeeded;
* request.expectedVersion = expectedVersion;
* request.expectedVersionLength = ( sizeof( expectedVersion ) - 1U );
* request.statusDetails = statusDetails;
* request.statusDetailsLength = ( sizeof( statusDetails ) - 1U );
*
* messageLength = Jobs_UpdateMsg( request
* messageBuffer,
* UPDATE_JOB_MSG_LENGTH );
*
Expand All @@ -876,9 +907,7 @@ JobsStatus_t Jobs_Update( char * buffer,
* @endcode
*/
/* @[declare_jobs_updatemsg] */
size_t Jobs_UpdateMsg( JobCurrentStatus_t status,
const char * expectedVersion,
size_t expectedVersionLength,
size_t Jobs_UpdateMsg( JobsUpdateRequest_t request,
char * buffer,
size_t bufferSize );
/* @[declare_jobs_updatemsg] */
Expand Down
107 changes: 77 additions & 30 deletions source/jobs.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ static const size_t apiTopicLength[] =
JOBS_API_UPDATE_LENGTH + JOBS_API_FAILURE_LENGTH,
};

static const char * const jobStatusString[] =
{
"QUEUED",
"IN_PROGRESS",
"FAILED",
"SUCCEEDED",
"REJECTED"
};

/**
* @brief Predicate returns true for a valid thing name or job ID character.
*
Expand Down Expand Up @@ -813,53 +822,91 @@ JobsStatus_t Jobs_Update( char * buffer,
return ret;
}

size_t Jobs_UpdateMsg( JobCurrentStatus_t status,
const char * expectedVersion,
size_t expectedVersionLength,
char * buffer,
size_t bufferSize )
/**
* @brief Get the total length of optional fields provided for
* the Jobs_UpdateMsg. These optional fields, if provided, require
* additional buffer space.
*
* @param request A JobsUpdateRequest_t containing the optional fields.
* @return size_t The buffer space required for the optional fields.
*/
static size_t getOptionalFieldsLength( JobsUpdateRequest_t request )
{
static const char * const jobStatusString[] =
size_t minimumOptionalFieldsBufferSize = 0U;

if( ( request.expectedVersion != NULL ) && ( request.expectedVersionLength > 0U ) )
{
"QUEUED",
"IN_PROGRESS",
"FAILED",
"SUCCEEDED",
"REJECTED"
};
minimumOptionalFieldsBufferSize += JOBS_API_EXPECTED_VERSION_LENGTH + request.expectedVersionLength;
}

static const size_t jobStatusStringLengths[] =
if( ( request.statusDetails != NULL ) && ( request.statusDetailsLength ) )
{
CONST_STRLEN( "QUEUED" ),
CONST_STRLEN( "IN_PROGRESS" ),
CONST_STRLEN( "FAILED" ),
CONST_STRLEN( "SUCCEEDED" ),
CONST_STRLEN( "REJECTED" )
};
minimumOptionalFieldsBufferSize += JOBS_API_STATUS_DETAILS_LENGTH + request.statusDetailsLength;
}

assert( ( ( size_t ) status ) < ARRAY_LENGTH( jobStatusString ) );
return minimumOptionalFieldsBufferSize;
}

size_t start = 0U;
size_t minimumBufferSize = JOBS_API_STATUS_LENGTH + jobStatusStringLengths[ status ] + CONST_STRLEN( "\"}" );
/**
* @brief Get the total length of the required fields in the
* Jobs_UpdateMsg request.
*
* @param request A JobsUpdateRequest_t containing the optional fields.
* @return size_t The buffer space required for the optional fields.
*/
static size_t getRequiredFieldsLength( JobsUpdateRequest_t request )
{
return JOBS_API_STATUS_LENGTH + strlen( jobStatusString[ request.status ] ) + CONST_STRLEN( "\"}" );
}

if( ( expectedVersion != NULL ) && ( expectedVersionLength > 0U ) )
/**
* @brief Check non-null optional fields in the Jobs_UpdateMsg request
* for validity.
*
* @param request A JobsUpdateRequest_t containing the optional fields.
* @return true Optional fields appear valid.
* @return false Optional fields are invalid.
*/
static bool areOptionalFieldsValid( JobsUpdateRequest_t request )
{
bool optionalFieldsValid = true;

if( ( request.statusDetails != NULL ) && ( request.statusDetailsLength ) )
{
minimumBufferSize += JOBS_API_EXPECTED_VERSION_LENGTH + expectedVersionLength;
optionalFieldsValid &= ( JSONSuccess == JSON_Validate( request.statusDetails, request.statusDetailsLength ) );
}

bool writeFailed = bufferSize < minimumBufferSize;
return optionalFieldsValid;
}

size_t Jobs_UpdateMsg( JobsUpdateRequest_t request,
char * buffer,
size_t bufferSize )
{
assert( ( ( size_t ) request.status ) < ARRAY_LENGTH( jobStatusString ) );

size_t start = 0U;
size_t minimumBufferSize = getRequiredFieldsLength( request ) + getOptionalFieldsLength( request );
bool writeFailed = bufferSize < minimumBufferSize || !areOptionalFieldsValid( request );

if( !writeFailed && ( jobStatusString[ status ] != NULL ) )
if( !writeFailed )
{
( void ) strnAppend( buffer, &start, bufferSize, JOBS_API_STATUS, JOBS_API_STATUS_LENGTH );
( void ) strnAppend( buffer, &start, bufferSize, jobStatusString[ status ], jobStatusStringLengths[ status ] );
( void ) strnAppend( buffer, &start, bufferSize, jobStatusString[ request.status ], strlen( jobStatusString[ request.status ] ) );
}

/* This is an optional field so do not fail if expected version is missing */
if( !writeFailed && ( expectedVersion != NULL ) && ( expectedVersionLength > 0U ) )
/* This is an optional field so do not fail if expected version is missing.*/
if( !writeFailed && ( request.expectedVersion != NULL ) && ( request.expectedVersionLength > 0U ) )
{
( void ) strnAppend( buffer, &start, bufferSize, JOBS_API_EXPECTED_VERSION, JOBS_API_EXPECTED_VERSION_LENGTH );
( void ) strnAppend( buffer, &start, bufferSize, expectedVersion, expectedVersionLength );
( void ) strnAppend( buffer, &start, bufferSize, request.expectedVersion, request.expectedVersionLength );
}

/* This is an optional field so do not fail if status details is missing.*/
if( !writeFailed && ( request.statusDetails != NULL ) && ( request.statusDetailsLength > 0U ) )
{
( void ) strnAppend( buffer, &start, bufferSize, JOBS_API_STATUS_DETAILS, JOBS_API_STATUS_DETAILS_LENGTH );
( void ) strnAppend( buffer, &start, bufferSize, request.statusDetails, request.statusDetailsLength );
}

if( !writeFailed )
Expand Down
Loading
Loading