static void rsaJsonRpcProxy_serviceFunc()

in bundles/remote_services/rsa_rpc_json/src/rsa_json_rpc_proxy_impl.c [210:305]


static void rsaJsonRpcProxy_serviceFunc(void *userData, void *args[], void *returnVal) {
    celix_status_t  status = CELIX_SUCCESS;
    if (returnVal == NULL) {
        return;
    }
    if ((args == NULL) || (*((void **)args[0]) == NULL)) {
        *(celix_status_t *)returnVal = CELIX_ILLEGAL_ARGUMENT;
        return;
    }
    assert(userData != NULL);
    struct method_entry *entry = userData;
    rsa_json_rpc_proxy_t *proxy = *((void **)args[0]);
    rsa_json_rpc_proxy_factory_t *proxyFactory = proxy->proxyFactory;
    assert(proxyFactory != NULL);

    char *invokeRequest = NULL;
    int rc = jsonRpc_prepareInvokeRequest(entry->dynFunc, entry->id, args, &invokeRequest);
    if (rc != 0) {
        celix_logHelper_logTssErrors(proxyFactory->logHelper, CELIX_LOG_LEVEL_ERROR);
        celix_logHelper_error(proxyFactory->logHelper, "Error preparing invoke request for %s",
                              dynFunction_getName(entry->dynFunc));
        *(celix_status_t *)returnVal = CELIX_SERVICE_EXCEPTION;
        return;
    }

    struct iovec replyIovec = {NULL,0};
    celix_properties_t *metadata = celix_properties_create();
    if (metadata == NULL) {
        celix_logHelper_error(proxyFactory->logHelper,"Error creating metadata for %s",
                              dynFunction_getName(entry->dynFunc));
        free(invokeRequest);
        *(celix_status_t *)returnVal = CELIX_ENOMEM;
        return;
    }
    celix_properties_setLong(metadata, "SerialProtocolId", proxyFactory->serialProtoId);
    bool cont = remoteInterceptorHandler_invokePreProxyCall(proxyFactory->interceptorsHandler,
            proxyFactory->endpointDesc->properties, dynFunction_getName(entry->dynFunc), &metadata);
    if (cont) {
        struct iovec requestIovec = {invokeRequest,strlen(invokeRequest) + 1};
        struct rsa_request_sender_callback_data data= {
                .endpointDesc = proxyFactory->endpointDesc,
                .metadata = metadata,
                .request = &requestIovec,
                .response = &replyIovec
        };
        status = rsaRequestSenderTracker_useService(proxyFactory->reqSenderTracker, proxyFactory->reqSenderSvcId,
                &data, rsaJsonRpcProxy_useReqSenderSvcCallback);
        if (status == CELIX_SUCCESS && dynFunction_hasReturn(entry->dynFunc)) {
            if (replyIovec.iov_base != NULL) {
                int rsErrno = CELIX_SUCCESS;
                int retVal = jsonRpc_handleReply(entry->dynFunc,
                        (const char *)replyIovec.iov_base , args, &rsErrno);
                if(retVal != 0) {
                    status = CELIX_SERVICE_EXCEPTION;
                    celix_logHelper_logTssErrors(proxyFactory->logHelper, CELIX_LOG_LEVEL_ERROR);
                    celix_logHelper_error(proxyFactory->logHelper, "Error handling reply for %s",
                                          dynFunction_getName(entry->dynFunc));
                } else if (rsErrno != CELIX_SUCCESS) {
                    //return the invocation error of remote service function
                    status = rsErrno;
                }
            } else {
                celix_logHelper_error(proxyFactory->logHelper,"Expect service proxy has return, but reply is empty.");
                status = CELIX_ILLEGAL_ARGUMENT;
            }
        } else if (status != CELIX_SUCCESS) {
            celix_logHelper_error(proxyFactory->logHelper,"Service proxy send request failed. %d", status);
        }
        remoteInterceptorHandler_invokePostProxyCall(proxyFactory->interceptorsHandler,
                proxyFactory->endpointDesc->properties, dynFunction_getName(entry->dynFunc), metadata);
    } else {
        celix_logHelper_error(proxyFactory->logHelper, "%s has been intercepted.", proxyFactory->endpointDesc->serviceName);
        status = CELIX_INTERCEPTOR_EXCEPTION;
    }

    //free metadata
    if(metadata != NULL) {
        celix_properties_destroy(metadata);
    }

    if (proxyFactory->callsLogFile != NULL) {
        fprintf(proxyFactory->callsLogFile, "PROXY REMOTE CALL:\n\tservice=%s\n\tservice_id=%lu\n\trequest_payload=%s\n\trequest_response=%s\n\tstatus=%i\n",
                proxyFactory->endpointDesc->serviceName, proxyFactory->endpointDesc->serviceId, invokeRequest, (char *)replyIovec.iov_base, status);
        fflush(proxyFactory->callsLogFile);
    }


    free(invokeRequest); //Allocated by json_dumps in jsonRpc_prepareInvokeRequest
    if (replyIovec.iov_base) {
        free(replyIovec.iov_base); //Allocated by json_dumps
    }

    *(celix_status_t *) returnVal = status;

    return;
}