celix_status_t remoteServiceAdmin_exportService()

in bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c [580:691]


celix_status_t remoteServiceAdmin_exportService(remote_service_admin_t *admin, char *serviceId, celix_properties_t *properties, celix_array_list_t** registrationsOut) {
    celix_status_t status = CELIX_SUCCESS;

    bool export = false;
    const char *exportConfigs = celix_properties_get(properties, CELIX_RSA_SERVICE_EXPORTED_CONFIGS, RSA_DFI_CONFIGURATION_TYPE);
    if (exportConfigs != NULL) {
        // See if the EXPORT_CONFIGS matches this RSA. If so, try to export.

        char *ecCopy = strndup(exportConfigs, strlen(exportConfigs));
        const char delimiter[2] = ",";
        char *token, *savePtr;

        token = strtok_r(ecCopy, delimiter, &savePtr);
        while (token != NULL) {
            if (strncmp(celix_utils_trimInPlace(token), RSA_DFI_CONFIGURATION_TYPE, 1024) == 0) {
                export = true;
                break;
            }

            token = strtok_r(NULL, delimiter, &savePtr);
        }

        free(ecCopy);
    } else {
        export = true;
    }

    celix_array_list_t *registrations = NULL;
    if (export) {
        registrations = celix_arrayList_create();
        celix_array_list_t* references = NULL;
        service_reference_pt reference = NULL;
        char filter[256];

        snprintf(filter, 256, "(%s=%s)", (char *) CELIX_FRAMEWORK_SERVICE_ID, serviceId);

        status = bundleContext_getServiceReferences(admin->context, NULL, filter, &references);

        celix_logHelper_log(admin->loghelper, CELIX_LOG_LEVEL_DEBUG, "RSA: exportService called for serviceId %s", serviceId);

        int i;
        int size = celix_arrayList_size(references);
        for (i = 0; i < size; i += 1) {
            if (i == 0) {
                reference = celix_arrayList_get(references, i);
            } else {
                bundleContext_ungetServiceReference(admin->context, celix_arrayList_get(references, i));
            }
        }
        celix_arrayList_destroy(references);

        if (reference == NULL) {
            celix_logHelper_log(admin->loghelper, CELIX_LOG_LEVEL_ERROR, "ERROR: expected a reference for service id %s.",
                          serviceId);
            status = CELIX_ILLEGAL_STATE;
        }

        const char *exports = NULL;
        const char *provided = NULL;
        if (status == CELIX_SUCCESS) {
            serviceReference_getProperty(reference, (char *) CELIX_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
            serviceReference_getProperty(reference, (char *) CELIX_FRAMEWORK_SERVICE_NAME, &provided);

            if (exports == NULL || provided == NULL || strcmp(exports, provided) != 0) {
                celix_logHelper_log(admin->loghelper, CELIX_LOG_LEVEL_WARNING, "RSA: No Services to export.");
                status = CELIX_ILLEGAL_STATE;
            } else {
                celix_logHelper_log(admin->loghelper, CELIX_LOG_LEVEL_INFO, "RSA: Export service (%s)", provided);
            }
        }

        if (status == CELIX_SUCCESS) {
            const char *interface = provided;
            endpoint_description_t *endpoint = NULL;
            export_registration_t *registration = NULL;

            remoteServiceAdmin_createEndpointDescription(admin, reference, properties, (char *) interface, &endpoint);
            status = exportRegistration_create(admin->loghelper, reference, endpoint, admin->context, admin->logFile,
                                               &registration);
            if (status == CELIX_SUCCESS) {
                status = exportRegistration_start(registration);
                if (status == CELIX_SUCCESS) {
                    celix_arrayList_add(registrations, registration);
                }
            }
        }


        if (status == CELIX_SUCCESS && celix_arrayList_size(registrations) > 0) {
            celixThreadRwlock_writeLock(&admin->exportedServicesLock);
            hashMap_put(admin->exportedServices, reference, registrations);
            celixThreadRwlock_unlock(&admin->exportedServicesLock);
        } else {
            celix_arrayList_destroy(registrations);
            registrations = NULL;
        }
    }

    if (status == CELIX_SUCCESS) {
        //We return a empty list of registrations if Remote Service Admin does not recognize any of the configuration types.
    	celix_array_list_t *newRegistrations = celix_arrayList_create();
        if (registrations != NULL) {
            int regSize = celix_arrayList_size(registrations);
            for (int i = 0; i < regSize; ++i) {
                celix_arrayList_add(newRegistrations, celix_arrayList_get(registrations, i));
            }
        }
        *registrationsOut = newRegistrations;
    }

    return status;
}