bool ADUC_ConfigInfo_Init()

in src/utils/config_utils/src/config_utils.c [326:516]


bool ADUC_ConfigInfo_Init(ADUC_ConfigInfo* config, const char* configFolder)
{
    bool succeeded = false;

    // Initialize out parameter.
    memset(config, 0, sizeof(*config));

    if (mallocAndStrcpy_s(&(config->configFolder), configFolder) != 0)
    {
        Log_Error("Failed to allocate memory for config file folder");
        return false;
    }

    char* configFilePath = NULL;

    if (IsNullOrEmpty(configFolder))
    {
        configFilePath = ADUC_StringFormat("%s/%s", ADUC_CONF_FOLDER, ADUC_CONF_FILE);
    }
    else
    {
        configFilePath = ADUC_StringFormat("%s/%s", configFolder, ADUC_CONF_FILE);
    }

    if (IsNullOrEmpty(configFilePath))
    {
        Log_Error("Failed to allocate memory for config file path");
        goto done;
    }

    config->rootJsonValue = Parse_JSON_File(configFilePath);

    if (config->rootJsonValue == NULL)
    {
        Log_Error("Failed parse of JSON file: %s", configFilePath);
        goto done;
    }

    if (!ADUC_Json_GetAgents(config->rootJsonValue, &(config->agentCount), &(config->agents)))
    {
        goto done;
    }

    config->schemaVersion = ADUC_JSON_GetStringFieldPtr(config->rootJsonValue, CONFIG_SCHEMA_VERSION);

    if (IsNullOrEmpty(config->schemaVersion))
    {
        Log_Error(INVALID_OR_MISSING_FIELD_ERROR_FMT, CONFIG_SCHEMA_VERSION);
        goto done;
    }

    config->manufacturer = ADUC_JSON_GetStringFieldPtr(config->rootJsonValue, CONFIG_MANUFACTURER);

    if (IsNullOrEmpty(config->manufacturer))
    {
        Log_Error(INVALID_OR_MISSING_FIELD_ERROR_FMT, CONFIG_MANUFACTURER);
        goto done;
    }

    config->model = ADUC_JSON_GetStringFieldPtr(config->rootJsonValue, CONFIG_MODEL);

    if (IsNullOrEmpty(config->model))
    {
        Log_Error(INVALID_OR_MISSING_FIELD_ERROR_FMT, CONFIG_MODEL);
        goto done;
    }

    // Edge gateway certification path is optional.
    config->edgegatewayCertPath = ADUC_JSON_GetStringFieldPtr(config->rootJsonValue, CONFIG_EDGE_GATEWAY_CERT_PATH);

    const JSON_Object* root_object = json_value_get_object(config->rootJsonValue);

    config->aduShellTrustedUsers = json_object_get_array(root_object, CONFIG_ADU_SHELL_TRUSTED_USERS);

    if (config->aduShellTrustedUsers == NULL)
    {
        Log_Error(INVALID_OR_MISSING_FIELD_ERROR_FMT, CONFIG_ADU_SHELL_TRUSTED_USERS);
        goto done;
    }

    // Note: compat property names are optional.
    config->compatPropertyNames = ADUC_JSON_GetStringFieldPtr(config->rootJsonValue, CONFIG_COMPAT_PROPERTY_NAMES);

    // Note: IoT Hub protocol is is optional.
    config->iotHubProtocol = ADUC_JSON_GetStringFieldPtr(config->rootJsonValue, CONFIG_IOT_HUB_PROTOCOL);

    // Note: download timeout is optional.
    ADUC_JSON_GetUnsignedIntegerField(
        config->rootJsonValue, CONFIG_DOWNLOAD_TIMEOUT_IN_MINUTES, &(config->downloadTimeoutInMinutes));

    // Ensure that adu-shell folder is valid.
    config->aduShellFolder = ADUC_JSON_GetStringFieldPtr(config->rootJsonValue, CONFIG_ADU_SHELL_FOLDER);

    if (config->aduShellFolder == NULL)
    {
        if (!ADUC_JSON_SetStringField(config->rootJsonValue, CONFIG_ADU_SHELL_FOLDER, ADUSHELL_FOLDER))
        {
            Log_Error("Failed to set adu-shell folder.");
            goto done;
        }
        config->aduShellFolder = ADUC_JSON_GetStringFieldPtr(config->rootJsonValue, CONFIG_ADU_SHELL_FOLDER);
    }

    config->aduShellFilePath = ADUC_StringFormat("%s/%s", config->aduShellFolder, ADUSHELL_FILENAME);
    if (config->aduShellFilePath == NULL)
    {
        Log_Error("Failed to allocate memory for adu-shell file path");
        goto done;
    }

    config->dataFolder = ADUC_JSON_GetStringFieldPtr(config->rootJsonValue, CONFIG_ADU_DATA_FOLDER);

    if (config->dataFolder == NULL)
    {
        if (!ADUC_JSON_SetStringField(config->rootJsonValue, CONFIG_ADU_DATA_FOLDER, ADUC_DATA_FOLDER))
        {
            Log_Error("Failed to set data folder.");
            goto done;
        }
        config->dataFolder = ADUC_JSON_GetStringFieldPtr(config->rootJsonValue, CONFIG_ADU_DATA_FOLDER);
    }

    if (!EnsureDataSubFolderSpecifiedOrSetDefaultValue(
            config->rootJsonValue,
            CONFIG_ADU_DOWNLOADS_FOLDER,
            &config->downloadsFolder,
            config->dataFolder,
            DOWNLOADS_PATH_SEGMENT))
    {
        goto done;
    }

    if (!EnsureDataSubFolderSpecifiedOrSetDefaultValue(
            config->rootJsonValue,
            CONFIG_ADU_EXTENSIONS_FOLDER,
            &config->extensionsFolder,
            config->dataFolder,
            EXTENSIONS_PATH_SEGMENT))
    {
        goto done;
    }

    // Since we're only allow overriding of 'extensions' folder, let's populate all extensions sub-folders.
    config->extensionsComponentEnumeratorFolder =
        ADUC_StringFormat("%s/%s", config->extensionsFolder, ADUC_EXTENSIONS_SUBDIR_COMPONENT_ENUMERATOR);

    if (config->extensionsComponentEnumeratorFolder == NULL)
    {
        Log_Error("Failed to allocate memory for component enumerator extension folder");
        goto done;
    }

    config->extensionsContentDownloaderFolder =
        ADUC_StringFormat("%s/%s", config->extensionsFolder, ADUC_EXTENSIONS_SUBDIR_CONTENT_DOWNLOADER);
    if (config->extensionsContentDownloaderFolder == NULL)
    {
        Log_Error("Failed to allocate memory for content downloader extension folder");
        goto done;
    }

    config->extensionsStepHandlerFolder =
        ADUC_StringFormat("%s/%s", config->extensionsFolder, ADUC_EXTENSIONS_SUBDIR_UPDATE_CONTENT_HANDLERS);
    if (config->extensionsStepHandlerFolder == NULL)
    {
        Log_Error("Failed to allocate memory for step handler extension folder");
        goto done;
    }

    config->extensionsDownloadHandlerFolder =
        ADUC_StringFormat("%s/%s", config->extensionsFolder, ADUC_EXTENSIONS_SUBDIR_DOWNLOAD_HANDLERS);
    if (config->extensionsDownloadHandlerFolder == NULL)
    {
        Log_Error("Failed to allocate memory for download handler extension folder");
        goto done;
    }

    succeeded = true;

done:

    if (configFilePath != NULL)
    {
        free(configFilePath);
    }

    if (!succeeded)
    {
        ADUC_ConfigInfo_UnInit(config);
    }
    return succeeded;
}