Skip to content

Commit

Permalink
Better Java examples (#200)
Browse files Browse the repository at this point in the history
## Changes
This PR makes several changes to examples and documentation for the Java
SDK.
1. Add documentation comments for the Wait class and methods, describing
when they are returned and how to use them to retrieve API responses.
2. Check in examples from
https://docs.databricks.com/en/dev-tools/sdk-java.html as a reference
for @PaulCornellDB for maintaining the docs page. This way, examples are
updated as necessary to account for any changes in the SDK.
3. Refreshed all existing examples to work with the current version of
the Java SDK.
4. Refactored all non-Spring Boot examples into a single maven project
in `examples/docs` so that users can find all relevant examples in a
single directory
(examples/docs/src/main/java/com/databricks/sdk/examples). This also
means that there are fewer `pom.xml` files that need to be maintained.
5. Bump the version of the Java SDK used in the example maven projects
as part of the release flow.

Later, as part of the release process, we may need to set the `SNAPSHOT`
version to make it possible to test local changes to the SDK more
easily.

## Tests
- [x] Compilation of the maven projects in the `examples/` directory
passes.
- [ ] Unable to test the release workflow (as that forcibly resets to
the last commit on main).
  • Loading branch information
mgyucht committed Dec 18, 2023
1 parent 2e49467 commit e6c2726
Show file tree
Hide file tree
Showing 18 changed files with 213 additions and 151 deletions.
4 changes: 3 additions & 1 deletion .codegen.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
"version": {
"pom.xml": "<artifactId>databricks-sdk-parent</artifactId>\n <version>$VERSION</version>",
"databricks-sdk-java/pom.xml": "<artifactId>databricks-sdk-parent</artifactId>\n <version>$VERSION</version>",
"databricks-sdk-java/src/main/java/com/databricks/sdk/core/UserAgent.java": "private static final String version = \"$VERSION\";"
"databricks-sdk-java/src/main/java/com/databricks/sdk/core/UserAgent.java": "private static final String version = \"$VERSION\";",
"examples/docs/pom.xml": "<artifactId>databricks-sdk-java</artifactId>\n <version>$VERSION</version>",
"examples/spring-boot-oauth-u2m-demo/pom.xml": "<artifactId>databricks-sdk-java</artifactId>\n <version>$VERSION</version>"
},
"toolchain": {
"require": ["mvn", "java"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,29 @@
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;

/**
* A Wait object is returned by long-running operations. It can be used to wait for the operation to
* complete.
*
* <p>Several operations, such as starting a cluster or submitting a job, are long-running
* operations. After being initiated by a call to the API, these operations continue to run in the
* background until they complete. A separate API call can be made to check the status of the
* operation. {@code Wait} objects encapsulate this process, polling for the status of the operation
* until it completes.
*
* <p>{@code Wait} objects expose both the response from the triggering API call and the awaited
* resource. For example, the {@link
* com.databricks.sdk.service.compute.ClustersAPI#create(com.databricks.sdk.service.compute.CreateCluster)}
* method returns a {@code Wait<ClusterDetails, CreateClusterResponse>} object. The response from
* the API call to create the cluster is available via the {@link #getResponse()} method. The
* awaited resource, the cluster details, is available via the {@link #get()} method.
*
* <p>The {@link #get()} method waits for the operation to complete for up to 20 minutes. To wait
* for a custom duration, use the {@link #get(Duration)} method.
*
* @param <T>
* @param <R>
*/
public class Wait<T, R> {
private final WaitStarter<T> impl;
private final R response;
Expand All @@ -23,14 +46,32 @@ public Wait<T, R> onProgress(Consumer<T> progress) {
return this;
}

/**
* Wait for the operation to complete for up to 20 minutes.
*
* @return the awaited resource
* @throws TimeoutException if the operation does not complete within 20 minutes
*/
public T get() throws TimeoutException {
return get(Duration.ofMinutes(20));
}

/**
* Wait for the operation to complete for up to the specified duration.
*
* @param timeout the maximum duration to wait
* @return the awaited resource
* @throws TimeoutException if the operation does not complete within the specified duration
*/
public T get(Duration timeout) throws TimeoutException {
return impl.apply(timeout, progress);
}

/**
* Get the response for the initial API call made to start the operation.
*
* @return the response object
*/
public R getResponse() {
return response;
}
Expand Down
36 changes: 0 additions & 36 deletions examples/cli-auth-demo/pom.xml

This file was deleted.

76 changes: 0 additions & 76 deletions examples/cli-oauth-u2m-demo/pom.xml

This file was deleted.

30 changes: 30 additions & 0 deletions examples/docs/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.databricks</groupId>
<artifactId>docs</artifactId>
<version>0.0.1</version>

<name>docs</name>
<url>https://github.com/databricks/databricks-sdk-java</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-reload4j</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>com.databricks</groupId>
<artifactId>databricks-sdk-java</artifactId>
<version>0.14.0</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* <p>Before running this example, make sure to configure the host and client ID in the {@code DatabricksConfig} object.
*/
public class App {
public class CliOAuthU2MExample {
public static void main(String[] args) {
DatabricksConfig config = new DatabricksConfig()
.setAuthType("external-browser")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.databricks.sdk.examples;

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.compute.ClusterDetails;
import com.databricks.sdk.service.compute.CreateCluster;
import com.databricks.sdk.service.compute.CreateClusterResponse;
import com.databricks.sdk.support.Wait;
import java.time.Duration;
import java.util.concurrent.TimeoutException;

public class CreateClusterExample {
public static void main(String[] args) throws TimeoutException {
WorkspaceClient w = new WorkspaceClient();

// Creating a cluster returns immediately.
Wait<ClusterDetails, CreateClusterResponse> wait =
w.clusters()
.create(
new CreateCluster()
.setClusterName("my-cluster")
.setSparkVersion("12.2.x-scala2.12")
.setNodeTypeId("i3.xlarge")
.setAutoterminationMinutes(15L)
.setNumWorkers(1L));

// Creating a cluster is a long-running operation. Wait for the cluster to finish
// starting by calling the Wait.get() method. This waits for 20 minutes by default.
ClusterDetails c = wait.get();

// Wait for a custom duration with the Wait.get(Duration timeout) method.
c = wait.get(Duration.ofMinutes(10));

System.out.println(
"View the cluster at "
+ w.config().getHost()
+ "#setting/clusters/"
+ c.getClusterId()
+ "/configuration\n");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.databricks.sdk.examples;

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.jobs.*;
import java.util.*;

public class CreateJobExample {
public static void main(String[] args) {
System.out.println("Some short name for the job (for example, my-job):");
Scanner in = new Scanner(System.in);
String jobName = in.nextLine();

System.out.println("Some short description for the job (for example, My job):");
String description = in.nextLine();

System.out.println(
"ID of the existing cluster in the workspace to run the job on (for example, 1234-567890-ab123cd4):");
String existingClusterId = in.nextLine();

System.out.println(
"Workspace path of the notebook to run (for example, /Users/someone@example.com/my-notebook):");
String notebookPath = in.nextLine();

System.out.println("Some key to apply to the job's tasks (for example, my-key): ");
String taskKey = in.nextLine();

System.out.println("Attempting to create the job. Please wait...");

WorkspaceClient w = new WorkspaceClient();

Map<String, String> map = new HashMap<>();

Collection<Task> tasks =
Arrays.asList(
new Task()
.setDescription(description)
.setExistingClusterId(existingClusterId)
.setNotebookTask(
new NotebookTask()
.setBaseParameters(map)
.setNotebookPath(notebookPath)
.setSource(Source.WORKSPACE))
.setTaskKey(taskKey));

CreateResponse j = w.jobs().create(new CreateJob().setName(jobName).setTasks(tasks));

System.out.println("View the job at " + w.config().getHost() + "/#job/" + j.getJobId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.databricks.sdk.examples;

import com.databricks.sdk.WorkspaceClient;
import java.util.Scanner;

public class DeleteClusterExample {

public static void main(String[] args) {
System.out.println("ID of cluster to delete (for example, 1234-567890-ab123cd4):");

Scanner in = new Scanner(System.in);
String c_id = in.nextLine();
WorkspaceClient w = new WorkspaceClient();

w.clusters().permanentDelete(c_id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.databricks.sdk.examples;

import com.databricks.sdk.AccountClient;
import com.databricks.sdk.service.iam.Group;
import com.databricks.sdk.service.iam.ListAccountGroupsRequest;

public class ListAccountGroupsExample {
public static void main(String[] args) {
AccountClient a = new AccountClient();

for (Group g : a.groups().list((new ListAccountGroupsRequest()))) {
System.out.println(g.getDisplayName());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.databricks.sdk.examples;

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.compute.ClusterDetails;
import com.databricks.sdk.service.compute.ListClustersRequest;

public class ListClustersExample {
public static void main(String[] args) {
WorkspaceClient w = new WorkspaceClient();

for (ClusterDetails c : w.clusters().list(new ListClustersRequest())) {
System.out.println(c.getClusterName());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ private static List<String> triggerJobOn(WorkspaceClient testWorkspace, ClusterD

String runName = String.format("java-sdk-run-%s", System.currentTimeMillis()/1000.0);

RunSubmitTaskSettings task = new RunSubmitTaskSettings()
SubmitTask task = new SubmitTask()
.setTaskKey("test-task")
.setSparkPythonTask(
new SparkPythonTask()
Expand Down
Loading

0 comments on commit e6c2726

Please sign in to comment.