Skip to content

Commit 02441de

Browse files
authored
Merge pull request #3464 from JMit-dev/queue-server-application
Add base bluesky-queueserver code
2 parents d5a37cd + 8f1cff7 commit 02441de

File tree

71 files changed

+4793
-0
lines changed

Some content is hidden

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

71 files changed

+4793
-0
lines changed

app/queue-server/README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Java Bluesky Interface (JBI)
2+
3+
Prototype Java client for the [Bluesky QueueServer](https://blueskyproject.io/bluesky-queueserver/) REST API.
4+
It includes:
5+
6+
* **BlueskyHttpClient** – thread-safe singleton with rate-limiting, automatic retries and JUL logging
7+
* **BlueskyService** – one blocking call per API route
8+
* **CLI / REPL***testing utilities only*
9+
* **JavaFX UI** – the part you actually launch in normal use
10+
11+
---
12+
13+
## Prerequisites
14+
15+
* Java 17
16+
* Maven
17+
* Running Bluesky HTTP Server at `http://localhost:60610`
18+
*single-user API key `a` assumed below*
19+
20+
```bash
21+
# 1) Start RE Manager
22+
start-re-manager --use-ipython-kernel=ON --zmq-publish-console=ON
23+
24+
# 2) Start HTTP Server
25+
QSERVER_HTTP_SERVER_SINGLE_USER_API_KEY=a \
26+
uvicorn --host localhost --port 60610 bluesky_httpserver.server:app
27+
````
28+
29+
---
30+
31+
## Configure
32+
33+
```bash
34+
export BLUESKY_API_KEY=a
35+
```
36+
37+
---
38+
39+
## Build & run
40+
41+
```bash
42+
mvn clean javafx:run
43+
```
44+
45+
### Verbose logging
46+
47+
```bash
48+
mvn -Djava.util.logging.config.file=src/main/resources/logging.properties javafx:run
49+
```
50+
51+
---
52+
53+
## CLI / REPL (testing only)
54+
55+
| Tool | Start (quiet) | Start with request tracing (`FINE`) |
56+
| -------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
57+
| **CLI** | `mvn -q -Dexec.mainClass=util.org.phoebus.applications.queueserver.RunEngineCli -Dexec.args="STATUS" exec:java` | `mvn -Djava.util.logging.config.file=src/main/resources/logging.properties -q -Dexec.mainClass=util.org.phoebus.applications.queueserver.RunEngineCli -Dexec.args="STATUS" exec:java` |
58+
| **REPL** | `mvn -q -Dexec.mainClass=util.org.phoebus.applications.queueserver.RunEngineRepl exec:java` | `mvn -Djava.util.logging.config.file=src/main/resources/logging.properties -q -Dexec.mainClass=util.org.phoebus.applications.queueserver.RunEngineRepl -Dexec.args="STATUS" exec:java` |
59+
60+
*CLI examples*
61+
62+
```bash
63+
# list endpoints
64+
mvn -q -Dexec.mainClass=com.jbi.util.RunEngineClili -Dexec.args="list" exec:java
65+
66+
# start the queue
67+
mvn -q -Dexec.mainClass=com.jbi.util.RunEngineClili -Dexec.args="QUEUE_START" exec:java
68+
```
69+
70+
`ENDPOINT [body]` accepts a JSON literal, `@file.json`, or `@-` for stdin.
71+
72+
---
73+
74+
## How logging works
75+
76+
* Logger name: **`com.jbi.bluesky`**
77+
* Levels
78+
79+
* `INFO` – API errors
80+
* `WARNING` – transport retries
81+
* `FINE` – each HTTP call + latency
82+
* Enable by passing JVM flag
83+
`-Djava.util.logging.config.file=src/main/resources/logging.properties`
84+
85+
---
86+
87+
## Tuning
88+
89+
```java
90+
// rate limit (req/sec)
91+
BlueskyHttpClient.initialize("http://localhost:60610",
92+
System.getenv("BLUESKY_API_KEY"),
93+
3.0);
94+
95+
// retry/back-off
96+
// edit src/main/java/com/jbi/util/HttpSupport.java
97+
MAX_RETRIES = 5;
98+
INITIAL_BACKOFF_MS = 500;
99+
BACKOFF_MULTIPLIER = 1.5;
100+
```

app/queue-server/pom.xml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
4+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>org.phoebus</groupId>
9+
<artifactId>app</artifactId>
10+
<version>5.0.3-SNAPSHOT</version>
11+
</parent>
12+
13+
<artifactId>app-queue-monitor</artifactId>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>org.phoebus</groupId>
18+
<artifactId>core-framework</artifactId>
19+
<version>${project.version}</version>
20+
</dependency>
21+
<dependency>
22+
<groupId>org.phoebus</groupId>
23+
<artifactId>core-ui</artifactId>
24+
<version>${project.version}</version>
25+
</dependency>
26+
<dependency>
27+
<groupId>org.phoebus</groupId>
28+
<artifactId>core-types</artifactId>
29+
<version>${project.version}</version>
30+
</dependency>
31+
32+
<!-- Anything _extra_ you need that Phoebus core does NOT ship -->
33+
<dependency>
34+
<groupId>com.fasterxml.jackson.dataformat</groupId>
35+
<artifactId>jackson-dataformat-yaml</artifactId>
36+
<version>2.19.1</version>
37+
</dependency>
38+
</dependencies>
39+
</project>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.phoebus.applications.queueserver;
2+
3+
import org.phoebus.framework.nls.NLS;
4+
5+
/** Externalised strings for Queue-Monitor plug-in */
6+
@SuppressWarnings("nls")
7+
public final class Messages {
8+
9+
// ---------- keep alphabetically sorted ----------
10+
public static String QueueServer; // display name
11+
public static String QueueServerMenuPath; // menu path
12+
// -----------------------------------------------
13+
14+
static { NLS.initializeMessages(Messages.class); }
15+
16+
private Messages() { /* no-instantiation */ }
17+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (C) 2024 European Spallation Source ERIC.
3+
*/
4+
5+
package org.phoebus.applications.queueserver;
6+
7+
import org.phoebus.framework.preferences.AnnotatedPreferences;
8+
import org.phoebus.framework.preferences.Preference;
9+
10+
public class Preferences {
11+
12+
@Preference
13+
public static String queue_server_url;
14+
15+
@Preference
16+
public static String api_key;
17+
18+
@Preference
19+
public static boolean debug;
20+
21+
@Preference
22+
public static int connectTimeout;
23+
24+
static
25+
{
26+
AnnotatedPreferences.initialize(Preferences.class, "/queueserver_preferences.properties");
27+
}
28+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.phoebus.applications.queueserver;
2+
3+
import java.net.URL;
4+
import java.util.logging.Logger;
5+
6+
import org.phoebus.applications.queueserver.client.RunEngineHttpClient;
7+
import org.phoebus.applications.queueserver.view.ViewFactory;
8+
import javafx.scene.Parent;
9+
10+
import org.phoebus.framework.spi.AppInstance;
11+
import org.phoebus.framework.spi.AppResourceDescriptor;
12+
import org.phoebus.framework.workbench.ApplicationService;
13+
import org.phoebus.ui.docking.DockItem;
14+
import org.phoebus.ui.docking.DockPane;
15+
16+
@SuppressWarnings("nls")
17+
public final class QueueServerApp implements AppResourceDescriptor {
18+
19+
public static final Logger LOGGER = Logger.getLogger(QueueServerApp.class.getPackageName());
20+
21+
public static final String NAME = "queue-server";
22+
private static final String DISPLAY_NAME = "Queue Server";
23+
24+
@Override public String getName() { return NAME; }
25+
@Override public String getDisplayName() { return DISPLAY_NAME; }
26+
27+
@Override public URL getIconURL() {
28+
return getClass().getResource("/icons/bluesky.png"); // add one or reuse probe.png
29+
}
30+
31+
@Override public AppInstance create() {
32+
33+
RunEngineHttpClient.initialize(Preferences.queue_server_url, Preferences.api_key);
34+
35+
Parent root = ViewFactory.APPLICATION.get();
36+
37+
QueueServerInstance inst = new QueueServerInstance(this, root);
38+
39+
DockItem tab = new DockItem(inst, root);
40+
DockPane.getActiveDockPane().addTab(tab);
41+
42+
return inst;
43+
}
44+
45+
@Override public AppInstance create(java.net.URI resource) {
46+
return ApplicationService.createInstance(NAME);
47+
}
48+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.phoebus.applications.queueserver;
2+
3+
import javafx.scene.Node;
4+
import org.phoebus.framework.persistence.Memento;
5+
import org.phoebus.framework.spi.AppDescriptor;
6+
import org.phoebus.framework.spi.AppInstance;
7+
8+
final class QueueServerInstance implements AppInstance {
9+
10+
private final AppDescriptor desc;
11+
private final Node view;
12+
13+
QueueServerInstance(AppDescriptor desc, Node view) {
14+
this.desc = desc;
15+
this.view = view;
16+
}
17+
18+
@Override public AppDescriptor getAppDescriptor() { return desc; }
19+
public Node create() { return view; }
20+
21+
@Override public void restore(Memento m) { /* nothing */ }
22+
@Override public void save (Memento m) { /* nothing */ }
23+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.phoebus.applications.queueserver;
2+
3+
import org.phoebus.framework.workbench.ApplicationService;
4+
import org.phoebus.ui.javafx.ImageCache;
5+
import org.phoebus.ui.spi.MenuEntry;
6+
import javafx.scene.image.Image;
7+
8+
public final class QueueServerMenuEntry implements MenuEntry {
9+
10+
@Override public String getName() { return Messages.QueueServer; }
11+
@Override public Image getIcon() { return ImageCache.getImage(
12+
QueueServerApp.class,
13+
"/icons/bluesky.png"); } // same icon as descriptor
14+
@Override public String getMenuPath() { return Messages.QueueServerMenuPath; }
15+
16+
@Override public Void call() throws Exception {
17+
ApplicationService.createInstance(QueueServerApp.NAME);
18+
return null;
19+
}
20+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.phoebus.applications.queueserver.api;
2+
3+
public record ConsoleOutputText(
4+
boolean success,
5+
String msg,
6+
String text
7+
) {}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.phoebus.applications.queueserver.api;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
public record ConsoleOutputUid(
6+
boolean success,
7+
String msg,
8+
@JsonProperty("console_output_uid")
9+
String uid
10+
) {}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.phoebus.applications.queueserver.api;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
5+
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
public record ConsoleOutputUpdate(
10+
boolean success,
11+
String msg,
12+
@JsonProperty("console_output_msgs")
13+
List<Map<String,Object>> consoleOutputMsgs,
14+
@JsonProperty("last_msg_uid")
15+
String lastMsgUid
16+
) {}

0 commit comments

Comments
 (0)