oracle / oci-java-sdk

Oracle Cloud Infrastructure SDK for Java
https://cloud.oracle.com/cloud-infrastructure
Other
201 stars 156 forks source link

httpProvider on StreamClient.builder() seems to do nothing #488

Closed MikeyCarter closed 1 year ago

MikeyCarter commented 1 year ago

I have to specify httpProvider in my setup or I get "No http provider available; add dependency on one of the oci-java-sdk-common-httpclient-* choices, e.g. oci-java-sdk-common-httpclient-jersey"

With the StreamClient it seams to work differently than other clients and it comes up with that error even with httpProvider defined. Doing a trace it goes to the "defaultProvider" instead of using what I specified.

KartikShrikantHegde commented 1 year ago

Hi @MikeyCarter , thanks for notifying the issue. One of our engineers will take a look. Thanks!

mricken commented 1 year ago

Hi @MikeyCarter , I was able to successfully run this example: https://github.com/oracle/oci-java-sdk/blob/master/bmc-examples/src/main/java/StreamsExample.java

Can you show me how you are creating the client? You say "you have to specify httpProvider", which makes me think it's different than just

StreamClient streamClient = StreamClient.builder().stream(stream).build(provider);

Thanks!

MikeyCarter commented 1 year ago

My builder is...

StreamClient streamClient = StreamClient.builder().stream(stream).httpProvider(new JerseyHttpProvider()).build(provider);

My workaround is to extend the builder class and add this to the build(), so I could access the main constructor.

try {
                Class c = Class.forName("com.oracle.bmc.streaming.StreamClient");
        Constructor<StreamClient> constructor = c.getDeclaredConstructor(com.oracle.bmc.common.ClientBuilderBase.class, 
                                                                             com.oracle.bmc.auth.AbstractAuthenticationDetailsProvider.class);
        constructor.setAccessible(true); 
        return constructor.newInstance(this, authenticationDetailsProvider); 
} catch (Exception e) {
                e.printStackTrace();
}

When it uses the default build() it drops the httpProvider value and goes to the "default". In my case, I'm using this inside a Jenkins plugin and the "systemLoader" is Jenkins master where the SDK classes doen't exist. That's how I figured out it's dropping the httpProvider as it's going into all that code when httpProvider is null.

MikeyCarter commented 1 year ago

What I'm assuming is going on is the default build() is calling one of these, which is dropping the builder you supply for a new one.

    @Deprecated
    public StreamClient(
            com.oracle.bmc.auth.AbstractAuthenticationDetailsProvider authenticationDetailsProvider,
            com.oracle.bmc.ClientConfiguration configuration,
            com.oracle.bmc.http.ClientConfigurator clientConfigurator,
            com.oracle.bmc.http.signing.RequestSignerFactory defaultRequestSignerFactory,
            java.util.List<com.oracle.bmc.http.ClientConfigurator> additionalClientConfigurators) {
        this(
                builder()
                        .configuration(configuration)
                        .clientConfigurator(clientConfigurator)
                        .requestSignerFactory(defaultRequestSignerFactory)
                        .additionalClientConfigurators(additionalClientConfigurators),
                authenticationDetailsProvider);
    }
mricken commented 1 year ago

Thank you for the additional information, @MikeyCarter . I'm now able to reproduce the problem and can work on a solution. Thanks for bringing this to our attention!

mricken commented 1 year ago

A fix for this problem should be released on April 11.

mricken commented 1 year ago

This was fixed in version 3.11.0.

@MikeyCarter , could you please give it a try, and if it doesn't work, re-open this issue? Thanks again for bringing this to our attention.