diff --git a/.travis.yml b/.travis.yml
index 125ad8f..94e3c54 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,5 +22,4 @@ deploy:
draft: true
on:
branch: master
- tags: true
- condition: "$TRAVIS_TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+"
\ No newline at end of file
+ tags: true
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 34ea7f3..2922f5f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.erikmafo
bigtableviewer
- 0.1.2
+ 0.1.3-SNAPSHOT
jar
bigtableviewer
@@ -187,7 +187,7 @@
com.google.cloud.bigtable
- bigtable-hbase-1.x
+ bigtable-hbase-1.x-shaded
1.7.0
@@ -196,6 +196,11 @@
1
compile
+
+ javax.annotation
+ javax.annotation-api
+ 1.3.2
+
com.google.code.gson
gson
@@ -231,5 +236,10 @@
1.10.19
test
+
+ com.google.inject
+ guice
+ 4.2.2
+
\ No newline at end of file
diff --git a/src/main/java/com/erikmafo/btviewer/MainApp.java b/src/main/java/com/erikmafo/btviewer/MainApp.java
index 7271334..4a34f0a 100644
--- a/src/main/java/com/erikmafo/btviewer/MainApp.java
+++ b/src/main/java/com/erikmafo/btviewer/MainApp.java
@@ -1,4 +1,10 @@
package com.erikmafo.btviewer;
+import com.erikmafo.btviewer.services.BigtableClient;
+import com.erikmafo.btviewer.services.BigtableInstanceManager;
+import com.erikmafo.btviewer.services.CredentialsManager;
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Module;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
@@ -9,7 +15,8 @@
/**
* Created by erikmafo on 12.12.17.
*/
-public class MainApp extends Application {
+public class MainApp extends Application implements Module {
+
public static void main(String[] args) {
launch(args);
}
@@ -17,6 +24,7 @@ public static void main(String[] args) {
@Override
public void start(Stage primaryStage) throws Exception{
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/main.fxml"));
+ loader.setControllerFactory(Guice.createInjector(this)::getInstance);
Parent root = loader.load();
primaryStage.setTitle("Bigtable viewer");
primaryStage.setScene(new Scene(root, 800, 700));
@@ -27,4 +35,11 @@ public void start(Stage primaryStage) throws Exception{
public void stop() throws Exception {
super.stop();
}
+
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(BigtableClient.class).toInstance(new BigtableClient());
+ binder.bind(CredentialsManager.class).toInstance(new CredentialsManager());
+ binder.bind(BigtableInstanceManager.class).toInstance(new BigtableInstanceManager());
+ }
}
diff --git a/src/main/java/com/erikmafo/btviewer/components/BigtableView.java b/src/main/java/com/erikmafo/btviewer/components/BigtableTableView.java
similarity index 72%
rename from src/main/java/com/erikmafo/btviewer/components/BigtableView.java
rename to src/main/java/com/erikmafo/btviewer/components/BigtableTableView.java
index 4368564..ebf1328 100644
--- a/src/main/java/com/erikmafo/btviewer/components/BigtableView.java
+++ b/src/main/java/com/erikmafo/btviewer/components/BigtableTableView.java
@@ -2,18 +2,19 @@
import com.erikmafo.btviewer.model.BigtableColumn;
import com.erikmafo.btviewer.model.BigtableRow;
-import com.erikmafo.btviewer.services.BigtableResultScanner;
-import javafx.application.Platform;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.control.*;
-import javafx.scene.layout.GridPane;
+import javafx.scene.input.ScrollEvent;
+import javafx.scene.layout.VBox;
import java.io.IOException;
import java.util.*;
@@ -22,18 +23,19 @@
/**
* Created by erikmafo on 12.12.17.
*/
-public class BigtableView extends GridPane {
+public class BigtableTableView extends VBox {
- public static final String ROWKEY = "rowkey";
+ private static final String ROWKEY = "rowkey";
@FXML
- private TableView tableView;
+ private Button configureRowValueTypesButton;
- private BigtableResultScanner scanner;
+ @FXML
+ private TableView tableView;
- public BigtableView() {
+ public BigtableTableView() {
- FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/bigtable_view.fxml"));
+ FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/bigtable_table_view.fxml"));
loader.setRoot(this);
loader.setController(this);
@@ -44,10 +46,7 @@ public BigtableView() {
}
tableView.getColumns().add(createRowKeyColumn());
- tableView.setOnScroll(event -> {
- ScrollBar bar = getVerticalScrollbar();
- Platform.runLater(() -> addRows((int)bar.getMax()));
- });
+ configureRowValueTypesButton.setVisible(false); // TODO: enable this feature
}
private ScrollBar getVerticalScrollbar() {
@@ -72,6 +71,19 @@ private ScrollBar getVerticalScrollbar() {
return tableColumn;
}
+ public int getMaxRows() {
+ ScrollBar bar = getVerticalScrollbar();
+ return (int)bar.getMax();
+ }
+
+ public void setOnConfigureRowValuesTypes(EventHandler eventHandler) {
+ configureRowValueTypesButton.setOnAction(eventHandler);
+ }
+
+ public void setOnScrollEvent(EventHandler eventHandler) {
+ getVerticalScrollbar().setOnScroll(eventHandler);
+ }
+
public List getColumns() {
return tableView.getColumns()
.stream()
@@ -82,24 +94,13 @@ public List getColumns() {
.collect(Collectors.toList());
}
- public void setBigtableScanner(BigtableResultScanner scanner)
- {
- if (this.scanner != null)
- {
- BigtableResultScanner prevScanner = this.scanner;
- Platform.runLater(() ->
- {
- try {
- prevScanner.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- });
- }
- this.scanner = scanner;
+ public void clear() {
tableView.getColumns().removeIf(t -> !t.getText().equals(ROWKEY));
setBigTableRows(FXCollections.observableArrayList());
- Platform.runLater(() -> addRows(20));
+ }
+
+ public void add(BigtableRow row) {
+ tableView.getItems().add(row);
}
private void addColumn(String family, String qualifier) {
@@ -116,7 +117,6 @@ private void addColumn(String family, String qualifier) {
return new ReadOnlyObjectWrapper<>(bigtableRow.getCellValue(family, qualifier));
});
-
if (familyColumn == null) {
familyColumn = new TableColumn<>(family);
familyColumn.getColumns().add(qualifierColumn);
@@ -137,22 +137,4 @@ private void setBigTableRows(ObservableList bigtableRows) {
}
});
}
-
- private void addRows(int maxRows) {
- int count = 0;
-
- BigtableRow row;
- do {
- try {
- row = scanner.next();
- if (row == null) {
- break;
- }
- tableView.getItems().add(row);
- count++;
- } catch (IOException e) {
- e.printStackTrace();
- }
- } while (count < maxRows);
- }
}
diff --git a/src/main/java/com/erikmafo/btviewer/components/BigtableTablesListView.java b/src/main/java/com/erikmafo/btviewer/components/BigtableTablesListView.java
index 6ee59ec..e00ed17 100644
--- a/src/main/java/com/erikmafo/btviewer/components/BigtableTablesListView.java
+++ b/src/main/java/com/erikmafo/btviewer/components/BigtableTablesListView.java
@@ -1,22 +1,23 @@
package com.erikmafo.btviewer.components;
+import com.erikmafo.btviewer.events.BigtableProjectTreeItemExpanded;
import com.erikmafo.btviewer.model.BigtableInstance;
import com.erikmafo.btviewer.model.BigtableTable;
import javafx.beans.property.ReadOnlyObjectProperty;
-import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleObjectProperty;
-import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.*;
-import javafx.scene.layout.GridPane;
+import javafx.scene.layout.VBox;
import java.io.IOException;
import java.util.List;
+import java.util.stream.Collectors;
-public class BigtableTablesListView extends GridPane {
+public class BigtableTablesListView extends VBox {
@FXML
private Button addInstanceButton;
@@ -26,9 +27,7 @@ public class BigtableTablesListView extends GridPane {
private SimpleObjectProperty selectedTableProperty;
- private SimpleObjectProperty selectedInstanceProperty = new SimpleObjectProperty<>();
-
- private SimpleStringProperty selectedProjectProperty = new SimpleStringProperty();
+ private EventHandler treeItemExpandedEventHandler;
public BigtableTablesListView(){
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/bigtable_tables_list_view.fxml"));
@@ -62,11 +61,15 @@ private static int countParents(TreeItem treeItem) {
return 1 + countParents(treeItem.getParent());
}
- public void setOnAddBigtableInstance(EventHandler eventHandler) {
+ public void setOnCreateNewBigtableInstance(EventHandler eventHandler) {
addInstanceButton.setOnAction(eventHandler);
}
- public void addBigtableInstance(BigtableInstance instance, ChangeListener expandedListener) {
+ public void addBigtableInstances(List bigtableInstances) {
+ bigtableInstances.forEach(this::addBigtableInstance);
+ }
+
+ public void addBigtableInstance(BigtableInstance instance) {
TreeItem projectTreeItem = treeView.getRoot()
.getChildren()
@@ -75,7 +78,21 @@ public void addBigtableInstance(BigtableInstance instance, ChangeListener(instance.getProjectId());
+ final TreeItem projectTreeItemFinal = new TreeItem<>(instance.getProjectId());
+
+ projectTreeItemFinal.expandedProperty().addListener(new ChangeListener() {
+ @Override
+ public void changed(ObservableValue extends Boolean> observableValue, Boolean wasExpanded, Boolean isExpanded) {
+ if (isExpanded && treeItemExpandedEventHandler != null) {
+ List bigtableInstances = projectTreeItemFinal.getChildren()
+ .stream()
+ .map(i -> new BigtableInstance(instance.getProjectId(), i.getValue()))
+ .collect(Collectors.toList());
+ treeItemExpandedEventHandler.handle(new BigtableProjectTreeItemExpanded(bigtableInstances));
+ }
+ }
+ });
+ projectTreeItem = projectTreeItemFinal;
}
TreeItem instanceTreeItem = new TreeItem<>(instance.getInstanceId());
@@ -103,21 +120,10 @@ public void addBigtableTables(List tables) {
instance.getChildren().add(new TreeItem<>(table.getTableId()));
}
});
-
}
}
- private MenuItem getMenuItem(BigtableInstance instance) {
- MenuItem menuItem = new MenuItem(instance.getInstanceId());
- menuItem.setUserData(instance);
- return menuItem;
- }
-
- public ReadOnlyObjectProperty selectedInstanceProperty() {
- return selectedInstanceProperty;
- }
-
- public ReadOnlyStringProperty selectedProjectProperty() {
- return selectedProjectProperty;
+ public void setTreeItemExpandedEventHandler(EventHandler treeItemExpandedEventHandler) {
+ this.treeItemExpandedEventHandler = treeItemExpandedEventHandler;
}
}
diff --git a/src/main/java/com/erikmafo/btviewer/components/BigtableValueTypesDialog.java b/src/main/java/com/erikmafo/btviewer/components/BigtableValueTypesDialog.java
index 7076f49..efd32d3 100644
--- a/src/main/java/com/erikmafo/btviewer/components/BigtableValueTypesDialog.java
+++ b/src/main/java/com/erikmafo/btviewer/components/BigtableValueTypesDialog.java
@@ -4,7 +4,6 @@
import com.erikmafo.btviewer.model.CellDefinition;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
-import javafx.collections.transformation.SortedList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
@@ -32,7 +31,6 @@ public class BigtableValueTypesDialog extends DialogPane {
private BigtableValueTypesDialog() {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/bigtable_value_types_dialog.fxml"));
-
loader.setRoot(this);
loader.setController(this);
diff --git a/src/main/java/com/erikmafo/btviewer/components/RowSelectionView.java b/src/main/java/com/erikmafo/btviewer/components/RowSelectionView.java
new file mode 100644
index 0000000..fce5014
--- /dev/null
+++ b/src/main/java/com/erikmafo/btviewer/components/RowSelectionView.java
@@ -0,0 +1,49 @@
+package com.erikmafo.btviewer.components;
+
+import com.erikmafo.btviewer.events.ScanTableAction;
+import javafx.event.EventHandler;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.control.Button;
+import javafx.scene.control.ProgressBar;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.VBox;
+
+import java.io.IOException;
+
+public class RowSelectionView extends VBox {
+
+ @FXML
+ private Button scanTableButton;
+
+ @FXML
+ private ProgressBar progressBar;
+
+ @FXML
+ private TextField fromTextField;
+
+ @FXML
+ private TextField toTextField;
+
+ public RowSelectionView() {
+ FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/row_selection_view.fxml"));
+ loader.setRoot(this);
+ loader.setController(this);
+
+ try {
+ loader.load();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to load fxml", e);
+ }
+ progressBar.setVisible(false);
+ }
+
+ public void setOnScanTable(EventHandler eventHandler) {
+ scanTableButton.setOnAction(actionEvent ->
+ eventHandler.handle(new ScanTableAction(fromTextField.getText(), toTextField.getText())));
+ }
+
+ public ProgressBar getProgressBar() {
+ return progressBar;
+ }
+}
diff --git a/src/main/java/com/erikmafo/btviewer/components/SpecifyCredentialsPathDialog.java b/src/main/java/com/erikmafo/btviewer/components/SpecifyCredentialsPathDialog.java
new file mode 100644
index 0000000..9232476
--- /dev/null
+++ b/src/main/java/com/erikmafo/btviewer/components/SpecifyCredentialsPathDialog.java
@@ -0,0 +1,106 @@
+package com.erikmafo.btviewer.components;
+
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.control.*;
+import javafx.stage.FileChooser;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
+import java.nio.file.Path;
+import java.util.concurrent.CompletableFuture;
+
+public class SpecifyCredentialsPathDialog extends DialogPane {
+
+ @FXML
+ private TextField credentialsPathTextField;
+
+ public SpecifyCredentialsPathDialog() {
+ FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/specify_credentials_path_dialog.fxml"));
+
+ loader.setController(this);
+ loader.setRoot(this);
+ try {
+ loader.load();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ @FXML
+ private void handleEditCredentialsPathAction(ActionEvent event) {
+
+ FileChooser fileChooser = new FileChooser();
+ FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("json files (*.json)", "*.json");
+ fileChooser.getExtensionFilters().add(extFilter);
+ File file = fileChooser.showOpenDialog(getScene().getWindow());
+
+ if (file != null)
+ {
+ credentialsPathTextField.setText(file.getPath());
+ }
+
+ }
+
+ public static CompletableFuture displayAndAwaitResult(Path currentPath) {
+
+ CompletableFuture result = new CompletableFuture<>();
+
+ Dialog dialog = new Dialog<>();
+ SpecifyCredentialsPathDialog credentialsPathDialog = new SpecifyCredentialsPathDialog();
+
+ if (currentPath != null) {
+ credentialsPathDialog.credentialsPathTextField.textProperty().setValue(currentPath.toString());
+ }
+
+ dialog.setDialogPane(credentialsPathDialog);
+
+ dialog.setResultConverter(param -> {
+ if (ButtonBar.ButtonData.OK_DONE.equals(param.getButtonData())) {
+ return credentialsPathDialog.credentialsPathTextField.textProperty().get();
+ }
+ return null;
+ });
+
+ dialog.setOnHidden(event1 -> {
+ String pathAsString = dialog.getResult();
+ if (pathAsString != null) {
+ try {
+ Path path = Path.of(pathAsString);
+ if (Files.exists(path)) {
+ if (Files.isReadable(path)) {
+ result.complete(path);
+ } else {
+ Alert alert = new Alert(Alert.AlertType.INFORMATION);
+ alert.setTitle("Invalid path");
+ alert.setHeaderText("Please specify a valid path");
+ alert.setContentText("File is not readable");
+ alert.showAndWait();
+ }
+ } else {
+ Alert alert = new Alert(Alert.AlertType.INFORMATION);
+ alert.setTitle("Invalid path");
+ alert.setHeaderText("Please specify a valid path");
+ alert.setContentText("File not found");
+ alert.showAndWait();
+ }
+ } catch (InvalidPathException e) {
+ Alert alert = new Alert(Alert.AlertType.INFORMATION);
+ alert.setTitle("Invalid path");
+ alert.setHeaderText("Please specify a valid path");
+ alert.setContentText(e.getMessage());
+ alert.showAndWait();
+ }
+ }
+ });
+
+ dialog.show();
+
+ return result;
+ }
+
+}
diff --git a/src/main/java/com/erikmafo/btviewer/controllers/BigtableMenuBarController.java b/src/main/java/com/erikmafo/btviewer/controllers/BigtableMenuBarController.java
deleted file mode 100644
index 02943d4..0000000
--- a/src/main/java/com/erikmafo/btviewer/controllers/BigtableMenuBarController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.erikmafo.btviewer.controllers;
-
-import com.erikmafo.btviewer.model.BigtableValueParser;
-import com.erikmafo.btviewer.model.CredentialsRecord;
-import javafx.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.control.Menu;
-import javafx.scene.control.MenuItem;
-
-import javax.inject.Inject;
-import java.util.List;
-
-public class BigtableMenuBarController {
-
- @Inject
- public BigtableMenuBarController() {
- }
-
- @FXML
- private Menu selectTableMenu;
-
- @FXML
- private MenuItem credentialsMenu;
-
- public void handleManageCredentialsAction(ActionEvent event) {
-
- }
-
- public void handleCreateNewTableAction(ActionEvent event) {
-
- }
-
- public void addBigtableDefinitions(List bigtableDefinitions) {
- //bigtableDefinitions.forEach(this::addBigtableDefinition);
- }
-
- public void addCredentialRecords(List records) {
-
- }
-}
diff --git a/src/main/java/com/erikmafo/btviewer/controllers/MainController.java b/src/main/java/com/erikmafo/btviewer/controllers/MainController.java
index c6c22a0..2f1aefb 100644
--- a/src/main/java/com/erikmafo/btviewer/controllers/MainController.java
+++ b/src/main/java/com/erikmafo/btviewer/controllers/MainController.java
@@ -1,33 +1,18 @@
package com.erikmafo.btviewer.controllers;
-import com.erikmafo.btviewer.components.BigtableInstanceDialog;
-import com.erikmafo.btviewer.components.BigtableValueTypesDialog;
-import com.erikmafo.btviewer.components.BigtableTablesListView;
-import com.erikmafo.btviewer.components.BigtableView;
+import com.erikmafo.btviewer.components.*;
+import com.erikmafo.btviewer.events.BigtableProjectTreeItemExpanded;
+import com.erikmafo.btviewer.events.ScanTableAction;
import com.erikmafo.btviewer.model.*;
-import com.erikmafo.btviewer.services.BigtableClient;
-import com.erikmafo.btviewer.services.BigtableResultScanner;
-import com.erikmafo.btviewer.services.UserConfigurationService;
-import javafx.application.Platform;
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-import javafx.concurrent.Service;
-import javafx.concurrent.Task;
+import com.erikmafo.btviewer.services.*;
+import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
-import javafx.scene.control.MenuBar;
-import javafx.scene.control.ProgressBar;
-import javafx.scene.control.TextField;
-import javafx.scene.layout.VBox;
import javax.inject.Inject;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedList;
import java.util.List;
-import java.util.stream.Collectors;
/**
* Created by erikmafo on 23.12.17.
@@ -35,183 +20,115 @@
public class MainController {
@FXML
- private BigtableTablesListView tablesListView;
-
- @FXML
- private MenuBar bigtableMenuBar;
-
- @FXML
- private BigtableMenuBarController bigtableMenuBarController;
+ private RowSelectionView rowSelectionView;
@FXML
- private ProgressBar progressBar;
-
- @FXML
- private VBox mainView;
-
- @FXML
- private TextField fromTextField;
-
- @FXML
- private TextField toTextField;
+ private BigtableTablesListView tablesListView;
@FXML
private Label tableNameLabel;
@FXML
- private BigtableView bigtableView;
+ private BigtableTableView bigtableTableView;
- private final FetchBigtableRowsService fetchBigtableRowsService;
- private final UserConfigurationService userConfigurationService;
- private final ObservableList bigtableRows = FXCollections.observableArrayList(new ArrayList<>());
+ private final CredentialsManager credentialsManager;
+ private final BigtableInstanceManager bigtableInstanceManager;
private final BigtableClient bigtableClient;
@Inject
- public MainController() {
- this.userConfigurationService = new UserConfigurationService();
- this.bigtableClient = new BigtableClient();
- this.fetchBigtableRowsService = new FetchBigtableRowsService(bigtableClient);
+ public MainController(CredentialsManager credentialsManager,
+ BigtableInstanceManager bigtableInstanceManager,
+ BigtableClient bigtableClient) {
+ this.credentialsManager = credentialsManager;
+ this.bigtableInstanceManager = bigtableInstanceManager;
+ this.bigtableClient = bigtableClient;
}
public void initialize() {
-
- final String os = System.getProperty("os.name");
- if (os != null && os.startsWith("Mac")) {
- bigtableMenuBar.useSystemMenuBarProperty().set(true);
- }
-
- mainView.setVisible(false);
- progressBar.progressProperty().bind(fetchBigtableRowsService.progressProperty());
- progressBar.visibleProperty().bind(fetchBigtableRowsService.runningProperty());
-
- fetchBigtableRowsService.setOnSucceeded(event -> {
- mainView.setVisible(true);
- List rows = fetchBigtableRowsService.getValue();
- bigtableRows.setAll(rows);
- });
-
- tablesListView.selectedTableProperty().addListener((observable, oldValue, newValue) ->
- {
- bigtableRows.clear();
- mainView.setVisible(true);
- tableNameLabel.setText(newValue.getSimpleName());
- BigtableReadRequest request = new BigtableReadRequestBuilder()
- .setCredentialsPath(userConfigurationService.getCredentialsPath())
- .setBigtableTable(newValue)
- .setScan(new BigtableRowRange("", "~", 100))
- .build();
- try {
- bigtableView.setBigtableScanner(bigtableClient.execute(request));
- } catch (IOException e) {
- e.printStackTrace();
+ rowSelectionView.setVisible(false);
+ bigtableTableView.setVisible(false);
+ tableNameLabel.setVisible(false);
+
+ bigtableTableView.setOnConfigureRowValuesTypes(this::onConfigureRowValueTypes);
+ tablesListView.setOnCreateNewBigtableInstance(this::onAddNewBigtableInstance);
+ tablesListView.selectedTableProperty().addListener(this::onBigtableTableSelected);
+ tablesListView.setTreeItemExpandedEventHandler(new EventHandler() {
+ @Override
+ public void handle(BigtableProjectTreeItemExpanded event) {
+ event.getBigtableInstances().forEach(MainController.this::listBigtableTables);
}
});
+ rowSelectionView.setOnScanTable(this::onScanTableAction);
- tablesListView.setOnAddBigtableInstance(event -> {
- BigtableInstanceDialog.displayAndAwaitResult()
- .whenComplete((instance, throwable) -> {
- tablesListView.addBigtableInstance(instance, null);
- Platform.runLater(() -> tablesListView.addBigtableTables(tryListBigtableTables(instance)));
- });
- });
+
+ tablesListView.addBigtableInstances(bigtableInstanceManager.getInstances());
}
- private List tryListBigtableTables(BigtableInstance instance) {
- try {
- return bigtableClient.listTables(
- instance,
- userConfigurationService.getCredentialsPath())
- .stream()
- .map(this::getBigtableTable)
- .collect(Collectors.toList());
- } catch (IOException e) {
- return Collections.emptyList();
- }
+ private void onAddNewBigtableInstance(ActionEvent event) {
+ BigtableInstanceDialog.displayAndAwaitResult()
+ .whenComplete((instance, throwable) -> {
+ List allInstances = bigtableInstanceManager.getInstances();
+ allInstances.add(instance);
+ bigtableInstanceManager.setInstances(allInstances);
+
+ tablesListView.addBigtableInstance(instance);
+ listBigtableTables(instance);
+ });
}
- private List tryListBigtableInstances(String projectId) {
- try {
- return bigtableClient.listInstances(projectId, userConfigurationService.getCredentialsPath());
- } catch (IOException e) {
- return Collections.emptyList();
- }
+ private void listBigtableTables(BigtableInstance instance) {
+ ListBigtableTables listBigtableTables = new ListBigtableTables(
+ bigtableClient, instance, credentialsManager.getCredentialsPath());
+ listBigtableTables.setOnSucceeded(workerStateEvent -> {
+ tablesListView.addBigtableTables(listBigtableTables.getValue());
+ });
+ listBigtableTables.start();
}
- public void handleScanTableAction(ActionEvent actionEvent) {
+ private void onScanTableAction(ScanTableAction actionEvent) {
+ BigtableTable currentTable = tablesListView.selectedTableProperty().get();
+ bigtableTableView.clear();
BigtableReadRequest request = new BigtableReadRequestBuilder()
- .setCredentialsPath(userConfigurationService.getCredentialsPath())
- .setBigtableTable(tablesListView.selectedTableProperty().get())
- .setScan(new BigtableRowRange(fromTextField.getText(), toTextField.getText()))
+ .setCredentialsPath(credentialsManager.getCredentialsPath())
+ .setTable(currentTable)
+ .setRowRange(new BigtableRowRange(actionEvent.getFrom(), actionEvent.getTo()))
.build();
- try {
- bigtableView.setBigtableScanner(bigtableClient.execute(request));
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- //fetchBigtableRowsService.setReadRequest(request);
- //fetchBigtableRowsService.restart();
- }
-
- private BigtableTable getBigtableTable(String tableName) {
- return userConfigurationService
- .loadBigtableDefinitions()
- .stream()
- .filter(def -> tableName.equals(def.getName()))
- .findFirst().orElse(new BigtableTable(tableName));
+ readBigtableRows(request);
}
- public void handleConfigureValueParserAction(ActionEvent event) {
- BigtableValueTypesDialog.displayAndAwaitResult(bigtableView.getColumns());
+ private void onConfigureRowValueTypes(ActionEvent event) {
+ BigtableValueTypesDialog.displayAndAwaitResult(bigtableTableView.getColumns());
}
- private static class FetchBigtableRowsService extends Service> {
-
- private final BigtableClient bigtableClient;
-
- private BigtableReadRequest readRequest;
-
- public FetchBigtableRowsService(BigtableClient bigtableClient) {
- this.bigtableClient = bigtableClient;
- }
-
- public void setReadRequest(BigtableReadRequest readRequest) {
- this.readRequest = readRequest;
- }
+ private void onBigtableTableSelected(ObservableValue extends BigtableTable> observable, BigtableTable oldValue, BigtableTable newValue) {
- @Override
- protected Task> createTask() {
+ bigtableTableView.clear();
+ tableNameLabel.setText(newValue.getSimpleName());
+ tableNameLabel.setVisible(true);
+ rowSelectionView.setVisible(true);
- return new Task>() {
-
- @Override
- protected List call() throws Exception {
-
- List rows = new LinkedList<>();
-
- int count = 0;
-
- try(BigtableResultScanner scanner = bigtableClient.execute(readRequest)) {
-
- BigtableRow row = scanner.next();
+ BigtableReadRequest request = new BigtableReadRequestBuilder()
+ .setCredentialsPath(credentialsManager.getCredentialsPath())
+ .setTable(newValue)
+ .setRowRange(BigtableRowRange.DEFAULT)
+ .build();
- while (row != null) {
- rows.add(row);
- count++;
- updateProgress(count, readRequest.getScan().getMaxRows());
- row = scanner.next();
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw e;
- }
+ readBigtableRows(request);
+ }
- return rows;
- }
+ private void readBigtableRows(BigtableReadRequest request) {
+ ReadBigtableRows readRowsService = new ReadBigtableRows(bigtableClient, request);
+ readRowsService.setOnSucceeded(workerStateEvent -> {
+ bigtableTableView.setVisible(true);
+ rowSelectionView.getProgressBar().setVisible(false);
+ readRowsService.getValue()
+ .forEach(row -> bigtableTableView.add(row));
- };
- }
+ });
+ rowSelectionView.getProgressBar().setVisible(true);
+ rowSelectionView.getProgressBar().progressProperty().bind(readRowsService.progressProperty());
+ readRowsService.start();
}
}
diff --git a/src/main/java/com/erikmafo/btviewer/controllers/MenuBarController.java b/src/main/java/com/erikmafo/btviewer/controllers/MenuBarController.java
new file mode 100644
index 0000000..d75cf39
--- /dev/null
+++ b/src/main/java/com/erikmafo/btviewer/controllers/MenuBarController.java
@@ -0,0 +1,40 @@
+package com.erikmafo.btviewer.controllers;
+
+import com.erikmafo.btviewer.components.SpecifyCredentialsPathDialog;
+import com.erikmafo.btviewer.services.CredentialsManager;
+import javafx.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.control.MenuBar;
+import javafx.scene.control.MenuItem;
+import javax.inject.Inject;
+import java.nio.file.Path;
+
+public class MenuBarController {
+
+ private final CredentialsManager credentialsManager;
+
+ @Inject
+ public MenuBarController(CredentialsManager credentialsManager) {
+ this.credentialsManager = credentialsManager;
+ }
+
+ @FXML
+ private MenuItem credentialsMenu;
+
+ @FXML
+ private MenuBar menuBar;
+
+ public void initialize() {
+ final String os = System.getProperty("os.name");
+ if (os != null && os.startsWith("Mac")) {
+ menuBar.useSystemMenuBarProperty().set(true);
+ }
+ }
+
+ public void onManageCredentialsAction(ActionEvent event) {
+ Path currentPath = credentialsManager.getCredentialsPath();
+ SpecifyCredentialsPathDialog.displayAndAwaitResult(currentPath)
+ .whenComplete((newCredentialsPath, throwable) ->
+ credentialsManager.setCredentialsPath(newCredentialsPath));
+ }
+}
diff --git a/src/main/java/com/erikmafo/btviewer/events/BigtableProjectTreeItemExpanded.java b/src/main/java/com/erikmafo/btviewer/events/BigtableProjectTreeItemExpanded.java
new file mode 100644
index 0000000..004aa63
--- /dev/null
+++ b/src/main/java/com/erikmafo/btviewer/events/BigtableProjectTreeItemExpanded.java
@@ -0,0 +1,23 @@
+package com.erikmafo.btviewer.events;
+
+import com.erikmafo.btviewer.model.BigtableInstance;
+import javafx.event.Event;
+import javafx.event.EventType;
+
+import java.util.List;
+
+public class BigtableProjectTreeItemExpanded extends Event {
+
+ public static final EventType PROJECT_TREE_ITEM_EXPANDED_EVENT_TYPE = new EventType<>(EventType.ROOT);
+
+ private final List bigtableInstances;
+
+ public BigtableProjectTreeItemExpanded(List instances) {
+ super(PROJECT_TREE_ITEM_EXPANDED_EVENT_TYPE);
+ bigtableInstances = instances;
+ }
+
+ public List getBigtableInstances() {
+ return bigtableInstances;
+ }
+}
diff --git a/src/main/java/com/erikmafo/btviewer/events/ScanTableAction.java b/src/main/java/com/erikmafo/btviewer/events/ScanTableAction.java
new file mode 100644
index 0000000..8683bc8
--- /dev/null
+++ b/src/main/java/com/erikmafo/btviewer/events/ScanTableAction.java
@@ -0,0 +1,25 @@
+package com.erikmafo.btviewer.events;
+import javafx.event.Event;
+import javafx.event.EventType;
+
+public class ScanTableAction extends Event {
+
+ public static final EventType SCAN_TABLE = new EventType<>(EventType.ROOT);
+
+ private final String from;
+ private final String to;
+
+ public ScanTableAction(String from, String to) {
+ super(SCAN_TABLE);
+ this.from = from;
+ this.to = to;
+ }
+
+ public String getFrom() {
+ return from;
+ }
+
+ public String getTo() {
+ return to;
+ }
+}
diff --git a/src/main/java/com/erikmafo/btviewer/exceptions/InvalidBigtableDefinitionException.java b/src/main/java/com/erikmafo/btviewer/exceptions/InvalidBigtableDefinitionException.java
deleted file mode 100644
index 2d9e145..0000000
--- a/src/main/java/com/erikmafo/btviewer/exceptions/InvalidBigtableDefinitionException.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.erikmafo.btviewer.exceptions;
-
-public class InvalidBigtableDefinitionException extends Exception {
-
- public InvalidBigtableDefinitionException() {
- }
-
- public InvalidBigtableDefinitionException(String message) {
- super(message);
- }
-
- public InvalidBigtableDefinitionException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public InvalidBigtableDefinitionException(Throwable cause) {
- super(cause);
- }
-
- public InvalidBigtableDefinitionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
- super(message, cause, enableSuppression, writableStackTrace);
- }
-}
diff --git a/src/main/java/com/erikmafo/btviewer/model/BigtableCell.java b/src/main/java/com/erikmafo/btviewer/model/BigtableCell.java
index 8b4988b..2bf51f1 100644
--- a/src/main/java/com/erikmafo/btviewer/model/BigtableCell.java
+++ b/src/main/java/com/erikmafo/btviewer/model/BigtableCell.java
@@ -1,6 +1,6 @@
package com.erikmafo.btviewer.model;
-import com.google.protobuf.ByteString;
+import com.google.bigtable.repackaged.com.google.protobuf.ByteString;
public class BigtableCell {
diff --git a/src/main/java/com/erikmafo/btviewer/model/BigtableInstance.java b/src/main/java/com/erikmafo/btviewer/model/BigtableInstance.java
index 99b8e29..fd89aa2 100644
--- a/src/main/java/com/erikmafo/btviewer/model/BigtableInstance.java
+++ b/src/main/java/com/erikmafo/btviewer/model/BigtableInstance.java
@@ -6,6 +6,8 @@ public class BigtableInstance {
private String projectId;
+ public BigtableInstance() {}
+
public BigtableInstance(String name)
{
String[] parts = name.split("/");
@@ -18,6 +20,13 @@ public BigtableInstance(String projectId, String instanceId) {
this.instanceId = instanceId;
}
+ public void setInstanceId(String instanceId) {
+ this.instanceId = instanceId;
+ }
+
+ public void setProjectId(String projectId) {
+ this.projectId = projectId;
+ }
public String getProjectId() {
return projectId;
diff --git a/src/main/java/com/erikmafo/btviewer/model/BigtableReadRequest.java b/src/main/java/com/erikmafo/btviewer/model/BigtableReadRequest.java
index 3c227fe..08d7d25 100644
--- a/src/main/java/com/erikmafo/btviewer/model/BigtableReadRequest.java
+++ b/src/main/java/com/erikmafo/btviewer/model/BigtableReadRequest.java
@@ -1,19 +1,21 @@
package com.erikmafo.btviewer.model;
+import java.nio.file.Path;
+
public class BigtableReadRequest {
private final BigtableTable bigtableTable;
- private final String credentialsPath;
+ private final Path credentialsPath;
private final BigtableRowRange scan;
- BigtableReadRequest(BigtableTable bigtableTable, String credentialsPath, BigtableRowRange scan) {
+ BigtableReadRequest(BigtableTable bigtableTable, Path credentialsPath, BigtableRowRange scan) {
this.bigtableTable = bigtableTable;
this.credentialsPath = credentialsPath;
this.scan = scan;
}
- public String getCredentialsPath() {
+ public Path getCredentialsPath() {
return credentialsPath;
}
diff --git a/src/main/java/com/erikmafo/btviewer/model/BigtableReadRequestBuilder.java b/src/main/java/com/erikmafo/btviewer/model/BigtableReadRequestBuilder.java
index 94fafc7..c6ff875 100644
--- a/src/main/java/com/erikmafo/btviewer/model/BigtableReadRequestBuilder.java
+++ b/src/main/java/com/erikmafo/btviewer/model/BigtableReadRequestBuilder.java
@@ -1,22 +1,24 @@
package com.erikmafo.btviewer.model;
+import java.nio.file.Path;
+
public class BigtableReadRequestBuilder {
private BigtableTable bigtableTable;
- private String credentialsPath;
+ private Path credentialsPath;
private BigtableRowRange scan;
- public BigtableReadRequestBuilder setBigtableTable(BigtableTable bigtableTable) {
+ public BigtableReadRequestBuilder setTable(BigtableTable bigtableTable) {
this.bigtableTable = bigtableTable;
return this;
}
- public BigtableReadRequestBuilder setCredentialsPath(String credentialsPath) {
+ public BigtableReadRequestBuilder setCredentialsPath(Path credentialsPath) {
this.credentialsPath = credentialsPath;
return this;
}
- public BigtableReadRequestBuilder setScan(BigtableRowRange scan) {
+ public BigtableReadRequestBuilder setRowRange(BigtableRowRange scan) {
this.scan = scan;
return this;
}
diff --git a/src/main/java/com/erikmafo/btviewer/model/BigtableRowRange.java b/src/main/java/com/erikmafo/btviewer/model/BigtableRowRange.java
index 4057c69..81f7aaf 100644
--- a/src/main/java/com/erikmafo/btviewer/model/BigtableRowRange.java
+++ b/src/main/java/com/erikmafo/btviewer/model/BigtableRowRange.java
@@ -5,12 +5,14 @@
*/
public class BigtableRowRange {
+ public static BigtableRowRange DEFAULT = new BigtableRowRange("", "~", 1000);
+
private final String from;
private final String to;
private final int maxRows;
public BigtableRowRange(String from, String to) {
- this(from, to, 0);
+ this(from, to, 1000);
}
public BigtableRowRange(String from, String to, int maxRows) {
diff --git a/src/main/java/com/erikmafo/btviewer/model/BigtableTable.java b/src/main/java/com/erikmafo/btviewer/model/BigtableTable.java
index 2bf4caf..f2961fc 100644
--- a/src/main/java/com/erikmafo/btviewer/model/BigtableTable.java
+++ b/src/main/java/com/erikmafo/btviewer/model/BigtableTable.java
@@ -1,5 +1,6 @@
package com.erikmafo.btviewer.model;
-import com.google.cloud.bigtable.grpc.BigtableTableName;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.grpc.BigtableTableName;
+
import java.util.Collections;
import java.util.List;
diff --git a/src/main/java/com/erikmafo/btviewer/model/CellDefinition.java b/src/main/java/com/erikmafo/btviewer/model/CellDefinition.java
index bb37c86..1e0821c 100644
--- a/src/main/java/com/erikmafo/btviewer/model/CellDefinition.java
+++ b/src/main/java/com/erikmafo/btviewer/model/CellDefinition.java
@@ -3,11 +3,6 @@
public class CellDefinition {
-
- public CellDefinition() {
-
- }
-
public CellDefinition(String valueType, String family, String qualifier) {
this.valueType = valueType;
this.family = family;
@@ -18,7 +13,6 @@ public CellDefinition(String valueType, String family, String qualifier) {
private String family;
private String qualifier;
-
public String getValueType() {
return valueType;
}
diff --git a/src/main/java/com/erikmafo/btviewer/model/CredentialsRecord.java b/src/main/java/com/erikmafo/btviewer/model/CredentialsRecord.java
deleted file mode 100644
index 2e36e85..0000000
--- a/src/main/java/com/erikmafo/btviewer/model/CredentialsRecord.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.erikmafo.btviewer.model;
-
-import com.erikmafo.btviewer.exceptions.InvalidCredentialsRecordException;
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-public class CredentialsRecord {
-
- private String projectId;
-
- private String instanceId;
-
- private Path credentialsPath;
-
- public String getProjectId() {
- return projectId;
- }
-
- public void setProjectId(String projectId) {
- this.projectId = projectId;
- }
-
- public String getInstanceId() {
- return instanceId;
- }
-
- public void setInstanceId(String instanceId) {
- this.instanceId = instanceId;
- }
-
- public Path getCredentialsPath() {
- return credentialsPath;
- }
-
- public void setCredentialsPath(Path credentialsPath) {
- this.credentialsPath = credentialsPath;
- }
-
- public void ensureIsValid() throws InvalidCredentialsRecordException {
-
- String errorMessage = null;
-
- if (projectId == null || projectId.isEmpty()) {
- errorMessage = "Project id is not specified";
- } else if (instanceId == null || instanceId.isEmpty()) {
- errorMessage = "Instance id is not specified";
- } else if (credentialsPath == null) {
- errorMessage = "Credentials path is not specified";
- } else if (!credentialsPath.toFile().exists()) {
- errorMessage = "Credentials path does not exist";
- }
-
- if (errorMessage != null) {
- throw new InvalidCredentialsRecordException(errorMessage);
- }
- }
-
- public CredentialsRecordDto toDto() {
- CredentialsRecordDto dto = new CredentialsRecordDto();
- dto.setCredentialsPath(credentialsPath.toFile().getPath());
- dto.setInstanceId(instanceId);
- dto.setProjectId(projectId);
- return dto;
- }
-
- public static CredentialsRecord fromDto(CredentialsRecordDto dto) {
- CredentialsRecord record = new CredentialsRecord();
- record.setCredentialsPath(Paths.get(dto.getCredentialsPath()));
- record.setProjectId(dto.getProjectId());
- record.setInstanceId(dto.getInstanceId());
- return record;
- }
-}
diff --git a/src/main/java/com/erikmafo/btviewer/model/CredentialsRecordDto.java b/src/main/java/com/erikmafo/btviewer/model/CredentialsRecordDto.java
deleted file mode 100644
index d89c210..0000000
--- a/src/main/java/com/erikmafo/btviewer/model/CredentialsRecordDto.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.erikmafo.btviewer.model;
-
-public class CredentialsRecordDto {
-
- private String projectId;
- private String instanceId;
- private String credentialsPath;
-
- public String getProjectId() {
- return projectId;
- }
-
- public void setProjectId(String projectId) {
- this.projectId = projectId;
- }
-
- public String getInstanceId() {
- return instanceId;
- }
-
- public void setInstanceId(String instanceId) {
- this.instanceId = instanceId;
- }
-
- public String getCredentialsPath() {
- return credentialsPath;
- }
-
- public void setCredentialsPath(String credentialsPath) {
- this.credentialsPath = credentialsPath;
- }
-}
diff --git a/src/main/java/com/erikmafo/btviewer/services/BigtableClient.java b/src/main/java/com/erikmafo/btviewer/services/BigtableClient.java
index f030d33..d27bac2 100644
--- a/src/main/java/com/erikmafo/btviewer/services/BigtableClient.java
+++ b/src/main/java/com/erikmafo/btviewer/services/BigtableClient.java
@@ -1,24 +1,25 @@
package com.erikmafo.btviewer.services;
import com.erikmafo.btviewer.model.*;
-import com.google.bigtable.admin.v2.ListTablesRequest;
-import com.google.bigtable.admin.v2.ProjectName;
-import com.google.bigtable.admin.v2.Table;
-import com.google.bigtable.v2.ReadRowsRequest;
-import com.google.bigtable.v2.RowRange;
-import com.google.bigtable.v2.RowSet;
-import com.google.cloud.bigtable.admin.v2.BigtableInstanceAdminClient;
-import com.google.cloud.bigtable.admin.v2.BigtableInstanceAdminSettings;
-import com.google.cloud.bigtable.config.BigtableOptions;
-import com.google.cloud.bigtable.config.CallOptionsConfig;
-import com.google.cloud.bigtable.config.CredentialOptions;
-import com.google.cloud.bigtable.grpc.BigtableInstanceName;
-import com.google.cloud.bigtable.grpc.BigtableSession;
-import com.google.cloud.bigtable.grpc.BigtableTableAdminClient;
-import com.google.protobuf.ByteString;
-import java.io.FileInputStream;
+import com.google.bigtable.repackaged.com.google.bigtable.admin.v2.ListTablesRequest;
+import com.google.bigtable.repackaged.com.google.bigtable.admin.v2.ProjectName;
+import com.google.bigtable.repackaged.com.google.bigtable.admin.v2.Table;
+import com.google.bigtable.repackaged.com.google.bigtable.v2.ReadRowsRequest;
+import com.google.bigtable.repackaged.com.google.bigtable.v2.RowRange;
+import com.google.bigtable.repackaged.com.google.bigtable.v2.RowSet;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.admin.v2.BigtableInstanceAdminClient;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.admin.v2.BigtableInstanceAdminSettings;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.config.BigtableOptions;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.config.CallOptionsConfig;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.config.CredentialOptions;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.grpc.BigtableInstanceName;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.grpc.BigtableSession;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.grpc.BigtableTableAdminClient;
+import com.google.bigtable.repackaged.com.google.protobuf.ByteString;
import java.io.IOException;
import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -30,23 +31,21 @@
*/
public class BigtableClient {
- private Map credentialOptionsCache = new ConcurrentHashMap<>();
- public static final Charset DEFAULT_CHARSET = Charset.defaultCharset();
+ private final Map credentialOptionsCache = new ConcurrentHashMap<>();
+ private static final Charset DEFAULT_CHARSET = Charset.defaultCharset();
- private CredentialOptions getCredentialOptions(String credentialsPath) throws IOException {
+ private CredentialOptions getCredentialOptions(Path credentialsPath) throws IOException {
if (credentialsPath == null) {
return CredentialOptions.defaultCredentials();
}
- if (credentialOptionsCache.containsKey(credentialsPath)) {
- return credentialOptionsCache.get(credentialsPath);
+ if (credentialOptionsCache.containsKey(credentialsPath.toString())) {
+ return credentialOptionsCache.get(credentialsPath.toString());
}
- CredentialOptions credentialOptions = CredentialOptions.jsonCredentials(new FileInputStream(credentialsPath));
-
- credentialOptionsCache.put(credentialsPath, credentialOptions);
-
+ CredentialOptions credentialOptions = CredentialOptions.jsonCredentials(Files.newInputStream(credentialsPath));
+ credentialOptionsCache.put(credentialsPath.toString(), credentialOptions);
return credentialOptions;
}
@@ -54,7 +53,7 @@ public BigtableResultScanner execute(BigtableReadRequest bigtableReadRequest) th
BigtableTable bigtableTable = bigtableReadRequest.getBigtableTable();
BigtableRowRange bigtableRowRange = bigtableReadRequest.getScan();
- String credentialsPath = bigtableReadRequest.getCredentialsPath();
+ Path credentialsPath = bigtableReadRequest.getCredentialsPath();
BigtableSession bigtableSession = getBigtableSession(
bigtableTable.getProjectId(),
@@ -83,7 +82,7 @@ public BigtableResultScanner execute(BigtableReadRequest bigtableReadRequest) th
}
- public List listTables(BigtableInstance bigtableInstance, String credentialsPath) throws IOException {
+ public List listTables(BigtableInstance bigtableInstance, Path credentialsPath) throws IOException {
try (BigtableSession session = getBigtableSession(
bigtableInstance.getProjectId(),
bigtableInstance.getInstanceId(),
@@ -117,7 +116,7 @@ public List listInstances(String projectId, String credentials
}
- private BigtableSession getBigtableSession(String projectId, String instanceId, String credentialsPath) throws IOException {
+ private BigtableSession getBigtableSession(String projectId, String instanceId, Path credentialsPath) throws IOException {
BigtableOptions googleBigtableOptions =
BigtableOptions.builder()
diff --git a/src/main/java/com/erikmafo/btviewer/services/BigtableInstanceManager.java b/src/main/java/com/erikmafo/btviewer/services/BigtableInstanceManager.java
new file mode 100644
index 0000000..445f681
--- /dev/null
+++ b/src/main/java/com/erikmafo/btviewer/services/BigtableInstanceManager.java
@@ -0,0 +1,56 @@
+package com.erikmafo.btviewer.services;
+
+import com.erikmafo.btviewer.model.BigtableInstance;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.prefs.Preferences;
+
+public class BigtableInstanceManager {
+
+ private static final Type LIST_TYPE = new TypeToken>() {}.getType();
+ private static final String PREFERENCES_USER_ROOT_NODE_NAME = "bigtable-viewer-configs";
+ private static final String INSTANCES = "instances";
+
+ private final ExecutorService executorService = Executors.newSingleThreadExecutor();
+ private final Object mutex = new Object();
+
+ private final Gson gson = new Gson();
+ private List bigtableInstances;
+
+ public BigtableInstanceManager() {
+ String json = getPreferences().get(INSTANCES, null);
+ if (json != null) {
+ bigtableInstances = gson.fromJson(json, LIST_TYPE);
+ }
+ else {
+ bigtableInstances = new ArrayList<>();
+ }
+ }
+
+ public List getInstances() {
+ synchronized (mutex) {
+ return bigtableInstances;
+ }
+ }
+
+ public void setInstances(List instances) {
+
+ synchronized (mutex) {
+ this.bigtableInstances = instances;
+ executorService.submit(() -> {
+ String json = gson.toJson(instances, LIST_TYPE);
+ getPreferences().put(INSTANCES, json);
+ });
+ }
+ }
+
+ private Preferences getPreferences() {
+ return Preferences.userRoot().node(PREFERENCES_USER_ROOT_NODE_NAME);
+ }
+}
diff --git a/src/main/java/com/erikmafo/btviewer/services/BigtableResultScanner.java b/src/main/java/com/erikmafo/btviewer/services/BigtableResultScanner.java
index ac16583..d0a54b0 100644
--- a/src/main/java/com/erikmafo/btviewer/services/BigtableResultScanner.java
+++ b/src/main/java/com/erikmafo/btviewer/services/BigtableResultScanner.java
@@ -3,9 +3,9 @@
import com.erikmafo.btviewer.model.BigtableCell;
import com.erikmafo.btviewer.model.BigtableRow;
import com.erikmafo.btviewer.model.CellDefinition;
-import com.google.cloud.bigtable.grpc.BigtableSession;
-import com.google.cloud.bigtable.grpc.scanner.FlatRow;
-import com.google.cloud.bigtable.grpc.scanner.ResultScanner;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.grpc.BigtableSession;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.grpc.scanner.FlatRow;
+import com.google.bigtable.repackaged.com.google.cloud.bigtable.grpc.scanner.ResultScanner;
import java.io.Closeable;
import java.io.IOException;
diff --git a/src/main/java/com/erikmafo/btviewer/services/CredentialsManager.java b/src/main/java/com/erikmafo/btviewer/services/CredentialsManager.java
new file mode 100644
index 0000000..5711003
--- /dev/null
+++ b/src/main/java/com/erikmafo/btviewer/services/CredentialsManager.java
@@ -0,0 +1,57 @@
+package com.erikmafo.btviewer.services;
+import java.nio.file.Path;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.prefs.Preferences;
+
+/**
+ * Created by erikmafo on 25.12.17.
+ */
+public class CredentialsManager {
+
+ private static final String PREFERENCES_USER_ROOT_NODE_NAME = "bigtable-viewer-configs";
+ private static final String CREDENTIALS_PATH = "credentials-path";
+
+ private final ExecutorService executorService = Executors.newSingleThreadExecutor();
+ private final Object mutex = new Object();
+
+ private Path credentialsPath;
+
+ public CredentialsManager() {
+ String pathAsString = getPreferences().get(CREDENTIALS_PATH, null);
+
+ if (pathAsString != null) {
+ credentialsPath = Path.of(pathAsString);
+ }
+ }
+
+ public void setCredentialsPath(Path credentialsPath) {
+
+ if (credentialsPath == null) {
+ return;
+ }
+
+ synchronized (mutex) {
+ if (credentialsPath.equals(this.credentialsPath)) {
+ return;
+ }
+ this.credentialsPath = credentialsPath;
+ executorService.submit(() -> getPreferences().put(CREDENTIALS_PATH, credentialsPath.toString()));
+ }
+ }
+
+ public Path getCredentialsPath() {
+
+ synchronized (mutex) {
+ if (credentialsPath != null) {
+ return credentialsPath;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private Preferences getPreferences() {
+ return Preferences.userRoot().node(PREFERENCES_USER_ROOT_NODE_NAME);
+ }
+}
diff --git a/src/main/java/com/erikmafo/btviewer/services/ListBigtableTables.java b/src/main/java/com/erikmafo/btviewer/services/ListBigtableTables.java
new file mode 100644
index 0000000..9841534
--- /dev/null
+++ b/src/main/java/com/erikmafo/btviewer/services/ListBigtableTables.java
@@ -0,0 +1,42 @@
+package com.erikmafo.btviewer.services;
+
+import com.erikmafo.btviewer.model.BigtableInstance;
+import com.erikmafo.btviewer.model.BigtableTable;
+import javafx.concurrent.Service;
+import javafx.concurrent.Task;
+
+import java.nio.file.Path;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ListBigtableTables extends Service> {
+
+ private final BigtableClient client;
+ private final BigtableInstance instance;
+ private final Path credentialsPath;
+
+ public ListBigtableTables(BigtableClient client, BigtableInstance instance, Path credentialsPath) {
+ this.client = client;
+ this.instance = instance;
+ this.credentialsPath = credentialsPath;
+ }
+
+ @Override
+ protected Task> createTask() {
+ return new Task>() {
+ @Override
+ protected List call() throws Exception {
+ return client.listTables(
+ instance,
+ credentialsPath)
+ .stream()
+ .map(ListBigtableTables.this::getBigtableTable)
+ .collect(Collectors.toList());
+ }
+ };
+ }
+
+ private BigtableTable getBigtableTable(String tableName) {
+ return new BigtableTable(tableName);
+ }
+}
diff --git a/src/main/java/com/erikmafo/btviewer/services/ReadBigtableRows.java b/src/main/java/com/erikmafo/btviewer/services/ReadBigtableRows.java
new file mode 100644
index 0000000..c8a7421
--- /dev/null
+++ b/src/main/java/com/erikmafo/btviewer/services/ReadBigtableRows.java
@@ -0,0 +1,46 @@
+package com.erikmafo.btviewer.services;
+
+import com.erikmafo.btviewer.model.*;
+import javafx.concurrent.Service;
+import javafx.concurrent.Task;
+import java.util.ArrayList;
+import java.util.List;
+
+public class ReadBigtableRows extends Service> {
+
+ private final BigtableClient client;
+ private final BigtableReadRequest readRequest;
+
+ public ReadBigtableRows(BigtableClient client, BigtableReadRequest readRequest) {
+ this.client = client;
+ this.readRequest = readRequest;
+ }
+
+ @Override
+ protected Task> createTask() {
+ return new Task<>() {
+ @Override
+ protected List call() throws Exception {
+
+ try (BigtableResultScanner scanner = client.execute(readRequest)) {
+ List result = new ArrayList<>();
+ int count = 0;
+ BigtableRow row;
+ do {
+ count++;
+ row = scanner.next();
+ if (row == null) {
+ break;
+ }
+ result.add(row);
+ updateProgress(count, readRequest.getScan().getMaxRows());
+
+ } while (count < readRequest.getScan().getMaxRows());
+ return result;
+ }
+ }
+ };
+ }
+}
+
+
diff --git a/src/main/java/com/erikmafo/btviewer/services/UserConfigurationService.java b/src/main/java/com/erikmafo/btviewer/services/UserConfigurationService.java
deleted file mode 100644
index 9b2d206..0000000
--- a/src/main/java/com/erikmafo/btviewer/services/UserConfigurationService.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.erikmafo.btviewer.services;
-import com.erikmafo.btviewer.model.*;
-import com.google.gson.*;
-import com.google.gson.reflect.TypeToken;
-
-import java.lang.reflect.Type;
-import java.util.Collections;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.util.prefs.Preferences;
-import java.util.stream.Collectors;
-
-/**
- * Created by erikmafo on 25.12.17.
- */
-public class UserConfigurationService {
-
- private static final String PREFERENCES_USER_ROOT_NODE_NAME = "bigtable-viewer-configs";
- private static final String BIGTABLE_TABLE_DEFINITIONS = "bigtable-table-definitions";
- private static final String CREDENTIAL_RECORDS = "credential-records";
- private static final String CREDENTIALS_PATH = "credentials-path";
-
- private final Gson gson = new Gson();
-
- public String getCredentialsPath() {
- return getPreferences().get(CREDENTIALS_PATH, null);
- }
-
- public void setCredentialsPath(String credentialsPath) {
- getPreferences().put(CREDENTIALS_PATH, credentialsPath);
- }
-
- public void updateBigtableDefinitions(List bigtableOptions) {
-
- String json = gson.toJson(bigtableOptions);
-
- getPreferences().put(BIGTABLE_TABLE_DEFINITIONS, json);
- }
-
- public List loadBigtableDefinitions() {
-
- Preferences prefs = getPreferences();
-
- String json = prefs.get(BIGTABLE_TABLE_DEFINITIONS, null);
-
- if (json == null) {
- return Collections.emptyList();
- }
-
- Type listType = new TypeToken>() {
- }.getType();
-
-
- try {
- return gson.fromJson(json, listType);
- } catch (Exception ex) {
- Logger.getLogger(UserConfigurationService.class.getName()).log(Level.WARNING, "Unable to read bigtable options", ex);
- return Collections.emptyList();
- }
- }
-
-
- public List loadCredentialRecords() {
-
- String json = getPreferences().get(CREDENTIAL_RECORDS, null);
-
- if (json == null) {
- return Collections.emptyList();
- }
-
- Type listType = new TypeToken>() {}.getType();
-
- List dtos = gson.fromJson(json, listType);
-
- if (dtos == null) {
- return Collections.emptyList();
- }
-
- return dtos.stream().map(CredentialsRecord::fromDto).collect(Collectors.toList());
- }
-
-
- public void updateCredentialRecords(List records) {
-
- List dtos = records.stream().map(CredentialsRecord::toDto).collect(Collectors.toList());
-
- String json = gson.toJson(dtos);
-
- getPreferences().put(CREDENTIAL_RECORDS, json);
- }
-
- private Preferences getPreferences() {
- return Preferences.userRoot().node(PREFERENCES_USER_ROOT_NODE_NAME);
- }
-
-}
diff --git a/src/main/resources/css/main.css b/src/main/resources/css/main.css
index 3fb7f5f..8b13789 100644
--- a/src/main/resources/css/main.css
+++ b/src/main/resources/css/main.css
@@ -1,33 +1 @@
-.root {
- -fx-pref-height: 600.0;
- -fx-pref-width: 700.0;
-}
-
-.title {
- -fx-font-size: 14;
- -fx-font-name: "System Bold";
- -fx-alignment: "CENTER";
- -fx-padding: 10 20 10 20;
-}
-
-.tableTitleHBox {
- -fx-alignment: "CENTER";
- -fx-spacing: 3;
-}
-
-.tableTitleHBox .button {
- -fx-font-size: 9;
-}
-
-.scanTableControls {
- -fx-alignment: "CENTER";
- -fx-hgap: 5;
- -fx-vgap: 5;
-}
-
-.scanTableControls .hBox {
- -fx-spacing: 0
-}
-
-
diff --git a/src/main/resources/fxml/bigtable_instance_dialog.fxml b/src/main/resources/fxml/bigtable_instance_dialog.fxml
index 1d54421..b53d6cb 100644
--- a/src/main/resources/fxml/bigtable_instance_dialog.fxml
+++ b/src/main/resources/fxml/bigtable_instance_dialog.fxml
@@ -3,7 +3,6 @@
diff --git a/src/main/resources/fxml/bigtable_menu_bar.fxml b/src/main/resources/fxml/bigtable_menu_bar.fxml
index df49b62..9090863 100644
--- a/src/main/resources/fxml/bigtable_menu_bar.fxml
+++ b/src/main/resources/fxml/bigtable_menu_bar.fxml
@@ -4,16 +4,13 @@
-
-
-
+
@@ -22,8 +19,6 @@
-
-
diff --git a/src/main/resources/fxml/bigtable_table_view.fxml b/src/main/resources/fxml/bigtable_table_view.fxml
new file mode 100644
index 0000000..2995177
--- /dev/null
+++ b/src/main/resources/fxml/bigtable_table_view.fxml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/fxml/bigtable_tables_list_view.fxml b/src/main/resources/fxml/bigtable_tables_list_view.fxml
index 18b9e00..7b1ed5e 100644
--- a/src/main/resources/fxml/bigtable_tables_list_view.fxml
+++ b/src/main/resources/fxml/bigtable_tables_list_view.fxml
@@ -1,23 +1,8 @@
-
-
-
-
-
-
-
+
-
-
-
+
\ No newline at end of file
diff --git a/src/main/resources/fxml/bigtable_value_types_dialog.fxml b/src/main/resources/fxml/bigtable_value_types_dialog.fxml
index 179cc8d..4b561b3 100644
--- a/src/main/resources/fxml/bigtable_value_types_dialog.fxml
+++ b/src/main/resources/fxml/bigtable_value_types_dialog.fxml
@@ -12,7 +12,13 @@
-
+
diff --git a/src/main/resources/fxml/bigtable_view.fxml b/src/main/resources/fxml/bigtable_view.fxml
deleted file mode 100644
index 8c165d8..0000000
--- a/src/main/resources/fxml/bigtable_view.fxml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/resources/fxml/edit_single_credentials_dialog_pane.fxml b/src/main/resources/fxml/edit_single_credentials_dialog_pane.fxml
deleted file mode 100644
index 9e52fbe..0000000
--- a/src/main/resources/fxml/edit_single_credentials_dialog_pane.fxml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/resources/fxml/main.fxml b/src/main/resources/fxml/main.fxml
index 0b938ee..1f3dd38 100644
--- a/src/main/resources/fxml/main.fxml
+++ b/src/main/resources/fxml/main.fxml
@@ -1,65 +1,28 @@
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
-
-
+
+
+
diff --git a/src/main/resources/fxml/manage_credentials_dialog_pane.fxml b/src/main/resources/fxml/manage_credentials_dialog_pane.fxml
index 897cef4..b69dab4 100644
--- a/src/main/resources/fxml/manage_credentials_dialog_pane.fxml
+++ b/src/main/resources/fxml/manage_credentials_dialog_pane.fxml
@@ -13,8 +13,7 @@
prefWidth="600.0"
type="DialogPane"
headerText="Manage credentials"
- xmlns="http://javafx.com/javafx/8.0.121"
- xmlns:fx="http://javafx.com/fxml/1">
+ xmlns:fx="http://javafx.com/fxml">
diff --git a/src/main/resources/fxml/row_selection_view.fxml b/src/main/resources/fxml/row_selection_view.fxml
new file mode 100644
index 0000000..ad5f952
--- /dev/null
+++ b/src/main/resources/fxml/row_selection_view.fxml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/fxml/specify_credentials_path_dialog.fxml b/src/main/resources/fxml/specify_credentials_path_dialog.fxml
new file mode 100644
index 0000000..aba998e
--- /dev/null
+++ b/src/main/resources/fxml/specify_credentials_path_dialog.fxml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+