Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions core/src/main/java/io/temporal/samples/sleepfordays/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Sleep for days

This sample demonstrates how to use Temporal to run a workflow that periodically sleeps for a number of days.

## Run the sample

1. Start the Worker:

```bash
./gradlew -q execute -PmainClass=io.temporal.samples.sleepfordays.Worker
```

2. Start the Starter

```bash
./gradlew -q execute -PmainClass=io.temporal.samples.sleepfordays.Starter
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import io.temporal.activity.ActivityInterface;

@ActivityInterface
public interface SendEmailActivity {
void sendEmail(String email);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

public class SendEmailActivityImpl implements SendEmailActivity {
@Override
public void sendEmail(String email) {
System.out.println(email);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import io.temporal.activity.ActivityOptions;
import io.temporal.workflow.Promise;
import io.temporal.workflow.Workflow;
import java.time.Duration;

public class SleepForDaysImpl implements SleepForDaysWorkflow {

private final SendEmailActivity activity;
private boolean complete = false;

public SleepForDaysImpl() {
this.activity =
Workflow.newActivityStub(
SendEmailActivity.class,
ActivityOptions.newBuilder().setStartToCloseTimeout(Duration.ofSeconds(10)).build());
}

@Override
public String sleepForDays() {
while (!this.complete) {
activity.sendEmail(String.format("Sleeping for 30 days"));
Promise<Void> timer = Workflow.newTimer(Duration.ofDays(30));
Workflow.await(() -> timer.isCompleted() || this.complete);
}

return "done!";
}

@Override
public void complete() {
this.complete = true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import io.temporal.workflow.SignalMethod;
import io.temporal.workflow.WorkflowInterface;
import io.temporal.workflow.WorkflowMethod;

@WorkflowInterface
public interface SleepForDaysWorkflow {
@WorkflowMethod
String sleepForDays();

@SignalMethod
void complete();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;
import io.temporal.client.WorkflowStub;

public class Starter {

public static final String TASK_QUEUE = "SleepForDaysTaskQueue";

public static void main(String[] args) {
// Start a workflow execution.
SleepForDaysWorkflow workflow =
Worker.client.newWorkflowStub(
SleepForDaysWorkflow.class,
WorkflowOptions.newBuilder().setTaskQueue(TASK_QUEUE).build());

// Start the workflow.
WorkflowClient.start(workflow::sleepForDays);

WorkflowStub stub = WorkflowStub.fromTyped(workflow);

// Wait for workflow to complete. This will wait indefinitely until a 'complete' signal is sent.
stub.getResult(String.class);
System.exit(0);
}
}
40 changes: 40 additions & 0 deletions core/src/main/java/io/temporal/samples/sleepfordays/Worker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import io.temporal.client.WorkflowClient;
import io.temporal.serviceclient.WorkflowServiceStubs;
import io.temporal.worker.WorkerFactory;

public class Worker {
public static final String TASK_QUEUE = "SleepForDaysTaskQueue";
public static final WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs();
public static final WorkflowClient client = WorkflowClient.newInstance(service);
public static final WorkerFactory factory = WorkerFactory.newInstance(client);

public static void main(String[] args) {
io.temporal.worker.Worker worker = factory.newWorker(TASK_QUEUE);
worker.registerWorkflowImplementationTypes(SleepForDaysImpl.class);
worker.registerActivitiesImplementations(new SendEmailActivityImpl());

factory.start();
System.out.println("Worker started for task queue: " + TASK_QUEUE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2020 Temporal Technologies, Inc. All Rights Reserved
*
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Modifications copyright (C) 2017 Uber Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
* use this file except in compliance with the License. A copy of the License is
* located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

package io.temporal.samples.sleepfordays;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import io.temporal.client.WorkflowClient;
import io.temporal.client.WorkflowOptions;
import io.temporal.testing.TestWorkflowRule;
import java.time.Duration;
import org.junit.Rule;
import org.junit.Test;

public class SleepForDaysTest {

@Rule
public TestWorkflowRule testWorkflowRule =
TestWorkflowRule.newBuilder()
.setWorkflowTypes(SleepForDaysImpl.class)
.setDoNotStart(true)
.build();

@Test(timeout = 8000)
public void testSleepForDays() {
// Mock activity
SendEmailActivity activities = mock(SendEmailActivity.class);
testWorkflowRule.getWorker().registerActivitiesImplementations(activities);
// Start environment
testWorkflowRule.getTestEnvironment().start();

// Create a workflow
WorkflowOptions workflowOptions =
WorkflowOptions.newBuilder().setTaskQueue(testWorkflowRule.getTaskQueue()).build();
SleepForDaysWorkflow workflow =
testWorkflowRule
.getWorkflowClient()
.newWorkflowStub(SleepForDaysWorkflow.class, workflowOptions);

// Start workflow
WorkflowClient.start(workflow::sleepForDays);

long startTime = testWorkflowRule.getTestEnvironment().currentTimeMillis();
// Time-skip 5 minutes.
testWorkflowRule.getTestEnvironment().sleep(Duration.ofMinutes(5));
// Check that the activity has been called, we're now waiting for the sleep to finish.
verify(activities, times(1)).sendEmail(anyString());
// Time-skip 3 days.
testWorkflowRule.getTestEnvironment().sleep(Duration.ofDays(90));
// Expect 3 more activity calls.
verify(activities, times(4)).sendEmail(anyString());
// Send the signal to complete the workflow.
workflow.complete();
// Expect no more activity calls to have been made - workflow is complete.
verify(activities, times(4)).sendEmail(anyString());
// Expect more than 90 days to have passed.
long endTime = testWorkflowRule.getTestEnvironment().currentTimeMillis();
assertEquals(true, endTime - startTime > Duration.ofDays(90).toMillis());
}
}
Loading