jint JNICALL Java_software_amazon_awssdk_crt_eventstream_ClientConnection_clientConnect()

in src/native/event_stream_rpc_client.c [120:218]


jint JNICALL Java_software_amazon_awssdk_crt_eventstream_ClientConnection_clientConnect(
    JNIEnv *env,
    jclass jni_class,
    jbyteArray jni_host_name,
    jshort port,
    jlong jni_socket_options,
    jlong jni_tls_ctx,
    jlong jni_client_bootstrap,
    jobject jni_client_connection_handler) {
    (void)jni_class;
    struct aws_client_bootstrap *client_bootstrap = (struct aws_client_bootstrap *)jni_client_bootstrap;
    struct aws_socket_options *socket_options = (struct aws_socket_options *)jni_socket_options;
    struct aws_tls_ctx *tls_context = (struct aws_tls_ctx *)jni_tls_ctx;

    if (!client_bootstrap) {
        aws_jni_throw_runtime_exception(env, "ClientConnection.clientConnect: Invalid ClientBootstrap");
        return AWS_OP_ERR;
    }

    if (!socket_options) {
        aws_jni_throw_runtime_exception(env, "ClientConnection.clientConnect: Invalid SocketOptions");
        return AWS_OP_ERR;
    }

    struct aws_tls_connection_options connection_options;
    AWS_ZERO_STRUCT(connection_options);
    struct aws_tls_connection_options *conn_options_ptr = NULL;
    struct aws_string *host_name_str = NULL;

    if (tls_context) {
        aws_tls_connection_options_init_from_ctx(&connection_options, tls_context);
        conn_options_ptr = &connection_options;
    }

    struct aws_allocator *allocator = aws_jni_get_allocator();
    struct connection_callback_data *callback_data =
        aws_mem_calloc(allocator, 1, sizeof(struct connection_callback_data));

    if (!callback_data) {
        goto error;
    }

    jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
    if (jvmresult != 0) {
        aws_jni_throw_runtime_exception(env, "ClientConnection.clientConnect: Unable to get JVM");
        goto error;
    }

    callback_data->java_connection_handler = (*env)->NewGlobalRef(env, jni_client_connection_handler);

    if (!callback_data->java_connection_handler) {
        aws_jni_throw_runtime_exception(env, "ClientConnection.clientConnect: Unable to create global ref");
        goto error;
    }

    const size_t host_name_len = (*env)->GetArrayLength(env, jni_host_name);
    jbyte *host_name = (*env)->GetPrimitiveArrayCritical(env, jni_host_name, NULL);
    host_name_str = aws_string_new_from_array(allocator, (uint8_t *)host_name, host_name_len);
    (*env)->ReleasePrimitiveArrayCritical(env, jni_host_name, host_name, 0);

    if (!host_name_str) {
        aws_jni_throw_runtime_exception(env, "ServerListener.server_listener_new: Unable to allocate");
        goto error;
    }

    const char *c_str_host_name = aws_string_c_str(host_name_str);

    struct aws_event_stream_rpc_client_connection_options conn_options = {
        .socket_options = socket_options,
        .tls_options = conn_options_ptr,
        .user_data = callback_data,
        .port = (uint16_t)port,
        .bootstrap = client_bootstrap,
        .host_name = c_str_host_name,
        .on_connection_setup = s_on_connection_setup,
        .on_connection_shutdown = s_on_connection_shutdown,
        .on_connection_protocol_message = s_connection_protocol_message,
    };

    if (aws_event_stream_rpc_client_connection_connect(allocator, &conn_options)) {
        goto error;
    }

    aws_string_destroy(host_name_str);
    aws_tls_connection_options_clean_up(&connection_options);

    return AWS_OP_SUCCESS;

error:
    if (callback_data) {
        aws_mem_release(allocator, callback_data);
    }

    if (conn_options_ptr) {
        aws_tls_connection_options_clean_up(conn_options_ptr);
    }

    return AWS_OP_ERR;
}