Skip to content

Allow users of the SDK to provide their own copy of the apache HTTP … - #1

Closed
campbellbartlett wants to merge 2 commits into
masterfrom
campbell.customizable.http.client
Closed

campbellbartlett wants to merge 2 commits into
masterfrom
campbell.customizable.http.client

Conversation

@campbellbartlett

@campbellbartlett campbellbartlett commented Jan 15, 2025 •

Copy link
Copy Markdown
Owner

This PR addresses cloudinary#343 by making the SDK more flexible in how HTTP clients and strategies are configured.

Key Changes:

  1. Users can now provide their own HTTP client implementation
  2. Users can supply custom API/Uploader strategies instead of relying on reflection-based loading
  3. Legacy reflection-based strategy loading is preserved in LegacyCloudinaryLoader.java (currently needed for cloudinary-taglib and tests, but could be phased out in future)

The new architecture allows different HTTP library implementations (like okHttp or Jetty) to provide their own CloudinaryClient.java implementations.

Here's how it would work for a user of the com.cloudinary.http5 package:

Custom HTTP client example:

CloseableHttpClient client = HttpClients.custom()
        .setConnectionManager(aCustomConnectionManager)
        .setProxy(myCompaniesHttpProxyConfig)
        .setConnectionBackoffStrategy(myCustomBackoffStrategy)
        .build();

this.cloudinary = new CloudinaryClient(myCloudinaryConfig, client);

Custom Strategy Example:

this.cloudinary = new CloudinaryClient(myCloudinaryConfig, myUploaderStrategy, myApiStrategy);

All existing initialization methods are still supported:

// No-args constructor
new CloudinaryClient();

// Config via Map
new CloudinaryClient(myMapThatICreatedEarlier);

// Config via URL string
new CloudinaryClient(someUrlStringLoadedEarlier);

Next steps:

A similar implementation of CloudinaryClient should be created for com.cloudinary.android.

Breaking Change:

When upgrading, users will need to update their client instantiation from:

new Cloudinary()  // Old

to:

new CloudinaryClient()  // New

This change affects all constructor overloads (with and without arguments).

Comment on lines +33 to +43
public LegacyCloudinaryLoader() {
super(loadDefaultConfig(), getUploaderStrategy(loadDefaultConfig()), getApiStrategy(loadDefaultConfig()));
}

public LegacyCloudinaryLoader(Map<String, Object> configuration) {
super(new Configuration(configuration), getUploaderStrategy(new Configuration(configuration)), getApiStrategy(new Configuration(configuration)));
}

public LegacyCloudinaryLoader(String url) {
super(Configuration.from(url), getUploaderStrategy(Configuration.from(url)), getApiStrategy(Configuration.from(url)));
}

@campbellbartlett campbellbartlett Jan 15, 2025 •

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The load_strategies configuration property introduces unnecessary complexity to these constructors. Due to Java 8's requirement that super() must be the first statement in a constructor, combined with the conditional nature of the legacy strategy loading, we're forced into a more complicated implementation than is ideal.

I think that this property only exists for testing purposes in CloudinaryTest.java. If it were up to me I would consider removing it entirely and restructuring those tests accordingly. This would lead to cleaner, more maintainable constructor logic.

@campbellbartlett campbellbartlett changed the title Allow users of the SDK to pprovide their own copy of the apache HTTP … Allow users of the SDK to provide their own copy of the apache HTTP … Jan 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant