Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(java client): Add connector functions to java client #7222

Merged
merged 8 commits into from
Mar 19, 2021

Conversation

jzaralim
Copy link
Contributor

Description

Adds createConnector, dropConnector, listConnector and describeConnector to the Java client. I can split this into separate PRs if that makes it easier to review.

Testing done

Unit and integration tests

Reviewer checklist

  • Ensure docs are updated if necessary. (eg. if a user visible feature is being added or changed).
  • Ensure relevant issues are linked (description should include text like "Fixes #")

@jzaralim jzaralim requested a review from a team as a code owner March 12, 2021 22:57
Copy link
Contributor

@vcrfxia vcrfxia left a comment

Choose a reason for hiding this comment

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

Hey @jzaralim -- awesome test coverage! Are you planning to add docs in a separate PR? If you wouldn't mind, we should also add docs for the new serverInfo() method you added as part of the 0.16 release (could be a separate PR).

Left some questions inline, mostly about the interfaces, but the high-level LGTM!


import java.util.Map;

public interface CreateConnectorResult {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are the methods in this result useful? Doesn't the user already have all this information (since it's required in order to call createConnect() in the first place)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure, but this is the response that Connect returns when creating a new connector. If this is not useful for the Java client, we can remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm actually I guess this wouldn't be the only place the client shows less info than the old rest api. I'll remove it, having 3 very similar classes for connector responses is clunky anyway.


/**
*
* @return a list of sources that this connector reads/writes to
Copy link
Contributor

Choose a reason for hiding this comment

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

What sources are these? External sources (as opposed to ksqlDB streams/tables)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the Javadoc to make this more clear.


/**
*
* @return a list of topics consumed by this connector
Copy link
Contributor

Choose a reason for hiding this comment

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

"consumed" meaning this is only present for sink connectors?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the Javadoc to make this more clear.

private static Optional<List<ConnectorInfo>> getListConnectorsResponse(
final JsonObject connectorsEntity) {
try {
final JsonArray connectors = connectorsEntity.getJsonArray("connectors");
Copy link
Contributor

Choose a reason for hiding this comment

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

A bit late for this PR but we've been wanting to change the pattern of how the Java client response interfaces relate to the server response objects for a while now, in order to avoid custom JSON parsing like this. Here's the ticket with context: #6042

We should really do this before the next time we add additional interfaces, but it's outside the scope for this PR. (If you're keen on helping clean up the codebase and want to tackle it as a follow-up PR that'd be super, but no pressure 😁 )

@Test
public void shouldListConnectors() throws Exception {
// Given:
makeKsqlRequest("CREATE SOURCE CONNECTOR " + TEST_CONNECTOR + " WITH ('connector.class'='" + MOCK_SOURCE_CLASS + "');");
Copy link
Contributor

Choose a reason for hiding this comment

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

If all three of these tests create the same connector, why do whichever tests run second and third not fail (because the connector already exists)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The statement fails but doesn't throw an error. I ended up moving this to setUp and tearDown though.

Copy link
Contributor

@vcrfxia vcrfxia left a comment

Choose a reason for hiding this comment

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

Thanks @jzaralim -- LGTM once the inline comments are addressed and docs are added. It'd be nice to get another opinion on the new client interfaces as well cc @colinhicks .

SOURCE,
SINK,
/**
* Denotes an unknown connector type. This is used when there were errors in connector creation.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this the only reason the connector type might be UNKNOWN or are there others as well, for example, when listing existing connectors? For some reason I thought there were other possible reasons for an UNKNOWN type as well but I could be wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I couldn't find any other references to UNKNOWN, but there could be a reason on the Connect side of things that I'm missing. Updated docs to be more accurate

Copy link
Contributor

@vcrfxia vcrfxia left a comment

Choose a reason for hiding this comment

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

Two more minor questions inline -- LGTM overall! (Plus the comments from before on docs and getting product input on the new interfaces) Thanks @jzaralim .

assertThatEventually(() -> {
try {
return client.listConnectors().get().size();
} catch (InterruptedException | ExecutionException e) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this exception expected (under normal cases)? What would cause this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not. It's just that since this is a part of a lambda, we need to do a try-catch here in order for the code to compile.

() -> {
try {
return ((ConnectorList) makeKsqlRequest("SHOW CONNECTORS;").get(0)).getConnectors().size();
} catch (AssertionError e) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same questions as above. I notice there's no analogous try-catch around the SHOW CONNECTORS; request in the cleanupConnectors() helper method, curious why this situation is different.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It takes a while to provision a connector, even after CREATE CONNECTOR returns a successful response. When ksqlDB calls SHOW CONNECTORS;, it makes a call to '/info' for reach connector, so if the new connector is not done provisioning, it returns an error response which propagates.

@jzaralim jzaralim requested a review from derekjn March 19, 2021 17:06
* @return result of connector creation
*/
CompletableFuture<Void> createConnector(
String connectorName, boolean isSource, Map<String, String> properties);
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe we use Map<String, Object> to pass properties elsewhere in the client interface. Is there a reason for using <String, String> here, or should we keep this consistent with the other interface methods?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch! Will update the PR.

@jzaralim jzaralim merged commit 7766195 into confluentinc:master Mar 19, 2021
@jzaralim jzaralim deleted the connector-java-client branch March 19, 2021 18:56
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.

3 participants