diff --git a/backend/pom.xml b/backend/pom.xml
index 585e02b..9a55f62 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -42,7 +42,6 @@
2.22.2
UTF-8
3.6.3
- 2.0.13
4.2.1
2.13.0
2.13.0
diff --git a/frontend/pom.xml b/frontend/pom.xml
new file mode 100644
index 0000000..180e2c2
--- /dev/null
+++ b/frontend/pom.xml
@@ -0,0 +1,136 @@
+
+
+ 4.0.0
+
+
+
+ io.zell
+ zdb
+ 2.4.0-SNAPSHOT
+ ../pom.xml
+
+
+ frontend
+ frontend
+
+
+ UTF-8
+ 5.10.0
+
+
+
+
+ org.openjfx
+ javafx-controls
+ 21
+
+
+ org.openjfx
+ javafx-fxml
+ 21
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ ${junit.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${junit.version}
+ test
+
+
+ io.zell
+ backend
+ 2.4.0-SNAPSHOT
+ compile
+
+
+
+ org.slf4j
+ slf4j-simple
+ ${version.slf4j}
+ test
+
+
+
+
+
+
+
+
+ com.spotify.fmt
+ fmt-maven-plugin
+ ${plugin.version.fmt}
+
+
+ validate
+
+ format
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.11.0
+
+
+ 21
+
+
+
+ org.openjfx
+ javafx-maven-plugin
+ 0.0.8
+
+
+
+ default-cli
+
+ io.zell.zdb.frontend.ZdbFrontendMain
+ app
+ app
+ app
+ true
+ true
+ true
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.7.1
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+ io.zell.zdb.frontend.ZdbFrontendMain
+ true
+
+
+
+ jar-with-dependencies
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/main/java/io/zell/zdb/frontend/LogViewController.java b/frontend/src/main/java/io/zell/zdb/frontend/LogViewController.java
new file mode 100644
index 0000000..05be199
--- /dev/null
+++ b/frontend/src/main/java/io/zell/zdb/frontend/LogViewController.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright © 2021 Christopher Kujawa (zelldon91@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.zell.zdb.frontend;
+
+import io.zell.zdb.log.LogContentReader;
+import io.zell.zdb.log.records.ApplicationRecord;
+import io.zell.zdb.log.records.PersistedRecord;
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.ResourceBundle;
+import java.util.function.Consumer;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.*;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.input.*;
+import javafx.stage.DirectoryChooser;
+
+public class LogViewController implements Initializable {
+
+ @FXML private TableView zeebeData;
+
+ @FXML private Button findDataPath;
+
+ @FXML private TextField dataPath;
+
+ @FXML private TextField instanceKey;
+ @FXML private TextField fromPosition;
+ @FXML private TextField toPosition;
+ private final DirectoryChooser directoryChooser = new DirectoryChooser();
+ private ObservableList dataObservableList;
+
+ @Override
+ public void initialize(final URL url, final ResourceBundle resourceBundle) {
+ // time to initialize fields
+ final var userHome = System.getProperty("user.home");
+ this.dataPath.setText(userHome);
+
+ this.dataObservableList = FXCollections.observableList(new ArrayList<>());
+ // put into the data table view
+ this.zeebeData.setItems(this.dataObservableList);
+
+ // define columns
+ this.zeebeData
+ .getColumns()
+ .setAll(
+ LogViewController.createTableColumn("Position", "position"),
+ LogViewController.createTableColumn(
+ "Source\nRecord\nPosition", "sourceRecordPosition"),
+ LogViewController.createTableColumn("Timestamp", "timestamp"),
+ LogViewController.createTableColumn("Key", "key"),
+ LogViewController.createTableColumn("Record\ntype", "recordType"),
+ LogViewController.createTableColumn("Value\ntype", "valueType"),
+ LogViewController.createTableColumn("Intent", "intent"),
+ LogViewController.createTableColumn("Rejection\ntype", "rejectionType"),
+ LogViewController.createTableColumn("Rejection\nreason", "rejectionReason"),
+ LogViewController.createTableColumn("Request\nID", "requestId"),
+ LogViewController.createTableColumn("Request\nstream\nID", "requestStreamId"),
+ LogViewController.createTableColumn("Protocol\nversion", "protocolVersion"),
+ LogViewController.createTableColumn("Broker\nversion", "brokerVersion"),
+ LogViewController.createTableColumn("Record\nversion", "recordVersion"),
+ LogViewController.createTableColumn("Auth\ndata", "authData"),
+ LogViewController.createTableColumn("Record\nvalue", "recordValue"));
+
+ // enable multi-selection
+ this.zeebeData.getSelectionModel().setCellSelectionEnabled(true);
+ this.zeebeData.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+ this.zeebeData.setOnKeyPressed(new TableViewKeyEventClipboardCopier<>(this.zeebeData));
+ }
+
+ private static TableColumn createTableColumn(
+ final String displayName, final String propertyName) {
+ final TableColumn column = new TableColumn(displayName);
+ column.setCellValueFactory(new PropertyValueFactory(propertyName));
+ return column;
+ }
+
+ @FXML
+ protected void onFindFile() {
+ this.directoryChooser.setTitle("Zeebe data path");
+ this.directoryChooser.setInitialDirectory(new File(System.getProperty("user.home")));
+
+ final File file = this.directoryChooser.showDialog(this.findDataPath.getScene().getWindow());
+ if (file != null) {
+ this.dataPath.setText(file.getAbsolutePath());
+ findLog();
+ }
+ }
+
+ @FXML
+ private void findLog() {
+ if (this.dataPath.getText() == null || this.dataPath.getText().isBlank()) {
+ return;
+ }
+ final var logContentReader = new LogContentReader(new File(this.dataPath.getText()).toPath());
+
+ consumeValueFromTextField(this.instanceKey, logContentReader::filterForProcessInstance);
+ consumeValueFromTextField(this.fromPosition, logContentReader::seekToPosition);
+ consumeValueFromTextField(this.toPosition, logContentReader::limitToPosition);
+
+ fillTableWithData(logContentReader);
+ }
+
+ private void consumeValueFromTextField(final TextField textField, final Consumer consumer) {
+ if (textField.getText() != null && !textField.getText().isBlank()) {
+ try {
+ final long instanceKeyLong = Long.parseLong(textField.getText());
+ consumer.accept(instanceKeyLong);
+ } catch (final NumberFormatException nfe) {
+ System.out.printf(
+ "Expected to retrieve a number as instance key, but '%s' wasn't%n",
+ textField.getText());
+ }
+ }
+ }
+
+ private void fillTableWithData(final LogContentReader logContentReader) {
+ this.dataObservableList.clear();
+ while (logContentReader.hasNext()) {
+ final PersistedRecord next = logContentReader.next();
+
+ if (next instanceof final ApplicationRecord applicationRecord) {
+ for (final var r : applicationRecord.getEntries()) {
+ final var zeebeRecord =
+ new ZeebeRecord(
+ r.getPosition(),
+ r.getSourceRecordPosition(),
+ r.getTimestamp(),
+ r.getKey(),
+ r.getRecordType().name(),
+ r.getValueType().name(),
+ r.getIntent().name(),
+ r.getRejectionType().name(),
+ r.getRejectionReason(),
+ r.getRequestId(),
+ r.getRequestStreamId(),
+ r.getProtocolVersion(),
+ r.getBrokerVersion(),
+ r.getRecordVersion(),
+ r.getAuthData(),
+ r.getRecordValue().toString());
+ this.dataObservableList.add(zeebeRecord);
+ }
+ }
+ }
+ }
+}
diff --git a/frontend/src/main/java/io/zell/zdb/frontend/StateViewController.java b/frontend/src/main/java/io/zell/zdb/frontend/StateViewController.java
new file mode 100644
index 0000000..7ba723f
--- /dev/null
+++ b/frontend/src/main/java/io/zell/zdb/frontend/StateViewController.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright © 2021 Christopher Kujawa (zelldon91@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.zell.zdb.frontend;
+
+import io.camunda.zeebe.protocol.ZbColumnFamilies;
+import io.zell.zdb.state.KeyFormatters;
+import io.zell.zdb.state.ZeebeDbReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.ResourceBundle;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.*;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.input.*;
+import javafx.stage.DirectoryChooser;
+
+public class StateViewController implements Initializable {
+
+ @FXML private TableView zeebeData;
+
+ @FXML private Button findDataPath;
+
+ @FXML private TextField dataPath;
+
+ @FXML private ChoiceBox columnFamily;
+
+ private final DirectoryChooser directoryChooser = new DirectoryChooser();
+ private ObservableList dataObservableList;
+
+ @Override
+ public void initialize(final URL url, final ResourceBundle resourceBundle) {
+ // time to initialize fields
+ final var userHome = System.getProperty("user.home");
+ this.dataPath.setText(userHome);
+ this.dataPath.setEditable(false);
+
+ this.columnFamily.setItems(
+ FXCollections.observableList(
+ Arrays.stream(ZbColumnFamilies.values()).map(Enum::name).toList()));
+ this.columnFamily.setValue(ZbColumnFamilies.DEFAULT.name());
+
+ // put into the data table view
+ this.dataObservableList = FXCollections.observableList(new ArrayList<>());
+ this.zeebeData.setItems(this.dataObservableList);
+ // define columns
+ this.zeebeData.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY_ALL_COLUMNS);
+ this.zeebeData
+ .getColumns()
+ .setAll(
+ StateViewController.createTableColumn("Key", "key"),
+ StateViewController.createTableColumn("Value", "value"));
+
+ // enable multi-selection
+ this.zeebeData.getSelectionModel().setCellSelectionEnabled(true);
+ this.zeebeData.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+ this.zeebeData.setOnKeyPressed(new TableViewKeyEventClipboardCopier<>(this.zeebeData));
+ }
+
+ private static TableColumn createTableColumn(
+ final String displayName, final String propertyName) {
+ final TableColumn column = new TableColumn(displayName);
+ column.setCellValueFactory(new PropertyValueFactory(propertyName));
+ return column;
+ }
+
+ public class StateDataKV {
+ private final StringProperty key;
+ private final StringProperty value;
+
+ public StateDataKV(final String key, final String value) {
+ this.key = new SimpleStringProperty(key);
+ this.value = new SimpleStringProperty(value);
+ }
+
+ public String getKey() {
+ return this.key.get();
+ }
+
+ public StringProperty keyProperty() {
+ return this.key;
+ }
+
+ public void setKey(final String key) {
+ this.key.set(key);
+ }
+
+ public String getValue() {
+ return this.value.get();
+ }
+
+ public StringProperty valueProperty() {
+ return this.value;
+ }
+
+ public void setValue(final String value) {
+ this.value.set(value);
+ }
+ }
+
+ @FXML
+ protected void onFindFile() {
+ this.directoryChooser.setTitle("Zeebe data path");
+ this.directoryChooser.setInitialDirectory(new File(System.getProperty("user.home")));
+
+ final File file = this.directoryChooser.showDialog(this.findDataPath.getScene().getWindow());
+
+ if (file != null) {
+ this.dataPath.setText(file.getAbsolutePath());
+ fillTableViewWithStateData(this.dataPath.getText(), this.columnFamily.getValue());
+ }
+ }
+
+ private void fillTableViewWithStateData(final String path, final String columnFamilyName) {
+ // read data based on column family
+ final var zeebeDbReader = new ZeebeDbReader(new File(path).toPath());
+ final var columnFamilyValue = ZbColumnFamilies.valueOf(columnFamilyName);
+
+ final var keyFormatter = KeyFormatters.ofDefault().forColumnFamily(columnFamilyValue);
+
+ // remove old content
+ this.dataObservableList.clear();
+ this.zeebeData.setColumnResizePolicy(TableView.UNCONSTRAINED_RESIZE_POLICY);
+ // update table view
+ zeebeDbReader.visitDBWithPrefix(
+ columnFamilyValue,
+ (key, value) ->
+ this.dataObservableList.add(new StateDataKV(keyFormatter.formatKey(key), value)));
+ }
+
+ public void selectColumnFamily() {
+ // do something on selecting CF
+ try {
+ final var expectedPath = this.dataPath.getText();
+
+ fillTableViewWithStateData(expectedPath, this.columnFamily.getValue());
+ } catch (final Exception exception) {
+ if (exception instanceof FileNotFoundException) {
+ // no state path
+ System.out.println(
+ String.format(
+ "Current path %s doesn't point to a state path.", this.dataPath.getText()));
+ return;
+ }
+ exception.printStackTrace();
+ }
+ }
+}
diff --git a/frontend/src/main/java/io/zell/zdb/frontend/TableViewKeyEventClipboardCopier.java b/frontend/src/main/java/io/zell/zdb/frontend/TableViewKeyEventClipboardCopier.java
new file mode 100644
index 0000000..0b4121e
--- /dev/null
+++ b/frontend/src/main/java/io/zell/zdb/frontend/TableViewKeyEventClipboardCopier.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2021 Christopher Kujawa (zelldon91@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.zell.zdb.frontend;
+
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+import javafx.scene.control.TablePosition;
+import javafx.scene.control.TableView;
+import javafx.scene.input.*;
+
+public class TableViewKeyEventClipboardCopier implements EventHandler {
+
+ public static final KeyCodeCombination KEY_CODE_COMBINATION_COPY =
+ new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_ANY);
+ private final TableView tableView;
+
+ public TableViewKeyEventClipboardCopier(final TableView tableView) {
+ this.tableView = tableView;
+ }
+
+ @Override
+ public void handle(final T keyEvent) {
+ if (KEY_CODE_COMBINATION_COPY.match(keyEvent)) {
+ if (keyEvent.getSource() instanceof TableView) {
+ final var clipboard = Clipboard.getSystemClipboard();
+ final var content = new ClipboardContent();
+
+ final ObservableList selectedCells =
+ this.tableView.getSelectionModel().getSelectedCells();
+
+ for (final var position : selectedCells) {
+ final var value = position.getTableColumn().getCellObservableValue(position.getRow());
+ final String valueStr = value.getValue().toString();
+ System.out.println(valueStr);
+ content.putString(valueStr);
+ }
+ clipboard.setContent(content);
+ System.out.println("Selection copied to clipboard");
+
+ // event is handled, consume it
+ keyEvent.consume();
+ }
+ }
+ }
+}
diff --git a/frontend/src/main/java/io/zell/zdb/frontend/ZdbApplication.java b/frontend/src/main/java/io/zell/zdb/frontend/ZdbApplication.java
new file mode 100644
index 0000000..2e1c212
--- /dev/null
+++ b/frontend/src/main/java/io/zell/zdb/frontend/ZdbApplication.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright © 2021 Christopher Kujawa (zelldon91@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.zell.zdb.frontend;
+
+import java.io.IOException;
+import javafx.application.Application;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Scene;
+import javafx.scene.input.*;
+import javafx.stage.Stage;
+
+public class ZdbApplication extends Application {
+ @Override
+ public void start(final Stage stage) throws IOException {
+ final FXMLLoader fxmlLoader = new FXMLLoader(ZdbApplication.class.getResource("zdb-view.fxml"));
+ final Scene scene = new Scene(fxmlLoader.load(), 320, 240);
+ stage.setTitle("Zeebe debug and inspection tool");
+ stage.setScene(scene);
+ stage.show();
+ }
+
+ public static void main(final String[] args) {
+ launch();
+ }
+}
diff --git a/frontend/src/main/java/io/zell/zdb/frontend/ZdbFrontendMain.java b/frontend/src/main/java/io/zell/zdb/frontend/ZdbFrontendMain.java
new file mode 100644
index 0000000..cf6149f
--- /dev/null
+++ b/frontend/src/main/java/io/zell/zdb/frontend/ZdbFrontendMain.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright © 2021 Christopher Kujawa (zelldon91@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.zell.zdb.frontend;
+
+public class ZdbFrontendMain {
+
+ public static void main(String[] args) {
+ ZdbApplication.main(args);
+ }
+}
diff --git a/frontend/src/main/java/io/zell/zdb/frontend/ZeebeRecord.java b/frontend/src/main/java/io/zell/zdb/frontend/ZeebeRecord.java
new file mode 100644
index 0000000..6d4411c
--- /dev/null
+++ b/frontend/src/main/java/io/zell/zdb/frontend/ZeebeRecord.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright © 2021 Christopher Kujawa (zelldon91@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.zell.zdb.frontend;
+
+import javafx.beans.property.*;
+
+public class ZeebeRecord {
+ // Record(val position: Long,
+ // val sourceRecordPosition: Long,
+ // val timestamp: Long,
+ // val key: Long,
+ // val recordType: RecordType,
+ // val valueType: ValueType,
+ // @Serializable(with = IntentSerializer::class)
+ // val intent: Intent,
+ // val rejectionType: RejectionType? = RejectionType.NULL_VAL,
+ // val rejectionReason: String? = "",
+ // val requestId: Long? = 0,
+ // val requestStreamId: Int = 0,
+ // val protocolVersion: Int,
+ // val brokerVersion: String,
+ // val recordVersion: Int ? = 0,
+ // val authData: String ? = "",
+ // val recordValue: JsonElement,
+ // /*Transient marks to ignore the property during serialization */
+ // @Transient val piRelatedValue: ProcessInstanceRelatedValue? =
+ // null
+ private final LongProperty position;
+ private final LongProperty sourceRecordPosition;
+ private final LongProperty timestamp;
+ private final LongProperty key;
+ private final StringProperty recordType;
+ private final StringProperty ValueType;
+ private final StringProperty intent;
+
+ private final StringProperty rejectionType;
+ private final StringProperty rejectionReason;
+ private final LongProperty requestId;
+ private final IntegerProperty requestStreamId;
+ private final IntegerProperty protocolVersion;
+ private final StringProperty brokerVersion;
+ private final IntegerProperty recordVersion;
+ private final StringProperty authData;
+ private final StringProperty recordValue;
+
+ public ZeebeRecord(
+ final long position,
+ final long sourceRecordPostion,
+ final long timestamp,
+ final long key,
+ final String recordType,
+ final String valueType,
+ final String intent,
+ final String rejectionType,
+ final String rejectionReason,
+ final long requestId,
+ final int requestStreamId,
+ final int protocolVersion,
+ final String brokerVersion,
+ final int recordVersion,
+ final String authData,
+ final String recordValue) {
+ this.position = new SimpleLongProperty(position);
+ this.sourceRecordPosition = new SimpleLongProperty(sourceRecordPostion);
+ this.timestamp = new SimpleLongProperty(timestamp);
+ this.key = new SimpleLongProperty(key);
+ this.recordType = new SimpleStringProperty(recordType);
+ this.ValueType = new SimpleStringProperty(valueType);
+ this.intent = new SimpleStringProperty(intent);
+ this.rejectionType = new SimpleStringProperty(rejectionType);
+ this.rejectionReason = new SimpleStringProperty(rejectionReason);
+ this.requestId = new SimpleLongProperty(requestId);
+ this.requestStreamId = new SimpleIntegerProperty(requestStreamId);
+ this.protocolVersion = new SimpleIntegerProperty(protocolVersion);
+ this.brokerVersion = new SimpleStringProperty(brokerVersion);
+ this.recordVersion = new SimpleIntegerProperty(recordVersion);
+ this.authData = new SimpleStringProperty(authData);
+ this.recordValue = new SimpleStringProperty(recordValue);
+ }
+
+ public String getRejectionType() {
+ return this.rejectionType.get();
+ }
+
+ public StringProperty rejectionTypeProperty() {
+ return this.rejectionType;
+ }
+
+ public void setRejectionType(final String rejectionType) {
+ this.rejectionType.set(rejectionType);
+ }
+
+ public String getRejectionReason() {
+ return this.rejectionReason.get();
+ }
+
+ public StringProperty rejectionReasonProperty() {
+ return this.rejectionReason;
+ }
+
+ public void setRejectionReason(final String rejectionReason) {
+ this.rejectionReason.set(rejectionReason);
+ }
+
+ public long getRequestId() {
+ return this.requestId.get();
+ }
+
+ public LongProperty requestIdProperty() {
+ return this.requestId;
+ }
+
+ public void setRequestId(final long requestId) {
+ this.requestId.set(requestId);
+ }
+
+ public int getRequestStreamId() {
+ return this.requestStreamId.get();
+ }
+
+ public IntegerProperty requestStreamIdProperty() {
+ return this.requestStreamId;
+ }
+
+ public void setRequestStreamId(final int requestStreamId) {
+ this.requestStreamId.set(requestStreamId);
+ }
+
+ public int getProtocolVersion() {
+ return this.protocolVersion.get();
+ }
+
+ public IntegerProperty protocolVersionProperty() {
+ return this.protocolVersion;
+ }
+
+ public void setProtocolVersion(final int protocolVersion) {
+ this.protocolVersion.set(protocolVersion);
+ }
+
+ public String getBrokerVersion() {
+ return this.brokerVersion.get();
+ }
+
+ public StringProperty brokerVersionProperty() {
+ return this.brokerVersion;
+ }
+
+ public void setBrokerVersion(final String brokerVersion) {
+ this.brokerVersion.set(brokerVersion);
+ }
+
+ public int getRecordVersion() {
+ return this.recordVersion.get();
+ }
+
+ public IntegerProperty recordVersionProperty() {
+ return this.recordVersion;
+ }
+
+ public void setRecordVersion(final int recordVersion) {
+ this.recordVersion.set(recordVersion);
+ }
+
+ public String getAuthData() {
+ return this.authData.get();
+ }
+
+ public StringProperty authDataProperty() {
+ return this.authData;
+ }
+
+ public void setAuthData(final String authData) {
+ this.authData.set(authData);
+ }
+
+ public String getRecordValue() {
+ return this.recordValue.get();
+ }
+
+ public StringProperty recordValueProperty() {
+ return this.recordValue;
+ }
+
+ public void setRecordValue(final String recordValue) {
+ this.recordValue.set(recordValue);
+ }
+
+ public long getPosition() {
+ return this.position.get();
+ }
+
+ public LongProperty positionProperty() {
+ return this.position;
+ }
+
+ public void setPosition(final long position) {
+ this.position.set(position);
+ }
+
+ public long getSourceRecordPosition() {
+ return this.sourceRecordPosition.get();
+ }
+
+ public LongProperty sourceRecordPositionProperty() {
+ return this.sourceRecordPosition;
+ }
+
+ public void setSourceRecordPosition(final long sourceRecordPosition) {
+ this.sourceRecordPosition.set(sourceRecordPosition);
+ }
+
+ public long getTimestamp() {
+ return this.timestamp.get();
+ }
+
+ public LongProperty timestampProperty() {
+ return this.timestamp;
+ }
+
+ public void setTimestamp(final long timestamp) {
+ this.timestamp.set(timestamp);
+ }
+
+ public long getKey() {
+ return this.key.get();
+ }
+
+ public LongProperty keyProperty() {
+ return this.key;
+ }
+
+ public void setKey(final long key) {
+ this.key.set(key);
+ }
+
+ public String getRecordType() {
+ return this.recordType.get();
+ }
+
+ public StringProperty recordTypeProperty() {
+ return this.recordType;
+ }
+
+ public void setRecordType(final String recordType) {
+ this.recordType.set(recordType);
+ }
+
+ public String getValueType() {
+ return this.ValueType.get();
+ }
+
+ public StringProperty valueTypeProperty() {
+ return this.ValueType;
+ }
+
+ public void setValueType(final String valueType) {
+ this.ValueType.set(valueType);
+ }
+
+ public String getIntent() {
+ return this.intent.get();
+ }
+
+ public StringProperty intentProperty() {
+ return this.intent;
+ }
+
+ public void setIntent(final String intent) {
+ this.intent.set(intent);
+ }
+}
diff --git a/frontend/src/main/resources/io/zell/zdb/frontend/log-view.fxml b/frontend/src/main/resources/io/zell/zdb/frontend/log-view.fxml
new file mode 100644
index 0000000..916b75e
--- /dev/null
+++ b/frontend/src/main/resources/io/zell/zdb/frontend/log-view.fxml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/main/resources/io/zell/zdb/frontend/state-view.fxml b/frontend/src/main/resources/io/zell/zdb/frontend/state-view.fxml
new file mode 100644
index 0000000..7deadb8
--- /dev/null
+++ b/frontend/src/main/resources/io/zell/zdb/frontend/state-view.fxml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/main/resources/io/zell/zdb/frontend/zdb-view.fxml b/frontend/src/main/resources/io/zell/zdb/frontend/zdb-view.fxml
new file mode 100644
index 0000000..d35e0e5
--- /dev/null
+++ b/frontend/src/main/resources/io/zell/zdb/frontend/zdb-view.fxml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 5938369..995a92d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,6 +56,7 @@
21
3.3.1
2.23
+ 2.0.13
4.5
UTF-8
30.0-jre
@@ -114,6 +115,7 @@
backend
cli
+ frontend