diff --git a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/Messages.java b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/Messages.java
index b48e686d3b..9688a35962 100644
--- a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/Messages.java
+++ b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/Messages.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2019 European Spallation Source ERIC.
+ * Copyright (C) 2024 European Spallation Source ERIC.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -118,6 +118,8 @@ public class Messages {
public static String nodeSelectionForConfiguration;
public static String noValueAvailable;
public static String readbackPVName;
+ public static String restoreFailed;
+ public static String restoreFailedPVs;
public static String saveFilter;
public static String saveFilterConfirmOverwrite;
diff --git a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/client/SaveAndRestoreClient.java b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/client/SaveAndRestoreClient.java
index a95994721d..394e514bf5 100644
--- a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/client/SaveAndRestoreClient.java
+++ b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/client/SaveAndRestoreClient.java
@@ -231,4 +231,18 @@ public interface SaveAndRestoreClient {
* an exception.
*/
UserData authenticate(String userName, String password);
+
+ /**
+ * Requests service to restore the specified {@link SnapshotItem}s
+ * @param snapshotItems A {@link List} of {@link SnapshotItem}s
+ * @return A @{@link List} of {@link RestoreResult}s with information on potentially failed {@link SnapshotItem}s.
+ */
+ List restore(List snapshotItems);
+
+ /**
+ * Requests service to restore the specified snapshot.
+ * @param snapshotNodeId Unique id of a snapshot
+ * @return A @{@link List} of {@link RestoreResult}s with information on potentially failed {@link SnapshotItem}s.
+ */
+ List restore(String snapshotNodeId);
}
diff --git a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/client/SaveAndRestoreJerseyClient.java b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/client/SaveAndRestoreJerseyClient.java
index 53287edd87..7fd7d1ff8e 100644
--- a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/client/SaveAndRestoreJerseyClient.java
+++ b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/client/SaveAndRestoreJerseyClient.java
@@ -638,4 +638,55 @@ public UserData authenticate(String userName, String password) {
return response.getEntity(new GenericType<>() {
});
}
+
+ @Override
+ public List restore(List snapshotItems){
+ WebResource webResource =
+ getClient().resource(Preferences.jmasarServiceUrl + "/restore/items");
+ ClientResponse response;
+ try {
+ response = webResource.accept(CONTENT_TYPE_JSON)
+ .entity(snapshotItems, CONTENT_TYPE_JSON)
+ .post(ClientResponse.class);
+ } catch (UniformInterfaceException e) {
+ throw new RuntimeException(e);
+ }
+ if (response.getStatus() != ClientResponse.Status.OK.getStatusCode()) {
+ String message = "Restore failed";
+ try {
+ message = new String(response.getEntityInputStream().readAllBytes());
+ } catch (IOException e) {
+ logger.log(Level.WARNING, "Unable to parse response", e);
+ }
+ throw new SaveAndRestoreClientException(message);
+ }
+ return response.getEntity(new GenericType<>() {
+ });
+ }
+
+
+ public List restore(String snapshotNodeId){
+ WebResource webResource =
+ getClient()
+ .resource(Preferences.jmasarServiceUrl + "/restore/node")
+ .queryParam("codeId", snapshotNodeId);
+ ClientResponse response;
+ try {
+ response = webResource.accept(CONTENT_TYPE_JSON)
+ .post(ClientResponse.class);
+ } catch (UniformInterfaceException e) {
+ throw new RuntimeException(e);
+ }
+ if (response.getStatus() != ClientResponse.Status.OK.getStatusCode()) {
+ String message = "Restore failed";
+ try {
+ message = new String(response.getEntityInputStream().readAllBytes());
+ } catch (IOException e) {
+ logger.log(Level.WARNING, "Unable to parse response", e);
+ }
+ throw new SaveAndRestoreClientException(message);
+ }
+ return response.getEntity(new GenericType<>() {
+ });
+ }
}
diff --git a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreService.java b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreService.java
index fee17559ba..bafc1dd3b1 100644
--- a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreService.java
+++ b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreService.java
@@ -394,4 +394,26 @@ public UserData authenticate(String userName, String password) throws Exception{
executor.submit(() -> saveAndRestoreClient.authenticate(userName, password));
return future.get();
}
+
+ /**
+ * Requests service to restore the specified {@link SnapshotItem}s
+ * @param snapshotItems A {@link List} of {@link SnapshotItem}s
+ * @return A @{@link List} of {@link RestoreResult}s with information on potentially failed {@link SnapshotItem}s.
+ */
+ public List restore(List snapshotItems) throws Exception{
+ Future> future =
+ executor.submit(() -> saveAndRestoreClient.restore(snapshotItems));
+ return future.get();
+ }
+
+ /**
+ * Requests service to restore the specified snapshot.
+ * @param snapshotNodeId Unique id of a snapshot
+ * @return A @{@link List} of {@link RestoreResult}s with information on potentially failed {@link SnapshotItem}s.
+ */
+ public List restore(String snapshotNodeId) throws Exception{
+ Future> future =
+ executor.submit(() -> saveAndRestoreClient.restore(snapshotNodeId));
+ return future.get();
+ }
}
diff --git a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/snapshot/BaseSnapshotTableViewController.java b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/snapshot/BaseSnapshotTableViewController.java
index 035c832d79..a6d33c89f4 100644
--- a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/snapshot/BaseSnapshotTableViewController.java
+++ b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/snapshot/BaseSnapshotTableViewController.java
@@ -23,14 +23,21 @@
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
-import javafx.scene.control.*;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.ContextMenu;
+import javafx.scene.control.MenuItem;
+import javafx.scene.control.SelectionMode;
+import javafx.scene.control.SeparatorMenuItem;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableRow;
+import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
-
import org.epics.vtype.VType;
import org.phoebus.applications.saveandrestore.Messages;
import org.phoebus.applications.saveandrestore.SaveAndRestoreApplication;
@@ -42,18 +49,16 @@
import org.phoebus.ui.javafx.FocusUtil;
import org.phoebus.util.time.TimestampFormats;
-import java.lang.reflect.Field;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.time.Instant;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
-import static org.phoebus.ui.application.PhoebusApplication.logger;
-
/**
* Base controller class for the snapshot table view. It handles common items (UI components, methods) needed
* by all subclasses.
@@ -93,8 +98,6 @@ public abstract class BaseSnapshotTableViewController {
protected SnapshotController snapshotController;
- protected static boolean resizePolicyNotInitialized = true;
-
protected static final Logger LOGGER = Logger.getLogger(BaseSnapshotTableViewController.class.getName());
@FXML
@@ -127,27 +130,6 @@ public abstract class BaseSnapshotTableViewController {
*/
protected List snapshots = new ArrayList<>();
- public BaseSnapshotTableViewController() {
- if (resizePolicyNotInitialized) {
- AccessController.doPrivileged(resizePolicyAction);
- }
- }
-
- protected static PrivilegedAction