Skip to content

Commit

Permalink
Add Java basics examples (#132)
Browse files Browse the repository at this point in the history
* Add basic Java examples

* Small fixes to Java basics

* Add events state example

* Add basics-java to tests and update scripts and update Readme

* Fix basics examples to run separately

* Set durable execution to the default gradle run main.

* Remove TS from license header
  • Loading branch information
gvdongen authored May 2, 2024
1 parent 32d9b53 commit e529893
Show file tree
Hide file tree
Showing 29 changed files with 1,313 additions and 41 deletions.
2 changes: 2 additions & 0 deletions .tools/run_jvm_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ pushd $PROJECT_ROOT/templates/java-maven && mvn verify && popd || exit
pushd $PROJECT_ROOT/templates/kotlin-gradle && ./gradlew check && popd || exit
pushd $PROJECT_ROOT/templates/kotlin-gradle-lambda-cdk/lambda && ./gradlew check && popd || exit

pushd $PROJECT_ROOT/basics/basics-java && ./gradlew check && popd || exit

pushd $PROJECT_ROOT/patterns-use-cases/sagas/sagas-java && ./gradlew check && popd || exit

pushd $PROJECT_ROOT/tutorials/tour-of-restate-java && ./gradlew check && popd || exit
Expand Down
2 changes: 2 additions & 0 deletions .tools/update_jvm_examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ search_and_replace_version_maven $PROJECT_ROOT/templates/java-maven
search_and_replace_version_gradle $PROJECT_ROOT/templates/kotlin-gradle
search_and_replace_version_gradle $PROJECT_ROOT/templates/kotlin-gradle-lambda-cdk/lambda

search_and_replace_version_gradle $PROJECT_ROOT/basics/basics-java

search_and_replace_version_gradle $PROJECT_ROOT/patterns-use-cases/sagas/sagas-java
search_and_replace_version_gradle $PROJECT_ROOT/patterns-use-cases/sagas/sagas-kotlin

Expand Down
25 changes: 12 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@ challenges.

### Java

| Type | Name / Link |
|------------|-----------------------------------------------------------------|
| Use Cases | [Sagas](patterns-use-cases/sagas/sagas-java) |
| End-to-End | [Food Ordering App](end-to-end-applications/java/food-ordering) |
| Tutorial | [Tour of Restate](tutorials/tour-of-restate-java/) |
| Templates | [Template using Gradle](templates/java-gradle) |
| Templates | [Template using Maven](templates/java-maven) |
| Type | Name / Link |
|------------|----------------------------------------------------------------------------|
| Basics | [Durable Execution, Event-processing, Virtual Objects](basics/basics-java) |
| Use Cases | [Sagas](patterns-use-cases/sagas/sagas-java) |
| End-to-End | [Food Ordering App](end-to-end-applications/java/food-ordering) |
| Tutorial | [Tour of Restate](tutorials/tour-of-restate-java/) |
| Templates | [Template using Gradle](templates/java-gradle) |
| Templates | [Template using Maven](templates/java-maven) |

### Kotlin

Expand Down Expand Up @@ -81,17 +82,15 @@ Install and run the `restate-server` binary:
- Download from https://github.com/restatedev/restate/releases
- Install with Homebrew: `brew install restatedev/tap/restate-server`
- Install with _npm_: `npm install --global @restatedev/restate-server@latest`

Or run Restate Server in Docker:
- `docker run --name restate_dev --rm -p 8080:8080 -p 9070:9070 -p 9071:9071 --add-host=host.docker.internal:host-gateway docker.io/restatedev/restate:latest`
- Run in Docker: `docker run --name restate_dev --rm -p 8080:8080 -p 9070:9070 -p 9071:9071 --add-host=host.docker.internal:host-gateway docker.io/restatedev/restate:latest`


### (2) Register the examples at Restate Server

Many examples need to be registered at Restate, so that Restate will proxy their function calls and
do its magic. Once both server and example are running, register the example
The service endpoints need to be registered in Restate, so that Restate will proxy their function calls and
do its magic. Once both server and example are running, register the example:

* Via the [CLI](https://docs.restate.dev/operate/cli): `restate dp reg localhost:9080`
* Via the [CLI](https://docs.restate.dev/operate/cli): `restate deployments register localhost:9080`
* Via `curl localhost:9070/deployments -H 'content-type: application/json' -d '{"uri": "http://localhost:9080"}'`

**Important** When running Restate with Docker, use `host.docker.internal` instead of `localhost` in the URIs above.
Expand Down
35 changes: 35 additions & 0 deletions basics/basics-java/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

# Ignore Gradle project-specific cache directory
.gradle

# Ignore Gradle build output directory
build

.idea
*.iml

# Unignore the gradle wrapper
!gradle/wrapper/gradle-wrapper.jar
61 changes: 61 additions & 0 deletions basics/basics-java/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Examples of the basic concepts for Restate in TypeScript / JavaScript

The examples here showcase the most basic building blocks of Restate. **Durable Execution**,
**Durable Promises**, and **Virtual Objects**, and the **Workflows** abstraction built on top
of them.

The individual example files contain code snippets with comments and a brief descriptions
about how they work and how they can be run.

### Examples

* **[Basic Durable Execution:](durable_execution/RoleUpdateService.java):** Running code cleanly
to the end in the presence of failures. Automatic retries and recovery of previously
finished actions. The example applies a series of updates and permission setting changes
to user's profile.
```shell
./gradlew -PmainClass=durable_execution.RoleUpdateService run
```

* **[Durable Execution with Compensations](durable_execution_compensation/RoleUpdateService.java):**
Reliably compensating / undoing previous actions upon unrecoverable errors halfway
through multi-step change. This is the same example as above, extended for cases where
a part of the change cannot be applied (conflict) and everything has to roll back.
```shell
./gradlew -PmainClass=durable_execution_compensation.RoleUpdateService run
```

* **[Virtual Objects](virtual_objects/GreeterObject.java):** Stateful serverless objects
to manage durable consistent state and state-manipulating logic.
```shell
./gradlew -PmainClass=virtual_objects.GreeterObject run
```

* **[Kafka Event-processing](events_processing/UserUpdatesService.java):** Processing events to
update various downstream systems with durable event handlers, event-delaying,
in a strict-per-key order.
```shell
./gradlew -PmainClass=events_processing.UserUpdatesService run
```

* **[Stateful Event-processing](events_state/ProfileService.java):** Populating state from
events and making is queryable via RPC handlers.
```shell
./gradlew -PmainClass=events_state.ProfileService run
```


### Running the examples

1. Start Restate Server in a separate shell: `npx restate-server`

2. Start the relevant example. The commands are listed above for each example.

3. Register the example at Restate server by calling
`npx restate -y deployment register --force localhost:9080`.

_Note: the '--force' flag here is to circumvent all checks related to graceful upgrades, because it is only a playground, not a production setup._

4. Check the comments in the example for how to interact with the example.

**NOTE:** When you get an error of the type `{"code":"not_found","message":"Service 'greeter' not found. ...}`, then you forgot step (3) for that example.
47 changes: 47 additions & 0 deletions basics/basics-java/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import java.net.URI

plugins {
java
application
}

repositories {
mavenCentral()
}

val restateVersion = "0.9.0"

dependencies {
annotationProcessor("dev.restate:sdk-api-gen:$restateVersion")

// Restate SDK
implementation("dev.restate:sdk-api:$restateVersion")
implementation("dev.restate:sdk-http-vertx:$restateVersion")
// To use Jackson to read/write state entries (optional)
implementation("dev.restate:sdk-serde-jackson:$restateVersion")

// Jackson parameter names
// https://github.com/FasterXML/jackson-modules-java8/tree/2.14/parameter-names
implementation("com.fasterxml.jackson.module:jackson-module-parameter-names:2.16.1")
// Jackson java8 types
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.16.1")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.16.1")

// Logging (optional)
implementation("org.apache.logging.log4j:log4j-core:2.20.0")
}

// Set main class
application {
if (project.hasProperty("mainClass")) {
mainClass.set(project.property("mainClass") as String)
} else {
mainClass.set("durable_execution.RoleUpdateService")
}
}

tasks.withType<JavaCompile> {
// Using -parameters allows to use Jackson ParameterName feature
// https://github.com/FasterXML/jackson-modules-java8/tree/2.14/parameter-names
options.compilerArgs.add("-parameters")
}
Binary file not shown.
7 changes: 7 additions & 0 deletions basics/basics-java/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit e529893

Please sign in to comment.