Skip to content

Commit e8fb5f2

Browse files
committed
Merge remote-tracking branch 'origin/main' into java-icegrid-query
2 parents b273919 + af7faca commit e8fb5f2

File tree

51 files changed

+2153
-8
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2153
-8
lines changed
File renamed without changes.

java/Glacier2/callback/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Gradle generated build files
2+
bin
3+
build
4+
.gradle

java/Glacier2/callback/README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Glacier2 Callback
2+
3+
This demo shows how to write a client that establishes a session with a Glacier2 router. It also shows how to implement
4+
callbacks in this client.
5+
6+
This demo is similar to the [Ice Callback][1] demo, except all communications go through the Glacier router.
7+
8+
The connection between the client and the Glacier2 router is a "bidir" connection, like in the [Ice Bidir][2] demo:
9+
10+
```mermaid
11+
flowchart LR
12+
c[Client<br>hosts AlarmClock] --bidir connection--> g[Glacier2 router:4063]
13+
g --connection1--> s[Server:4061<br>hosts WakeUpService] --connection2--> g
14+
```
15+
16+
## Ice prerequisites
17+
18+
- Install Glacier2. See [Ice service installation].
19+
20+
## Building the demo
21+
22+
The demo has two Gradle projects, **client** and **server**, both using the [application plugin].
23+
24+
To build the demo, run:
25+
26+
```shell
27+
./gradlew build
28+
```
29+
30+
## Running the demo
31+
32+
Start the Server program in its own terminal:
33+
34+
```shell
35+
./gradlew :server:run --quiet
36+
```
37+
38+
Next, start the Glacier2 router in its own terminal:
39+
40+
```shell
41+
glacier2router --Ice.Config=config.glacier2
42+
```
43+
44+
> [!TIP]
45+
> You can also start the Glacier2 router before the server. The order does not matter: the server is identical to the
46+
> server provided in the [Ice Callback][1] demo and does not depend on Glacier2.
47+
48+
Finally, in a separate terminal, start the client application:
49+
50+
```shell
51+
./gradlew :client:run --quiet
52+
```
53+
54+
[Application plugin]: https://docs.gradle.org/current/userguide/application_plugin.html
55+
56+
[1]: ../callback
57+
[2]: ../bidir
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright (c) ZeroC, Inc.
2+
3+
plugins {
4+
// Apply the application plugin to tell gradle this is a runnable Java application.
5+
id("application")
6+
7+
// Apply the Slice-tools plugin to enable Slice compilation.
8+
id("com.zeroc.slice-tools") version "3.8.+"
9+
10+
// Pull in our local 'convention plugin' to enable linting.
11+
id("zeroc-linting")
12+
}
13+
14+
dependencies {
15+
// Add Ice and Glacier2 as implementation dependencies.
16+
implementation("com.zeroc:ice:3.8.+")
17+
implementation("com.zeroc:glacier2:3.8.+")
18+
implementation(project(":util"))
19+
}
20+
21+
sourceSets {
22+
main {
23+
// Add the AlarmClock.ice file from the parent slice directory to the main source set.
24+
slice {
25+
srcDirs("../slice")
26+
}
27+
}
28+
}
29+
30+
application {
31+
// Specify the main entry point for the application.
32+
mainClass.set("com.example.glacier2.callback.client.Client")
33+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright (c) ZeroC, Inc.
2+
3+
package com.example.glacier2.callback.client;
4+
5+
import java.time.ZoneOffset;
6+
import java.time.ZonedDateTime;
7+
import java.util.concurrent.ExecutionException;
8+
9+
import com.example.earlyriser.AlarmClockPrx;
10+
import com.example.earlyriser.WakeUpServicePrx;
11+
import com.example.util.Time;
12+
import com.zeroc.Glacier2.CannotCreateSessionException;
13+
import com.zeroc.Glacier2.PermissionDeniedException;
14+
import com.zeroc.Glacier2.RouterPrx;
15+
import com.zeroc.Glacier2.SessionPrx;
16+
import com.zeroc.Ice.Communicator;
17+
import com.zeroc.Ice.Identity;
18+
import com.zeroc.Ice.ObjectAdapter;
19+
import com.zeroc.Ice.Util;
20+
21+
class Client {
22+
public static void main(String[] args) {
23+
// Create an Ice communicator. We'll use this communicator to create proxies and manage outgoing connections.
24+
try (Communicator communicator = Util.initialize(args)) {
25+
26+
// Create a proxy to the Glacier2 router. The addressing information (transport, host and port number) is
27+
// derived from the value of Glacier2.Client.Endpoints in the glacier2 router configuration file.
28+
RouterPrx router = RouterPrx.createProxy(communicator, "Glacier2/router:tcp -h localhost -p 4063");
29+
30+
// Create a session with the Glacier2 router. In this demo, the Glacier2 router is configured to accept any
31+
// username/password combination. This call establishes a network connection to the Glacier2 router; the
32+
// lifetime of the session is the same as the lifetime of the connection.
33+
SessionPrx session;
34+
try {
35+
session = router.createSession(System.getProperty("user.name"), "password");
36+
} catch (PermissionDeniedException | CannotCreateSessionException e) {
37+
System.out.println("Could not create session: " + e.getMessage());
38+
return;
39+
}
40+
41+
// The proxy returned by createSession is null because we did not configure a SessionManager on the Glacier2
42+
// router.
43+
assert session == null;
44+
45+
// Obtain a category string from the router. We need to use this category for the identity of
46+
// server->client callbacks invoked through the Glacier2 router.
47+
String clientCategory = router.getCategoryForClient();
48+
49+
// Create an object adapter with no name and no configuration, but with our router proxy. This object
50+
// adapter is a "bidirectional" object adapter, like the one created by the Ice/Bidir client application.
51+
// It does not listen on any port and it does not need to be activated.
52+
ObjectAdapter adapter = communicator.createObjectAdapterWithRouter("", router);
53+
54+
// Register the MockAlarmClock servant with the adapter. It uses the category retrieved from the router.
55+
// You can verify the Ring callback is never delivered if you provide a different category.
56+
var mockAlarmClock = new MockAlarmClock();
57+
AlarmClockPrx alarmClock = AlarmClockPrx.uncheckedCast(
58+
adapter.add(mockAlarmClock, new Identity("alarmClock", clientCategory)));
59+
60+
// Create a proxy to the wake-up service behind the Glacier2 router. Typically, the client cannot connect
61+
// directly to this server because it's on an unreachable network.
62+
WakeUpServicePrx wakeUpService = WakeUpServicePrx.createProxy(
63+
communicator,
64+
"wakeUpService:tcp -h localhost -p 4061");
65+
66+
// Configure the proxy to route requests using the Glacier2 router.
67+
wakeUpService = WakeUpServicePrx.uncheckedCast(wakeUpService.ice_router(router));
68+
69+
// Schedule a wake-up call in 5 seconds. This call establishes the connection to the server; incoming
70+
// requests over this connection are handled by the communicator's default object adapter.
71+
wakeUpService.wakeMeUp(alarmClock, Time.toTimeStamp(ZonedDateTime.now(ZoneOffset.UTC).plusSeconds(5)));
72+
System.out.println("Wake-up call scheduled, falling asleep...");
73+
try {
74+
// Wait until the user presses the stop button on the alarm clock.
75+
mockAlarmClock.stopPressed().get();
76+
System.out.println("Stop button pressed, exiting...");
77+
} catch (InterruptedException | ExecutionException ex) {
78+
System.err.println(ex);
79+
}
80+
}
81+
}
82+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright (c) ZeroC, Inc.
2+
3+
package com.example.glacier2.callback.client;
4+
5+
import java.util.concurrent.CompletableFuture;
6+
7+
import com.example.earlyriser.AlarmClock;
8+
import com.example.earlyriser.ButtonPressed;
9+
import com.zeroc.Ice.Current;
10+
11+
/**
12+
* MockAlarmClock is an Ice servant that implements Slice interface AlarmClock.
13+
*/
14+
class MockAlarmClock implements AlarmClock {
15+
private boolean _needMoreTime = true;
16+
17+
private final CompletableFuture<Void> _stopPressed;
18+
19+
public MockAlarmClock() {
20+
_stopPressed = new CompletableFuture<>();
21+
}
22+
23+
public CompletableFuture<Void> stopPressed() {
24+
return _stopPressed;
25+
}
26+
27+
// Implements the method ring from the AlarmClock interface generated by the Slice compiler.
28+
@Override
29+
public ButtonPressed ring(String message, Current current) {
30+
System.out.println("Dispatching ring request { message = '" + message + "' }");
31+
if (_needMoreTime) {
32+
System.out.println("Returning " + ButtonPressed.Snooze + " to request more time.");
33+
_needMoreTime = false; // we only snooze one time
34+
return ButtonPressed.Snooze;
35+
} else {
36+
_stopPressed.complete(null);
37+
System.out.println("Returning " + ButtonPressed.Stop + " to stop the alarm.");
38+
return ButtonPressed.Stop;
39+
}
40+
}
41+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Config file for glacier2router
2+
3+
# The client-visible endpoint of the Glacier2 router.
4+
Glacier2.Client.Endpoints=tcp -p 4063
5+
6+
# The server-visible endpoint of the Glacier2 router.
7+
# You need to configure this endpoint only when your servers make callbacks (call objects implemented by the clients).
8+
# If you don't use callbacks, don't set this property.
9+
Glacier2.Server.Endpoints=tcp -h 127.0.0.1
10+
11+
# This Glacier router accepts any username/password combination.
12+
Glacier2.PermissionsVerifier=Glacier2/NullPermissionsVerifier
13+
14+
# Turn on tracing.
15+
Glacier2.Client.Trace.Request=1
16+
Glacier2.Server.Trace.Request=1
17+
Glacier2.Trace.Session=1
18+
Glacier2.Trace.RoutingTable=1
42.6 KB
Binary file not shown.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
distributionBase=GRADLE_USER_HOME
2+
distributionPath=wrapper/dists
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-all.zip
4+
networkTimeout=10000
5+
validateDistributionUrl=true
6+
zipStoreBase=GRADLE_USER_HOME
7+
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)