Example #1
0
static void ClientSubscribe_PerformSuccessfulCallback(const char * path, void * value, void * context)
{
    AwaClientSubscription * subscription = (AwaClientSubscription *)value;
    PerformSuccessfulCallbackContext * successContext = (PerformSuccessfulCallbackContext *)context;

    const AwaPathResult * result = AwaClientSubscribeResponse_GetPathResult(successContext->Response, subscription->Path);
    if (!subscription->Cancel)
    {
        if (AwaPathResult_GetError(result) == AwaError_Success)
        {
            Map_Put(ClientSession_GetSubscribers(successContext->Session), subscription->Path, subscription);

            // map the subscription to this session.
            subscription->Session = successContext->Session;
        }
        else
        {
            LogErrorWithEnum(AwaPathResult_GetError(result), "Failed to subscribe to path %s\n", subscription->Path);
            successContext->Result = AwaError_Response;
        }
    }
}
int main(int argc, char ** argv)
{
    int result = 0;
    AwaClientSubscribeOperation * operation;
    struct gengetopt_args_info ai;
    AwaClientSession * session = NULL;

    // Catch CTRL-C to ensure clean-up
    signal(SIGINT, INThandler);

    if (cmdline_parser(argc, argv, &ai) != 0)
    {
        exit(1);
    }

    g_logLevel = ai.debug_given ? 2 : (ai.verbose_given ? 1 : 0);
    AwaLog_SetLevel(ai.debug_given ? AwaLogLevel_Debug : (ai.verbose_given ? AwaLogLevel_Verbose : AwaLogLevel_Warning));

    if (ai.inputs_num == 0)
    {
        Error("Specify one or more resource paths.\n");
        result = 1;
        goto cleanup;
    }

    session = Client_EstablishSession(ai.ipcAddress_arg, ai.ipcPort_arg);
    if (session != NULL)
    {
        operation = AwaClientSubscribeOperation_New(session);
        if (operation == NULL)
        {
            Error("Failed to create subscribe operation\n");
            exit(1);
        }

        void * context = &ai.quiet_given; // pass the quiet parameter as our context

        int count = 0;
        int i = 0;
        for (i = 0; i < ai.inputs_num; ++i)
        {
            Target * target = CreateTarget(ai.inputs[i]);
            if (target != NULL)
            {
                count = SubscribeToTarget(session, operation, target, context) ? count + 1 : count;
                FreeTarget(&target);
            }
        }

        if (AwaClientSubscribeOperation_Perform(operation, OPERATION_PERFORM_TIMEOUT) != AwaError_Success)
        {
            Error("Failed to perform subscribe operation\n");
            goto cleanup;
        }

        int validCount = count;
        const AwaClientSubscribeResponse * response = AwaClientSubscribeOperation_GetResponse(operation);
        SubscriptionNode * currentSubscription = g_subscriptionListHead;
        SubscriptionNode * nextSubscription;
        while (currentSubscription != NULL)
        {
            nextSubscription = currentSubscription->next;

            const AwaPathResult * pathResult = NULL;
            const char * path = NULL;

            switch (currentSubscription->type)
            {
                case AwaSubscribeType_Change:
                {
                    AwaClientChangeSubscription * subscription = (AwaClientChangeSubscription *)(currentSubscription->subscription);
                    path = AwaClientChangeSubscription_GetPath(subscription);
                    break;
                }
                case AwaSubscribeType_Execute:
                {
                    AwaClientExecuteSubscription * subscription = (AwaClientExecuteSubscription *)(currentSubscription->subscription);
                    path = AwaClientExecuteSubscription_GetPath(subscription);
                    break;
                }
                default:
                    Error("Unsupported subscribe type: %d for path %s\n", currentSubscription->type, path);
                    break;
            }

            pathResult = AwaClientSubscribeResponse_GetPathResult(response, path);
            if (AwaPathResult_GetError(pathResult) != AwaError_Success)
            {
                Error("Failed to subscribe to %s: %s\n", path, AwaError_ToString(AwaPathResult_GetError(pathResult)));
                validCount--;
            }

            currentSubscription = nextSubscription;
        }

        AwaClientSubscribeOperation_Free(&operation);

        Debug("count %d\n", count);
        // Wait if there's something to wait for
        if (count > 0)
        {
            if (validCount > 0)
            {
                Wait(session, ai.waitTime_arg, ai.waitCount_arg);
            }
            UnsubscribeFromTargets(session);
        }
    }
    else
    {
        Error("Failed to establish Awa Session\n");
        result = 1;
    }
cleanup:
    if (session)
    {
        FreeSubscriptionList();
        Client_ReleaseSession(&session);
    }
    cmdline_parser_free(&ai);
    return result;
}
static void UnsubscribeFromTargets(AwaClientSession * session)
{ 
    AwaClientSubscribeOperation * operation = AwaClientSubscribeOperation_New(session);
    if (operation == NULL)
    {
        Error("Failed to create subscribe operation\n");
        exit(1);
    }

    // Add cancels for each subscription
    SubscriptionNode * currentSubscription = g_subscriptionListHead;
    SubscriptionNode * nextSubscription;
    while(currentSubscription != NULL)
    {
        nextSubscription = currentSubscription->next;

        switch (currentSubscription->type)
        {
            case AwaSubscribeType_Change:
                if (AwaClientSubscribeOperation_AddCancelChangeSubscription(operation, currentSubscription->subscription) != AwaError_Success)
                {
                    Error("AwaClientSubscribeOperation_AddCancelChangeSubscription() failed for path %s\n", AwaClientChangeSubscription_GetPath(currentSubscription->subscription));
                }
                break;
            case AwaSubscribeType_Execute:
                if (AwaClientSubscribeOperation_AddCancelExecuteSubscription(operation, currentSubscription->subscription) != AwaError_Success)
                {
                    Error("AwaClientSubscribeOperation_AddCancelExecuteSubscription() failed for path %s\n", AwaClientExecuteSubscription_GetPath(currentSubscription->subscription));
                }
                break;
            default:
                Error("Unsupported subscribe type: %d\n", currentSubscription->type);
                break;
        }
        currentSubscription = nextSubscription;
    }

    if (AwaClientSubscribeOperation_Perform(operation, OPERATION_PERFORM_TIMEOUT) != AwaError_Success)
    {
        Error("Failed to perform subscribe operation\n");
    }

    // Check response for each subscription
    const AwaClientSubscribeResponse * response = AwaClientSubscribeOperation_GetResponse(operation);
    currentSubscription = g_subscriptionListHead;
    while (currentSubscription != NULL)
    {
        nextSubscription = currentSubscription->next;

        const AwaPathResult * result = NULL;
        const char * path = NULL;

        switch (currentSubscription->type)
        {
            case AwaSubscribeType_Change:
            {
                AwaClientChangeSubscription * subscription = (AwaClientChangeSubscription *)(currentSubscription->subscription);
                path = AwaClientChangeSubscription_GetPath(subscription);
                break;
            }
            case AwaSubscribeType_Execute:
            {
                AwaClientExecuteSubscription * subscription = (AwaClientExecuteSubscription *)(currentSubscription->subscription);
                path = AwaClientExecuteSubscription_GetPath(subscription);
                break;
            }
            default:
                Error("Unsupported subscribe type: %d for path %s\n", currentSubscription->type, path);
                break;
        }

        result = AwaClientSubscribeResponse_GetPathResult(response, path);
        if (AwaPathResult_GetError(result) != AwaError_Success)
        {
            Error("Failed to cancel subscription to %s: %s\n", path, AwaError_ToString(AwaPathResult_GetError(result)));
        }

        currentSubscription = nextSubscription;
    }
    AwaClientSubscribeOperation_Free(&operation);

    // Finally free each subscription
    currentSubscription = g_subscriptionListHead;
    while(currentSubscription != NULL)
    {
        nextSubscription = currentSubscription->next;

        switch (currentSubscription->type)
        {
            case AwaSubscribeType_Change:
            {
                AwaClientChangeSubscription * subscription = (AwaClientChangeSubscription *)(currentSubscription->subscription);
                if (AwaClientChangeSubscription_Free(&subscription) != AwaError_Success)
                {
                    Error("AwaClientChangeSubscription_Free() failed for path %s\n", AwaClientChangeSubscription_GetPath(subscription));
                }
                break;
            }
            case AwaSubscribeType_Execute:
            {
                AwaClientExecuteSubscription * subscription = (AwaClientExecuteSubscription *)(currentSubscription->subscription);
                if (AwaClientExecuteSubscription_Free(&subscription) != AwaError_Success)
                {
                    Error("AwaClientExecuteSubscription_Free() failed\n for path %s\n", AwaClientExecuteSubscription_GetPath(subscription));
                }
                break;
            }
            default:
                Error("Unsupported subscribe type: %d\n", currentSubscription->type);
                break;
        }
        currentSubscription = nextSubscription;
    }
}