Add model group implementation for client server setup

This commit is contained in:
0xb00bface 2021-05-13 13:19:32 +02:00
parent c49a7db192
commit ba21dd2aeb
13 changed files with 217 additions and 67 deletions

View File

@ -1,6 +1,8 @@
package ctbrec.ui.action; package ctbrec.ui.action;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@ -49,7 +51,7 @@ public class AddToGroupAction {
if (StringUtil.isBlank(text)) { if (StringUtil.isBlank(text)) {
return; return;
} }
Set<ModelGroup> modelGroups = Config.getInstance().getSettings().modelGroups; Set<ModelGroup> modelGroups = recorder.getModelGroups();
Optional<ModelGroup> existingGroup = modelGroups.stream().filter(mg -> mg.getName().equalsIgnoreCase(text)).findFirst(); Optional<ModelGroup> existingGroup = modelGroups.stream().filter(mg -> mg.getName().equalsIgnoreCase(text)).findFirst();
if (existingGroup.isPresent()) { if (existingGroup.isPresent()) {
existingGroup.get().add(model); existingGroup.get().add(model);
@ -63,7 +65,7 @@ public class AddToGroupAction {
recorder.saveModelGroup(group); recorder.saveModelGroup(group);
} }
} }
} catch (IOException e) { } catch (IOException | InvalidKeyException | NoSuchAlgorithmException e) {
Dialogs.showError(source.getScene(), "Add model to group", "Saving model group failed", e); Dialogs.showError(source.getScene(), "Add model to group", "Saving model group failed", e);
} finally { } finally {
source.setCursor(Cursor.DEFAULT); source.setCursor(Cursor.DEFAULT);

View File

@ -1,10 +1,12 @@
package ctbrec.ui.action; package ctbrec.ui.action;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import ctbrec.Config;
import ctbrec.Model; import ctbrec.Model;
import ctbrec.ModelGroup; import ctbrec.ModelGroup;
import ctbrec.recorder.Recorder; import ctbrec.recorder.Recorder;
@ -47,6 +49,12 @@ public class EditGroupAction {
group.getModelUrls().clear(); group.getModelUrls().clear();
group.getModelUrls().addAll(dialog.getUrls()); group.getModelUrls().addAll(dialog.getUrls());
recorder.saveModelGroup(group); recorder.saveModelGroup(group);
if (dialog.getUrls().isEmpty()) {
boolean delete = Dialogs.showConfirmDialog(DIALOG_TITLE, "Do you want to delete the group?", "Group is empty", source.getScene());
if (delete) {
recorder.deleteModelGroup(group);
}
}
} }
} catch (Exception e) { } catch (Exception e) {
Dialogs.showError(source.getScene(), DIALOG_TITLE, "Editing model group failed", e); Dialogs.showError(source.getScene(), DIALOG_TITLE, "Editing model group failed", e);
@ -55,7 +63,7 @@ public class EditGroupAction {
} }
} }
private static class EditModelGroupDialog extends GridPane { private class EditModelGroupDialog extends GridPane {
private TextField groupName; private TextField groupName;
private ListView<String> urlListView; private ListView<String> urlListView;
private ObservableList<String> urlList; private ObservableList<String> urlList;
@ -63,13 +71,18 @@ public class EditGroupAction {
private List<String> urls; private List<String> urls;
public EditModelGroupDialog(Model model) { public EditModelGroupDialog(Model model) {
Optional<ModelGroup> optionalModelGroup = Config.getInstance().getModelGroup(model); Optional<ModelGroup> optionalModelGroup;
if (optionalModelGroup.isPresent()) { try {
modelGroup = optionalModelGroup.get(); optionalModelGroup = recorder.getModelGroup(model);
urls = new ArrayList<>(modelGroup.getModelUrls()); if (optionalModelGroup.isPresent()) {
createGui(modelGroup); modelGroup = optionalModelGroup.get();
} else { urls = new ArrayList<>(modelGroup.getModelUrls());
Dialogs.showError(getScene(), DIALOG_TITLE, "No group found for model", null); createGui(modelGroup);
} else {
Dialogs.showError(getScene(), DIALOG_TITLE, "No group found for model", null);
}
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
Dialogs.showError(getScene(), DIALOG_TITLE, "Couldn't edit model group", e);
} }
} }

View File

@ -4,6 +4,8 @@ import static ctbrec.ui.controls.Dialogs.*;
import java.io.IOException; import java.io.IOException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -46,6 +48,7 @@ import ctbrec.ui.action.IgnoreModelsAction;
import ctbrec.ui.action.OpenRecordingsDir; import ctbrec.ui.action.OpenRecordingsDir;
import ctbrec.ui.action.SetStopDateAction; import ctbrec.ui.action.SetStopDateAction;
import ctbrec.ui.controls.CustomMouseBehaviorContextMenu; import ctbrec.ui.controls.CustomMouseBehaviorContextMenu;
import ctbrec.ui.controls.Dialogs;
import ctbrec.ui.controls.FasterVerticalScrollPaneSkin; import ctbrec.ui.controls.FasterVerticalScrollPaneSkin;
import ctbrec.ui.controls.SearchBox; import ctbrec.ui.controls.SearchBox;
import ctbrec.ui.controls.SearchPopover; import ctbrec.ui.controls.SearchPopover;
@ -543,7 +546,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
if (site.supportsTips()) { if (site.supportsTips()) {
contextMenu.getItems().add(sendTip); contextMenu.getItems().add(sendTip);
} }
Optional<ModelGroup> modelGroup = Config.getInstance().getModelGroup(model); Optional<ModelGroup> modelGroup = getModelGroup(model);
contextMenu.getItems().add(modelGroup.isEmpty() ? addToGroup : editGroup); contextMenu.getItems().add(modelGroup.isEmpty() ? addToGroup : editGroup);
contextMenu.getItems().addAll(copyUrl, openInBrowser, ignore, refresh, openRecDir); contextMenu.getItems().addAll(copyUrl, openInBrowser, ignore, refresh, openRecDir);
if (model instanceof MyFreeCamsModel && Objects.equals(System.getenv("CTBREC_DEV"), "1")) { if (model instanceof MyFreeCamsModel && Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
@ -555,6 +558,15 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
return contextMenu; return contextMenu;
} }
private Optional<ModelGroup> getModelGroup(Model model) {
try {
return recorder.getModelGroup(model);
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
Dialogs.showError(grid.getScene(), "Error", "Couldn't get model group for model " + model, e);
return Optional.empty();
}
}
private void editGroup(Model model) { private void editGroup(Model model) {
new EditGroupAction(this.getContent(), recorder, model).execute(); new EditGroupAction(this.getContent(), recorder, model).execute();
} }

View File

@ -1,5 +1,13 @@
package ctbrec.ui.tabs; package ctbrec.ui.tabs;
import static ctbrec.ui.controls.Dialogs.*;
import java.io.IOException;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.Model; import ctbrec.Model;
import ctbrec.sites.Site; import ctbrec.sites.Site;
import ctbrec.ui.SiteUiFactory; import ctbrec.ui.SiteUiFactory;
@ -7,13 +15,6 @@ import ctbrec.ui.controls.SearchPopover;
import ctbrec.ui.controls.SearchPopoverTreeList; import ctbrec.ui.controls.SearchPopoverTreeList;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.List;
import static ctbrec.ui.controls.Dialogs.showError;
public class ThumbOverviewTabSearchTask extends Task<List<Model>> { public class ThumbOverviewTabSearchTask extends Task<List<Model>> {

View File

@ -2,19 +2,26 @@ package ctbrec.ui.tabs.recorded;
import static ctbrec.ui.Icon.*; import static ctbrec.ui.Icon.*;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import ctbrec.Config;
import ctbrec.Model; import ctbrec.Model;
import ctbrec.ModelGroup; import ctbrec.ModelGroup;
import ctbrec.recorder.Recorder;
import ctbrec.ui.controls.Dialogs;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
public class ModelNameTableCell extends IconTableCell<String> { public class ModelNameTableCell extends IconTableCell<String> {
public ModelNameTableCell() { private Recorder recorder;
public ModelNameTableCell(Recorder recorder) {
super(Map.of(GROUP_16, new ImageView(GROUP_16.url()))); super(Map.of(GROUP_16, new ImageView(GROUP_16.url())));
this.recorder = recorder;
} }
@Override @Override
@ -26,7 +33,7 @@ public class ModelNameTableCell extends IconTableCell<String> {
if (item != null && !empty) { if (item != null && !empty) {
setText(item); setText(item);
Model m = getTableView().getItems().get(getTableRow().getIndex()); Model m = getTableView().getItems().get(getTableRow().getIndex());
Optional<ModelGroup> optionalGroup = Config.getInstance().getModelGroup(m); Optional<ModelGroup> optionalGroup = getModelGroup(m);
if (optionalGroup.isPresent()) { if (optionalGroup.isPresent()) {
ModelGroup group = optionalGroup.get(); ModelGroup group = optionalGroup.get();
setText(group.getName() + " (aka " + item + ')'); setText(group.getName() + " (aka " + item + ')');
@ -37,4 +44,13 @@ public class ModelNameTableCell extends IconTableCell<String> {
} }
super.updateItem(item, empty); super.updateItem(item, empty);
} }
private Optional<ModelGroup> getModelGroup(Model model) {
try {
return recorder.getModelGroup(model);
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
Dialogs.showError(getScene(), "Error", "Couldn't get model group for model " + model, e);
return Optional.empty();
}
}
} }

View File

@ -173,7 +173,7 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
TableColumn<JavaFxModel, String> name = new TableColumn<>("Model"); TableColumn<JavaFxModel, String> name = new TableColumn<>("Model");
name.setPrefWidth(200); name.setPrefWidth(200);
name.setCellValueFactory(new PropertyValueFactory<>("displayName")); name.setCellValueFactory(new PropertyValueFactory<>("displayName"));
name.setCellFactory(param -> new ModelNameTableCell()); name.setCellFactory(param -> new ModelNameTableCell(recorder));
name.setEditable(false); name.setEditable(false);
name.setId("name"); name.setId("name");
TableColumn<JavaFxModel, String> url = new TableColumn<>("URL"); TableColumn<JavaFxModel, String> url = new TableColumn<>("URL");
@ -694,7 +694,7 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
} else { } else {
menu.getItems().addAll(resumeRecording, pauseRecording); menu.getItems().addAll(resumeRecording, pauseRecording);
} }
Optional<ModelGroup> modelGroup = Config.getInstance().getModelGroup(selectedModels.get(0)); Optional<ModelGroup> modelGroup = getModelGroup(selectedModels.get(0));
menu.getItems().add(modelGroup.isEmpty() ? addToGroup : editGroup); menu.getItems().add(modelGroup.isEmpty() ? addToGroup : editGroup);
menu.getItems().addAll(copyUrl, openInPlayer, openInBrowser, openRecDir, switchStreamSource, follow, notes, ignore); menu.getItems().addAll(copyUrl, openInPlayer, openInBrowser, openRecDir, switchStreamSource, follow, notes, ignore);
@ -709,6 +709,15 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
return menu; return menu;
} }
private Optional<ModelGroup> getModelGroup(Model model) {
try {
return recorder.getModelGroup(model);
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
Dialogs.showError(grid.getScene(), "Error", "Couldn't get model group for model " + model, e);
return Optional.empty();
}
}
private void addToGroup(Model model) { private void addToGroup(Model model) {
new AddToGroupAction(this.getContent(), recorder, model).execute(); new AddToGroupAction(this.getContent(), recorder, model).execute();
table.refresh(); table.refresh();

View File

@ -311,10 +311,4 @@ public class Config {
public void enableSaving() { public void enableSaving() {
savingDisabled = false; savingDisabled = false;
} }
public Optional<ModelGroup> getModelGroup(Model model) {
return getSettings().modelGroups.stream()
.filter(mg -> mg.getModelUrls().contains(model.getUrl()))
.findFirst();
}
} }

View File

@ -783,16 +783,6 @@ public class NextGenLocalRecorder implements Recorder {
return config.getSettings().modelGroups; return config.getSettings().modelGroups;
} }
@Override
public Optional<ModelGroup> getModelGroup(UUID id) {
for (ModelGroup group : getModelGroups()) {
if (Objects.equals(group.getId(), id)) {
return Optional.of(group);
}
}
return Optional.empty();
}
@Override @Override
public void saveModelGroup(ModelGroup group) throws IOException { public void saveModelGroup(ModelGroup group) throws IOException {
Set<ModelGroup> modelGroups = config.getSettings().modelGroups; Set<ModelGroup> modelGroups = config.getSettings().modelGroups;

View File

@ -6,7 +6,6 @@ import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import ctbrec.Model; import ctbrec.Model;
@ -153,17 +152,23 @@ public interface Recorder {
*/ */
public int getModelCount(); public int getModelCount();
public Set<ModelGroup> getModelGroups(); public Set<ModelGroup> getModelGroups() throws InvalidKeyException, NoSuchAlgorithmException, IOException;
/** /**
* Saves a model group. If the group already exists, it will be overwritten. Otherwise it will * Saves a model group. If the group already exists, it will be overwritten. Otherwise it will
* be saved as a new group. * be saved as a new group.
* @param group * @param group
* @throws IOException * @throws IOException
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/ */
public void saveModelGroup(ModelGroup group) throws IOException; public void saveModelGroup(ModelGroup group) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
public Optional<ModelGroup> getModelGroup(UUID uuid); public void deleteModelGroup(ModelGroup group) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
public void deleteModelGroup(ModelGroup group) throws IOException; default Optional<ModelGroup> getModelGroup(Model model) throws InvalidKeyException, NoSuchAlgorithmException, IOException {
return getModelGroups().stream()
.filter(mg -> mg.getModelUrls().contains(model.getUrl()))
.findFirst();
}
} }

View File

@ -137,7 +137,7 @@ public class RecordingPreconditions {
} }
private void ensureNoOtherFromModelGroupIsRecording(Model model) throws InvalidKeyException, NoSuchAlgorithmException, IOException { private void ensureNoOtherFromModelGroupIsRecording(Model model) throws InvalidKeyException, NoSuchAlgorithmException, IOException {
Optional<ModelGroup> modelGroup = Config.getInstance().getModelGroup(model); Optional<ModelGroup> modelGroup = recorder.getModelGroup(model);
if (modelGroup.isPresent()) { if (modelGroup.isPresent()) {
for (String modelUrl : modelGroup.get().getModelUrls()) { for (String modelUrl : modelGroup.get().getModelUrls()) {
if (modelUrl.equals(model.getUrl())) { if (modelUrl.equals(model.getUrl())) {

View File

@ -9,9 +9,9 @@ import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -37,6 +37,7 @@ import ctbrec.io.HttpClient;
import ctbrec.io.HttpException; import ctbrec.io.HttpException;
import ctbrec.io.InstantJsonAdapter; import ctbrec.io.InstantJsonAdapter;
import ctbrec.io.ModelJsonAdapter; import ctbrec.io.ModelJsonAdapter;
import ctbrec.io.UuidJSonAdapter;
import ctbrec.sites.Site; import ctbrec.sites.Site;
import okhttp3.MediaType; import okhttp3.MediaType;
import okhttp3.Request; import okhttp3.Request;
@ -56,16 +57,20 @@ public class RemoteRecorder implements Recorder {
.add(Instant.class, new InstantJsonAdapter()) .add(Instant.class, new InstantJsonAdapter())
.add(Model.class, new ModelJsonAdapter()) .add(Model.class, new ModelJsonAdapter())
.add(File.class, new FileJsonAdapter()) .add(File.class, new FileJsonAdapter())
.add(UUID.class, new UuidJSonAdapter())
.build(); .build();
private JsonAdapter<ModelListResponse> modelListResponseAdapter = moshi.adapter(ModelListResponse.class); private JsonAdapter<ModelListResponse> modelListResponseAdapter = moshi.adapter(ModelListResponse.class);
private JsonAdapter<RecordingListResponse> recordingListResponseAdapter = moshi.adapter(RecordingListResponse.class); private JsonAdapter<RecordingListResponse> recordingListResponseAdapter = moshi.adapter(RecordingListResponse.class);
private JsonAdapter<ModelRequest> modelRequestAdapter = moshi.adapter(ModelRequest.class); private JsonAdapter<ModelRequest> modelRequestAdapter = moshi.adapter(ModelRequest.class);
private JsonAdapter<ModelGroupRequest> modelGroupRequestAdapter = moshi.adapter(ModelGroupRequest.class);
private JsonAdapter<ModelGroupListResponse> modelGroupListResponseAdapter = moshi.adapter(ModelGroupListResponse.class);
private JsonAdapter<RecordingRequest> recordingRequestAdapter = moshi.adapter(RecordingRequest.class); private JsonAdapter<RecordingRequest> recordingRequestAdapter = moshi.adapter(RecordingRequest.class);
private JsonAdapter<SimpleResponse> simpleResponseAdapter = moshi.adapter(SimpleResponse.class); private JsonAdapter<SimpleResponse> simpleResponseAdapter = moshi.adapter(SimpleResponse.class);
private List<Model> models = Collections.emptyList(); private List<Model> models = Collections.emptyList();
private List<Model> onlineModels = Collections.emptyList(); private List<Model> onlineModels = Collections.emptyList();
private List<Recording> recordings = Collections.emptyList(); private List<Recording> recordings = Collections.emptyList();
private Set<ModelGroup> modelGroups = new HashSet<>();
private List<Site> sites; private List<Site> sites;
private long spaceTotal = -1; private long spaceTotal = -1;
private long spaceFree = -1; private long spaceFree = -1;
@ -106,7 +111,7 @@ public class RemoteRecorder implements Recorder {
private Optional<String> sendRequest(String action) throws IOException, InvalidKeyException, NoSuchAlgorithmException { private Optional<String> sendRequest(String action) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
String msg = "{\"action\": \"" + action + "\"}"; String msg = "{\"action\": \"" + action + "\"}";
LOG.debug("Sending request to recording server: {}", msg); LOG.trace("Sending request to recording server: {}", msg);
RequestBody requestBody = RequestBody.Companion.create(msg, JSON); RequestBody requestBody = RequestBody.Companion.create(msg, JSON);
Request.Builder builder = new Request.Builder().url(getRecordingEndpoint()).post(requestBody); Request.Builder builder = new Request.Builder().url(getRecordingEndpoint()).post(requestBody);
addHmacIfNeeded(msg, builder); addHmacIfNeeded(msg, builder);
@ -124,7 +129,7 @@ public class RemoteRecorder implements Recorder {
private void sendRequest(String action, Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException { private void sendRequest(String action, Model model) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
String payload = modelRequestAdapter.toJson(new ModelRequest(action, model)); String payload = modelRequestAdapter.toJson(new ModelRequest(action, model));
LOG.debug("Sending request to recording server: {}", payload); LOG.trace("Sending request to recording server: {}", payload);
RequestBody body = RequestBody.Companion.create(payload, JSON); RequestBody body = RequestBody.Companion.create(payload, JSON);
Request.Builder builder = new Request.Builder().url(getRecordingEndpoint()).post(body); Request.Builder builder = new Request.Builder().url(getRecordingEndpoint()).post(body);
addHmacIfNeeded(payload, builder); addHmacIfNeeded(payload, builder);
@ -154,6 +159,7 @@ public class RemoteRecorder implements Recorder {
String msg = recordingRequestAdapter.toJson(recReq); String msg = recordingRequestAdapter.toJson(recReq);
RequestBody body = RequestBody.Companion.create(msg, JSON); RequestBody body = RequestBody.Companion.create(msg, JSON);
Request.Builder builder = new Request.Builder().url(getRecordingEndpoint()).post(body); Request.Builder builder = new Request.Builder().url(getRecordingEndpoint()).post(body);
LOG.trace("Sending request to recording server: {}", msg);
addHmacIfNeeded(msg, builder); addHmacIfNeeded(msg, builder);
Request request = builder.build(); Request request = builder.build();
try (Response response = client.execute(request)) { try (Response response = client.execute(request)) {
@ -173,6 +179,33 @@ public class RemoteRecorder implements Recorder {
} }
} }
private void sendRequest(String action, ModelGroup model) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
String payload = modelGroupRequestAdapter.toJson(new ModelGroupRequest(action, model));
LOG.trace("Sending request to recording server: {}", payload);
RequestBody body = RequestBody.Companion.create(payload, JSON);
Request.Builder builder = new Request.Builder().url(getRecordingEndpoint()).post(body);
addHmacIfNeeded(payload, builder);
Request request = builder.build();
try (Response response = client.execute(request)) {
if (response.isSuccessful()) {
String json = response.body().string();
updateModelGroups(json);
} else {
throw new HttpException(response.code(), response.message());
}
}
}
private void updateModelGroups(String responseBody) throws IOException {
ModelGroupListResponse resp = modelGroupListResponseAdapter.fromJson(responseBody);
if (!resp.status.equals(SUCCESS)) {
throw new IOException("Server returned error " + resp.status + " " + resp.msg);
}
modelGroups.clear();
modelGroups.addAll(resp.groups);
}
private void addHmacIfNeeded(String msg, Builder builder) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException { private void addHmacIfNeeded(String msg, Builder builder) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
if (Config.getInstance().getSettings().requireAuthentication) { if (Config.getInstance().getSettings().requireAuthentication) {
byte[] key = Config.getInstance().getSettings().key; byte[] key = Config.getInstance().getSettings().key;
@ -240,10 +273,25 @@ public class RemoteRecorder implements Recorder {
syncOnlineModels(); syncOnlineModels();
syncSpace(); syncSpace();
syncRecordings(); syncRecordings();
syncModelGroups();
sleep(); sleep();
} }
} }
private void syncModelGroups() {
try {
sendRequest("listModelGroups").ifPresent(body -> {
try {
updateModelGroups(body);
} catch (IOException e) {
LOG.error("Error while loading model groups from server", e);
}
});
} catch (IOException | InvalidKeyException | NoSuchAlgorithmException e) {
LOG.error("Error while loading model groups from server", e);
}
}
private void syncSpace() { private void syncSpace() {
try { try {
String msg = "{\"action\": \"space\"}"; String msg = "{\"action\": \"space\"}";
@ -427,6 +475,12 @@ public class RemoteRecorder implements Recorder {
public List<Model> models; public List<Model> models;
} }
private static class ModelGroupListResponse {
public String status;
public String msg;
public List<ModelGroup> groups;
}
private static class SimpleResponse { private static class SimpleResponse {
public String status; public String status;
public String msg; public String msg;
@ -475,6 +529,33 @@ public class RemoteRecorder implements Recorder {
} }
} }
public static class ModelGroupRequest {
private String action;
private ModelGroup modelGroup;
public ModelGroupRequest(String action, ModelGroup modelGroup) {
super();
this.action = action;
this.modelGroup = modelGroup;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public ModelGroup getModelGroup() {
return modelGroup;
}
public void setModelGroup(ModelGroup model) {
this.modelGroup = model;
}
}
public static class RecordingRequest { public static class RecordingRequest {
private String action; private String action;
private Recording recording; private Recording recording;
@ -609,28 +690,17 @@ public class RemoteRecorder implements Recorder {
} }
@Override @Override
public Set<ModelGroup> getModelGroups() { public Set<ModelGroup> getModelGroups() throws InvalidKeyException, NoSuchAlgorithmException, IOException {
// TODO Auto-generated method stub return modelGroups;
return null;
} }
@Override @Override
public void saveModelGroup(ModelGroup group) { public void saveModelGroup(ModelGroup group) throws InvalidKeyException, NoSuchAlgorithmException, IOException {
// TODO Auto-generated method stub sendRequest("saveModelGroup", group);
} }
@Override @Override
public void deleteModelGroup(ModelGroup group) { public void deleteModelGroup(ModelGroup group) throws InvalidKeyException, NoSuchAlgorithmException, IOException {
// TODO Auto-generated method stub sendRequest("deleteModelGroup", group);
}
@Override
public Optional<ModelGroup> getModelGroup(UUID id) {
for (ModelGroup group : getModelGroups()) {
if (Objects.equals(group.getId(), id)) {
return Optional.of(group);
}
}
return Optional.empty();
} }
} }

View File

@ -3,6 +3,9 @@ package ctbrec.recorder.postprocessing;
import static ctbrec.StringUtil.*; import static ctbrec.StringUtil.*;
import static java.util.Optional.*; import static java.util.Optional.*;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant; import java.time.Instant;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZoneOffset; import java.time.ZoneOffset;
@ -15,6 +18,9 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.Config; import ctbrec.Config;
import ctbrec.Model; import ctbrec.Model;
import ctbrec.ModelGroup; import ctbrec.ModelGroup;
@ -24,10 +30,18 @@ import ctbrec.sites.Site;
public abstract class AbstractPlaceholderAwarePostProcessor extends AbstractPostProcessor { public abstract class AbstractPlaceholderAwarePostProcessor extends AbstractPostProcessor {
private static final Logger LOG = LoggerFactory.getLogger(AbstractPlaceholderAwarePostProcessor.class);
public String fillInPlaceHolders(String input, PostProcessingContext ctx) { public String fillInPlaceHolders(String input, PostProcessingContext ctx) {
Recording rec = ctx.getRecording(); Recording rec = ctx.getRecording();
Config config = ctx.getConfig(); Config config = ctx.getConfig();
Optional<ModelGroup> modelGroup = config.getModelGroup(rec.getModel()); Optional<ModelGroup> modelGroup;
try {
modelGroup = ctx.getRecorder().getModelGroup(rec.getModel());
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
LOG.error("Couldn't get model group for {}", rec.getModel(), e);
return input;
}
Map<String, Function<String, Optional<String>>> placeholderValueSuppliers = new HashMap<>(); Map<String, Function<String, Optional<String>>> placeholderValueSuppliers = new HashMap<>();
placeholderValueSuppliers.put("modelName", r -> ofNullable(rec.getModel().getName())); placeholderValueSuppliers.put("modelName", r -> ofNullable(rec.getModel().getName()));

View File

@ -10,6 +10,8 @@ import java.time.Instant;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@ -25,11 +27,13 @@ import com.squareup.moshi.Moshi;
import ctbrec.Config; import ctbrec.Config;
import ctbrec.GlobalThreadPool; import ctbrec.GlobalThreadPool;
import ctbrec.Model; import ctbrec.Model;
import ctbrec.ModelGroup;
import ctbrec.Recording; import ctbrec.Recording;
import ctbrec.io.BandwidthMeter; import ctbrec.io.BandwidthMeter;
import ctbrec.io.FileJsonAdapter; import ctbrec.io.FileJsonAdapter;
import ctbrec.io.InstantJsonAdapter; import ctbrec.io.InstantJsonAdapter;
import ctbrec.io.ModelJsonAdapter; import ctbrec.io.ModelJsonAdapter;
import ctbrec.io.UuidJSonAdapter;
import ctbrec.recorder.Recorder; import ctbrec.recorder.Recorder;
import ctbrec.sites.Site; import ctbrec.sites.Site;
@ -67,6 +71,7 @@ public class RecorderServlet extends AbstractCtbrecServlet {
.add(Instant.class, new InstantJsonAdapter()) .add(Instant.class, new InstantJsonAdapter())
.add(Model.class, new ModelJsonAdapter(sites)) .add(Model.class, new ModelJsonAdapter(sites))
.add(File.class, new FileJsonAdapter()) .add(File.class, new FileJsonAdapter())
.add(UUID.class, new UuidJSonAdapter())
.build(); .build();
JsonAdapter<Request> requestAdapter = moshi.adapter(Request.class); JsonAdapter<Request> requestAdapter = moshi.adapter(Request.class);
Request request = requestAdapter.fromJson(json); Request request = requestAdapter.fromJson(json);
@ -234,6 +239,17 @@ public class RecorderServlet extends AbstractCtbrecServlet {
response = "{\"status\": \"success\"}"; response = "{\"status\": \"success\"}";
resp.getWriter().write(response); resp.getWriter().write(response);
break; break;
case "saveModelGroup":
recorder.saveModelGroup(request.modelGroup);
sendModelGroups(resp, recorder.getModelGroups());
break;
case "deleteModelGroup":
recorder.deleteModelGroup(request.modelGroup);
sendModelGroups(resp, recorder.getModelGroups());
break;
case "listModelGroups":
sendModelGroups(resp, recorder.getModelGroups());
break;
default: default:
resp.setStatus(SC_BAD_REQUEST); resp.setStatus(SC_BAD_REQUEST);
response = "{\"status\": \"error\", \"msg\": \"Unknown action ["+request.action+"]\"}"; response = "{\"status\": \"error\", \"msg\": \"Unknown action ["+request.action+"]\"}";
@ -258,6 +274,13 @@ public class RecorderServlet extends AbstractCtbrecServlet {
} }
} }
private void sendModelGroups(HttpServletResponse resp, Set<ModelGroup> modelGroups) throws IOException {
JSONObject jsonResponse = new JSONObject();
jsonResponse.put("status", "success");
jsonResponse.put("groups", modelGroups);
resp.getWriter().write(jsonResponse.toString());
}
private void startByUrl(Request request) throws InvalidKeyException, NoSuchAlgorithmException, IOException { private void startByUrl(Request request) throws InvalidKeyException, NoSuchAlgorithmException, IOException {
String url = request.model.getUrl(); String url = request.model.getUrl();
for (Site site : sites) { for (Site site : sites) {
@ -291,5 +314,6 @@ public class RecorderServlet extends AbstractCtbrecServlet {
public String action; public String action;
public Model model; public Model model;
public Recording recording; public Recording recording;
public ModelGroup modelGroup;
} }
} }