src/utils/workflow_utils/inc/aduc/workflow_utils.h (123 lines of code) (raw):
/**
* @file workflow_utils.h
* @brief Util functions for ADUC_Workflow data.
*
* @copyright Copyright (c) Microsoft Corporation.
* Licensed under the MIT License.
*/
#ifndef ADUC_WORKFLOW_UTILS_H
#define ADUC_WORKFLOW_UTILS_H
#include "aduc/adu_types.h"
#include "aduc/result.h"
#include "aduc/types/update_content.h"
#include "aduc/types/workflow.h"
#include <azure_c_shared_utility/strings.h>
#include <stdbool.h>
#include <string.h> // strlen
#include <sys/types.h> // ino_t
EXTERN_C_BEGIN
// fwd declaration
typedef void* ADUC_WorkflowHandle;
//
// Initialization.
//
/**
* @brief Instantiate and initialize workflow object with info from @p updateManifestJson
*
* @param updateManifestJson A json string containing an update manifest data.
* @param validateManifest A indicates whether to validate the manifest signature.
* Note that a referenced step manifest file doesn't contain a signature. We sign at the top level.
* @param handle A workflow object handle with information about the workflow.
* @return ADUC_Result
*/
ADUC_Result workflow_init(const char* updateManifestJson, bool validateManifest, ADUC_WorkflowHandle* handle);
/**
* @brief Instantiate and initialize workflow object with info from specified file.
*
* @param updateManifestFile Full path to a file containing an update manifest data.
* @param validateManifest A boolean indicates whether to validate the manifest signature.
* @param handle A workflow object handle with information about the workflow.
* @return ADUC_Result
*/
ADUC_Result
workflow_init_from_file(const char* updateManifestFile, bool validateManifest, ADUC_WorkflowHandle* handle);
/**
* @brief Instantiate and initialize workflow object with info from the @p sourceHandle inline step.
*
* @param base A source workflow object.
* @param stepIndex A step index.
* @param handle A workflow object handle with information about the workflow.
* @return ADUC_Result
*/
ADUC_Result workflow_create_from_inline_step(ADUC_WorkflowHandle base, size_t stepIndex, ADUC_WorkflowHandle* handle);
/**
* @brief Transfer action data from @p sourceHandle to @p targetHandle.
* The sourceHandle will no longer contains transferred action data.
* Caller should not use sourceHandle for other workflow related purposes.
*
* @param targetHandle A target workflow object.
* @param sourceHandle A source workflow object.
* @return Returns true if succeeded, or false if failed.
*/
bool workflow_transfer_data(ADUC_WorkflowHandle targetHandle, ADUC_WorkflowHandle sourceHandle);
/**
* @brief Deep copy string. Caller must call workflow_free_string() when done.
*
* @param s Input string.
* @return A copy of input string if succeeded. Otherwise, return NULL.
*/
char* workflow_copy_string(const char* s);
/**
* @brief Free text buffer returned by workflow_get_* APIs.
*
* @param string
*/
void workflow_free_string(char* string);
/**
* @brief Free workflow content.
*
* @param handle A workflow object handle.
*/
void workflow_uninit(ADUC_WorkflowHandle handle);
/**
* @brief Free workflow content and dealloc workflow object.
*
* @param handle A workflow data object handle.
*/
void workflow_free(ADUC_WorkflowHandle handle);
//
// Property setters and getters.
//
/**
* @brief Get Update Action.
*
* @param handle A workflow data object handle.
* @return ADUCITF_UpdateAction
*/
ADUCITF_UpdateAction workflow_get_action(ADUC_WorkflowHandle handle);
/**
* @brief Get Update Type.
*
* @param handle A workflow data object handle.
* @return const char* A current workflow update type.
*/
char* workflow_get_update_type(ADUC_WorkflowHandle handle);
/**
* @brief Gets the update type of the specified workflow.
*
* @param handle A workflow object handle.
* @return An UpdateType string. Caller does not own the string so must not free it.
*/
const char* workflow_peek_update_type(ADUC_WorkflowHandle handle);
/**
* @brief gets the current workflow step.
*
* @param handle A workflow data object handle.
* @return the workflow step.
*/
ADUCITF_WorkflowStep workflow_get_current_workflowstep(ADUC_WorkflowHandle handle);
/**
* @brief sets the current workflow step.
*
* @param handle A workflow data object handle.
* @param workflowStep The workflow step.
*/
void workflow_set_current_workflowstep(ADUC_WorkflowHandle handle, ADUCITF_WorkflowStep workflowStep);
/**
* @brief Explicit set workflow id for this workflow.
*
* @param handle A workflow data object handle.
* @param id
* @return Return true if succeeded.
*/
bool workflow_set_id(ADUC_WorkflowHandle handle, const char* id);
/**
* @brief Get the workflow id.
*
* @param handle A workflow data object handle.
* @return char* contains workflow id. Caller must call workflow_free_string() to free the memory once done.
*/
char* workflow_get_id(ADUC_WorkflowHandle handle);
/**
* @brief Get a read-only workflow id.
*
* @param handle A workflow data object handle.
* @return Return the workflow id.
*/
const char* workflow_peek_id(ADUC_WorkflowHandle handle);
/**
* @brief Explicit set workflow retryTimestamp for this workflow.
*
* @param handle A workflow data object handle.
* @param retryTimestamp The retryTimestamp
* @return Return true if succeeded.
*/
bool workflow_set_retryTimestamp(ADUC_WorkflowHandle handle, const char* retryTimestamp);
/**
* @brief Get a read-only workflow retryTimestamp.
*
* @param handle A workflow data object handle.
* @return Return the workflow retryTimestamp. Returns null if retryTimestamp did not exist in service request.
*/
const char* workflow_peek_retryTimestamp(ADUC_WorkflowHandle handle);
/**
* @brief Set a work folder (a.k.a, sandbox) for this workflow.
*
* @param handle A workflow data object handle.
* @param format A format string for work folder path.
* @param ... An argument list.
* @return Return true is succeeded.
*/
bool workflow_set_workfolder(ADUC_WorkflowHandle handle, const char* format, ...);
/**
* @brief Get the work folder for this workflow.
*
* @param handle A workflow data object handle.
* @return char* contains full path to work folder. Caller must call workflow_free_string() to free the memory once done.
*/
char* workflow_get_workfolder(const ADUC_WorkflowHandle handle);
/**
* @brief Get the base directory for this workflow.
* @details The base directory is the parent directory of the work folder.
* @param handle A workflow data object handle.
* @return char* contains full path to work folder. Caller must call workflow_free_string() to free the memory once done.
*/
char* workflow_get_root_sandbox_dir(const ADUC_WorkflowHandle handle);
/**
* @brief Sets selected-components (in a form of serialized json string) to be used in this workflow.
*
* @param handle A workflow data object handle.
* @param selectedComponents Json string contains one or more components.
* @return Returns true if succeeded.
*/
bool workflow_set_selected_components(ADUC_WorkflowHandle handle, const char* selectedComponents);
/**
* @brief Gets a reference to the selected-components JSON string.
*
* @param handle A workflow data object handle.
* @return const char* Contain selected-components JSON. Caller must not free this string.
*/
const char* workflow_peek_selected_components(ADUC_WorkflowHandle handle);
/**
* @brief Gets the update files count.
*
* @param handle A workflow data object handle.
* @return size_t Total files count.
*/
size_t workflow_get_update_files_count(ADUC_WorkflowHandle handle);
/**
* @brief Gets the update file entity at the specified index.
*
* @param handle A workflow data object handle.
* @param index An index of the file to get.
* @param entity An output file entity object. Caller must uninitialize it via ADUC_FileEntity_Uninit when done.
* @return true on success.
*/
bool workflow_get_update_file(ADUC_WorkflowHandle handle, size_t index, ADUC_FileEntity* entity);
/**
* @brief Gets the update file entity by name.
*
* @param[in] handle A workflow data object handle.
* @param[in] fileName File name.
* @param[out] entity An output file entity object. Caller must uninitialize it via ADUC_FileEntity_Uninit().
* @return true on success.
*/
bool workflow_get_update_file_by_name(ADUC_WorkflowHandle handle, const char* fileName, ADUC_FileEntity* entity);
/**
* @brief Gets the inode associated with the update file entity at the specified index.
*
* @param handle A workflow data object handle.
* @param index An index of the file to get.
* @return ino_t The inode, or ADUC_INODE_SENTINEL_VALUE if inode has not been set yet.
*/
ino_t workflow_get_update_file_inode(ADUC_WorkflowHandle handle, size_t index);
/**
* @brief Sets the inode associated with the update file entity at the specified index.
*
* @param handle A workflow data object handle.
* @param index An index of the file to get.
* @param inode The inode.
* @return bool true on success.
*/
bool workflow_set_update_file_inode(ADUC_WorkflowHandle handle, size_t index, ino_t inode);
/**
* @brief Gets a bundle updates count.
*
* @param handle A workflow data object handle.
* @return size_t Total bundle updates count.
*/
size_t workflow_get_bundle_updates_count(ADUC_WorkflowHandle handle);
/**
* @brief Gets a bundle update file at specified index.
*
* @param[in] handle A workflow data object handle.
* @param[in] index An index of the file to get.
* @param[out] entity An output file entity object.
* @return true on success.
*/
bool workflow_get_bundle_updates_file(ADUC_WorkflowHandle handle, size_t index, ADUC_FileEntity* entity);
/**
* @brief Get an Update Manifest property (string) without copying the value.
* Caller must not free the pointer.
*
* @param handle A workflow data object handle.
* @param[in] propertyName Name of the property to get.
* @return const char* A reference to property value. Caller must not free this pointer.
*/
const char* workflow_peek_update_manifest_string(ADUC_WorkflowHandle handle, const char* propertyName);
/**
* @brief Get a property of type 'string' in the workflow update manifest.
*
* @param handle A workflow object handle.
* @param propertyName The name of a property to get.
*
* @return A copy of specified property. Caller must call workflow_free_string when done with the value.
*/
char* workflow_get_update_manifest_string_property(ADUC_WorkflowHandle handle, const char* propertyName);
/**
* @brief Get a 'Compatibility' entry of the workflow at a specified @p index.
*
* @param handle A workflow object handle.
* @param index Index of the compatibility set to.
*
* @return A copy of compatibility entry. Caller must call workflow_free_string when done with the value.
*/
char* workflow_get_update_manifest_compatibility(ADUC_WorkflowHandle handle, size_t index);
/**
* @brief Get update manifest version.
*
* @param handle A workflow object handle.
*
* @return int The manifest version number. Return -1, if failed.
*/
int workflow_get_update_manifest_version(ADUC_WorkflowHandle handle);
/**
* @brief Return an update id of this workflow.
* This id should be reported to the cloud once the update installed successfully.
*
* @param handle A workflow object handle.
* @param[out] updateId A pointer to the output ADUC_UpdateId struct.
* Must call 'workflow_free_update_id' function to free the memory when done.
*
* @return ADUC_Result Return ADUC_GeneralResult_Success if success. Otherwise, return ADUC_GeneralResult_Failure with extendedResultCode.
*/
ADUC_Result workflow_get_expected_update_id(ADUC_WorkflowHandle handle, ADUC_UpdateId** updateId);
/**
* @brief Return an update id of this workflow.
* This id should be reported to the cloud once the update installed successfully.
*
* @param handle A workflow object handle.
*
* @return char* Expected update id string.
* Caller must call 'workflow_free_string' function to free the memory when done.
*/
char* workflow_get_expected_update_id_string(ADUC_WorkflowHandle handle);
/**
* @brief Get installed-criteria string from this workflow.
* @param handle A workflow object handle.
* @return Returns installed-criteria string.
* Caller must call 'workflow_free_string' function to free the memory when done.
*/
char* workflow_get_installed_criteria(ADUC_WorkflowHandle handle);
/**
* @brief Get the Update Manifest 'compatibility' array, in serialized json string format.
*
* @param handle A workflow handle.
* @return char* If success, returns a serialized json string. Otherwise, returns NULL.
* Caller must call 'workflow_free_string' function to free the memory when done.
*/
char* workflow_get_compatibility(ADUC_WorkflowHandle handle);
/**
* @brief Free memory allocated for @p updateId.
*
* @param updateId Update Id object to free.
*/
void workflow_free_update_id(ADUC_UpdateId* updateId);
void workflow_set_operation_in_progress(ADUC_WorkflowHandle handle, bool inProgress);
bool workflow_get_operation_in_progress(ADUC_WorkflowHandle handle);
void workflow_set_operation_cancel_requested(ADUC_WorkflowHandle handle, bool cancel);
bool workflow_get_operation_cancel_requested(ADUC_WorkflowHandle handle);
void workflow_clear_inprogress_and_cancelrequested(ADUC_WorkflowHandle handle);
//
// Tree
//
/**
* @brief Get root workflow object handle.
*
* @param handle A workflow data object handle.
* @return ADUC_WorkflowHandle A root workflow object handle. If @p handle doesn't have parent, return NULL.
*/
ADUC_WorkflowHandle workflow_get_root(ADUC_WorkflowHandle handle);
/**
* @brief Get parent workflow object handle of @p handle.
*
* @param handle A workflow data object handle.
* @return ADUC_WorkflowHandle A parent workflow object handle.
*/
ADUC_WorkflowHandle workflow_get_parent(ADUC_WorkflowHandle handle);
/**
* @brief Get child workflow count. For example, for Bundle Update, this is a count of
* Leaf (Components) Updates. For Leaf (Components) Update, this is a count of 'InstallItems'.
*
* @param handle A workflow data object handle.
* @return A total count of child workflows.
*/
size_t workflow_get_children_count(ADUC_WorkflowHandle handle);
/**
* @brief Get child workflow at specified @p index.
* Note: To get the last child, pass (-1) index.
*
* @param handle A workflow data object handle.
* @param index Index of child to get.
* @return ADUC_WorkflowHandle A child workflow object handle.
*/
ADUC_WorkflowHandle workflow_get_child(ADUC_WorkflowHandle handle, size_t index);
/**
* @brief Insert @p childHandle into @p handle children list.
*
* The @p childHandle will be freed when @p handle is free using workflow_free() function.
*
* The @p childHandler's level will be set to ( @p handle's level + 1 ).
*
* @param handle A parent workflow object handle.
* @param index An index indicate the location the @p childHandle will be inserted at.
* To insert at the end of the list, pass '-1'.
* @param childHandle A child workflow object handle.
* @return true on success.
*/
bool workflow_insert_child(ADUC_WorkflowHandle handle, int index, ADUC_WorkflowHandle childHandle);
// If success, returns removed file.
// Note: to remove the last child, pass (-1) index.
ADUC_WorkflowHandle workflow_remove_child(ADUC_WorkflowHandle handle, int index);
//
// State
//
bool workflow_set_state(ADUC_WorkflowHandle handle, ADUCITF_State state);
ADUCITF_State workflow_get_root_state(ADUC_WorkflowHandle handle);
ADUCITF_State workflow_get_state(ADUC_WorkflowHandle handle);
ADUC_Result workflow_get_result(ADUC_WorkflowHandle handle);
void workflow_set_result(ADUC_WorkflowHandle handle, ADUC_Result result);
void workflow_add_erc(ADUC_WorkflowHandle handle, ADUC_Result_t erc);
STRING_HANDLE workflow_get_extra_ercs(ADUC_WorkflowHandle handle);
/**
* @brief Set workflow resultDetails string.
*
* @param handle A workflow object handle.
* @param format A string format.
* @param ... Arguments.
*/
void workflow_set_result_details(ADUC_WorkflowHandle handle, const char* format, ...);
/**
* @brief Get a reference of the workflow result details string.
*
* @param handle A workflow data object handle.
* @return const char* A reference to result details string. Caller must not free this pointer.
*/
const char* workflow_peek_result_details(ADUC_WorkflowHandle handle);
void workflow_set_installed_update_id(ADUC_WorkflowHandle handle, const char* installedUpdateId);
const char* workflow_peek_installed_update_id(ADUC_WorkflowHandle handle);
bool workflow_read_state_from_file(ADUC_WorkflowHandle handle, const char* stateFilename);
/**
* @brief Request a workflow cancellation.
*
* @param handle A workflow data object handle.
* @return A boolean indicates that the 'WORKFLOW_PROPERTY_FIELD_CANCEL_REQUESTED' property successfully set to 'true'.
*/
bool workflow_request_cancel(ADUC_WorkflowHandle handle);
/**
* @brief Check whether the workflow cancellation is requested.
*
* @param handle A workflow data object handle.
* @return A boolean indicates whether the workflow cancellation is requested.
*/
bool workflow_is_cancel_requested(ADUC_WorkflowHandle handle);
/**
* @brief Request the agent to restart after the top level workflow is finished.
*
* @param handle A workflow data object handle.
* @return 'True' if request success.
*/
bool workflow_request_agent_restart(ADUC_WorkflowHandle handle);
/**
* @brief Request the agent to restart immediately after current operation (e.g., download, install, or apply) is finished.
*
* @param handle A workflow data object handle.
* @return 'True' if request success.
*/
bool workflow_request_immediate_agent_restart(ADUC_WorkflowHandle handle);
/**
* @brief Check whether the agent restart is requested.
*
* @param handle A workflow data object handle.
* @return A boolean indicates whether the agent restart is requested.
*/
bool workflow_is_agent_restart_requested(ADUC_WorkflowHandle handle);
/**
* @brief Check whether the agent immediate restart is requested.
*
* @param handle A workflow data object handle.
* @return A boolean indicates whether the agent immediate restart is requested.
*/
bool workflow_is_immediate_agent_restart_requested(ADUC_WorkflowHandle handle);
/**
* @brief Request the agent to reboot the device after the top level workflow is finished.
*
* @param handle A workflow data object handle.
* @return 'True' if request success.
*/
bool workflow_request_reboot(ADUC_WorkflowHandle handle);
/**
* @brief Request the agent to reboot the device immediately after current operation (e.g., download, install, or apply) is finished.
*
* @param handle A workflow data object handle.
* @return 'True' if request success.
*/
bool workflow_request_immediate_reboot(ADUC_WorkflowHandle handle);
/**
* @brief Check whether the device reboot is requested.
*
* @param handle A workflow data object handle.
* @return A boolean indicates whether the device reboot is requested.
*/
bool workflow_is_reboot_requested(ADUC_WorkflowHandle handle);
/**
* @brief Check whether the immediate device reboot is requested.
*
* @param handle A workflow data object handle.
* @return A boolean indicates whether the immediate device reboot is requested.
*/
bool workflow_is_immediate_reboot_requested(ADUC_WorkflowHandle handle);
/**
* @brief Set workflow cancellation type.
*
* @param handle A workflow data object handle.
* @param cancellationType A cancellation type.
*/
void workflow_set_cancellation_type(ADUC_WorkflowHandle handle, ADUC_WorkflowCancellationType cancellationType);
/**
* @brief Set workflow cancellation type.
*
* @param handle A workflow data object handle.
* @param cancellationType A cancellation type.
*/
ADUC_WorkflowCancellationType workflow_get_cancellation_type(ADUC_WorkflowHandle handle);
bool workflow_update_retry_deployment(ADUC_WorkflowHandle handle, const char* retryToken);
bool workflow_update_replacement_deployment(
ADUC_WorkflowHandle currentWorkflowHandle, ADUC_WorkflowHandle nextWorkflowHandle);
void workflow_update_for_replacement(ADUC_WorkflowHandle handle);
void workflow_update_for_retry(ADUC_WorkflowHandle handle);
//
// Misc.
//
/**
* @brief Compare id of @p handle0 and @p handle1
*
* @param handle0 The workflow handle containing the first workflow id.
* @param handle1 The workflow handle containing the second workflow id.
* @return 0 if ids are equal.
*/
int workflow_id_compare(ADUC_WorkflowHandle handle0, ADUC_WorkflowHandle handle1);
/**
* @brief Compare id of @p handle and @p workflowId. No memory is allocated or freed by this function.
*
* @param handle The handle for first workflow id.
* @param workflowId The c-string for the second workflow id.
* @return bool Returns true if ids are equal.
*/
bool workflow_isequal_id(ADUC_WorkflowHandle handle, const char* workflowId);
/**
* @brief Create a new workflow data handler using base workflow and serialized 'instruction' json string.
*
* @param base The base workflow containing valid Update Action and Manifest.
* @param instruction A serialized json string containing single 'installItem' from an instruction file.
* @param handle An output workflow object handle.
* @return ADUC_Result
*/
ADUC_Result
workflow_create_from_instruction(ADUC_WorkflowHandle base, const char* instruction, ADUC_WorkflowHandle* handle);
/**
* @brief Create a new workflow data handler using base workflow and serialized 'instruction' json string.
*
* @param base The base workflow containing valid Update Action and Manifest.
* @param instruction A JSON_Value object containing single 'installItem' from an instruction file.
* @param handle An output workflow object handle.
* @return ADUC_Result
*/
ADUC_Result
workflow_create_from_instruction_value(ADUC_WorkflowHandle base, JSON_Value* instruction, ADUC_WorkflowHandle* handle);
//
// Update Manifest Version 4
//
/**
* @brief Set workflow level.
*
* @param handle A workflow object handle.
* @param level A workflow level
*/
void workflow_set_level(ADUC_WorkflowHandle handle, int level);
/**
* @brief Set workflow step index.
*
* @param handle A workflow object handle.
* @param stepIndex A workflow step index.
*/
void workflow_set_step_index(ADUC_WorkflowHandle handle, size_t stepIndex);
/**
* @brief Get workflow level.
*
* @param handle A workflow object handle.
* @return Returns -1 if the specified handle is invalid. Otherwise, return the workflow level.
*/
int workflow_get_level(ADUC_WorkflowHandle handle);
/**
* @brief Get workflow step index.
*
* @param handle A workflow object handle.
* @return Returns -1 if the specified handle is invalid. Otherwise, return the workflow step index.
*/
int workflow_get_step_index(ADUC_WorkflowHandle handle);
/**
* @brief Get update manifest instructions steps count.
*
* @param handle A workflow object handle.
*
* @return Total count of the update instruction steps.
*/
size_t workflow_get_instructions_steps_count(ADUC_WorkflowHandle handle);
/**
* @brief Get a read-only update manifest step type
*
* @param handle A workflow object handle.
* @param stepIndex A step index.
*
* @return A step type. This can be 'inline' or 'reference'.
*/
const char* workflow_peek_step_type(ADUC_WorkflowHandle handle, size_t stepIndex);
/**
* @brief Returns whether the specified step is an 'inline' step.
*
* @param handle A workflow object handle.
* @param stepIndex A step index.
*
* @return bool Return true if the specified step exists, and is inline step.
* Otherwise, return false.
*
*/
bool workflow_is_inline_step(ADUC_WorkflowHandle handle, size_t stepIndex);
/**
* @brief Get a read-only update manifest step handler (name)
*
* @param handle A workflow object handle.
* @param stepIndex A step index.
*
* @return A step handler name.
*/
const char* workflow_peek_update_manifest_step_handler(ADUC_WorkflowHandle handle, size_t stepIndex);
/**
* @brief Get a read-only handlerProperties string value.
*
* @param handle A workflow object handle.
* @param propertyName
*
* @return A read-only string value of specified property in handlerProperties map.
* Returns NULL if specifed property doesnot exist, or not a 'string' type.
*/
const char*
workflow_peek_update_manifest_handler_properties_string(ADUC_WorkflowHandle handle, const char* propertyName);
/**
* @brief Gets a reference step update manifest file at specified index.
*
* @param[in] handle A workflow data object handle.
* @param[in] stepIndex A step index.
* @param[out] entity An output reference step update manifest file entity object.
* @return Returns true on success.
*/
bool workflow_get_step_detached_manifest_file(ADUC_WorkflowHandle handle, size_t stepIndex, ADUC_FileEntity* entity);
/**
* @brief Gets a serialized json string of the specified workflow's Update Manifest.
*
* @param handle A workflow data object handle.
* @param pretty Whether to format the output string.
* @return char* An output json string. Caller must free the string with workflow_free_string().
*/
char* workflow_get_serialized_update_manifest(ADUC_WorkflowHandle handle, bool pretty);
/**
* @brief Gets the file path of the entity target update under the download work folder sandbox.
*
* @param workflowHandle The workflow handle.
* @param entity The file entity.
* @param outFilePath The resultant work folder file path to the file entity.
* @return bool true if success
* @remark Caller will own the STRING_HANDLE outFilePath and must call STRING_delete on it.
*/
bool workflow_get_entity_workfolder_filepath(
ADUC_WorkflowHandle workflowHandle, const ADUC_FileEntity* entity, STRING_HANDLE* outFilePath);
/**
* @brief Gets boolean indicates whether to bypass duplicate workflow check, and always process the update.
*/
bool workflow_get_force_update(ADUC_WorkflowHandle workflowHandle);
/**
* @brief Sets boolean indicates whether to bypass duplicate workflow check, and always process the update.
*
* @param handle The workflow handle.
* @param forceUpdate Set to true to bypass duplicate workflow check.
*/
void workflow_set_force_update(ADUC_WorkflowHandle handle, bool forceUpdate);
/**
* @brief peeks at the properties under the "workflow" unprotected property
*
* @param updateActionJsonObj The JSON object of the update action JSON.
* @param outWorkflowUpdateAction The output parameter for receiving the value of "action" under "workflow". May be set to NULL if there was none in the JSON.
* @param outRootKeyPkgUrl_optional The output parameter for receiving the value of "rootkeyPkgUrl" unprotected property from the updateAction json. Will not be set when error result is returned or NULL is passed.
* @param outWorkflowId_optional The output parameter for receiving the value of "id" under "workflow". May be set to NULL if there was none in the JSON.
*
* @details Caller must never free workflowId.
* @returns ADUC_Result The result.
*/
ADUC_Result workflow_parse_peek_unprotected_workflow_properties(
JSON_Object* updateActionJsonObj,
ADUCITF_UpdateAction* outWorkflowUpdateAction,
char** outRootkeyPkgUrl_optional,
char** outWorkflowId_optional);
/**
* @brief Allocate and initialize a workflow handle onto the workflow Data.
*
* @param workflowData The workflow data on which to set the new workflow handle.
* @return true on success.
*/
bool workflow_init_workflow_handle(ADUC_WorkflowData* workflowData);
/**
* @brief Sets the update action json on the workflow handle
*
* @param handle The workflow handle on which to set the update action json object.
* @param jsonObj The update action json object.
* @return true on success.
*/
bool workflow_set_update_action_object(ADUC_WorkflowHandle handle, JSON_Object* jsonObj);
EXTERN_C_END
#endif // ADUC_WORKFLOW_UTILS_H