Skip to content

Commit

Permalink
Add UI Improvements:
Browse files Browse the repository at this point in the history
- substring search in acl Viewer
- search by principal name in acl viewer
- copy topic name to clipboard in describe topic dialog
  • Loading branch information
an0r0c committed Sep 30, 2021
1 parent aa24deb commit 99051a3
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 18 deletions.
38 changes: 27 additions & 11 deletions src/main/java/at/esque/kafka/acl/viewer/AclViewerController.java
Expand Up @@ -9,14 +9,10 @@
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.util.Callback;
import org.apache.kafka.common.resource.PatternType;
import org.apache.kafka.common.resource.ResourceType;
Expand All @@ -34,6 +30,9 @@ public class AclViewerController {
@FXML
TextField resourceName;

@FXML
TextField principalName;

@FXML
ComboBox<PatternType> resourcePatternCombo;

Expand All @@ -55,6 +54,9 @@ public class AclViewerController {
@FXML
TableColumn<Acl, String> hostColumn;

@FXML
ToggleButton substringSearch;

private KafkaesqueAdminClient adminClient;

private BooleanProperty refreshRunning = new SimpleBooleanProperty(false);
Expand Down Expand Up @@ -123,13 +125,20 @@ private void startSearch(ActionEvent actionEvent) {
runInDaemonThread(() -> {
List<Acl> aclList = new ArrayList<>();
Platform.runLater(() -> refreshRunning.setValue(true));
adminClient.getACLs(resourceTypeCombo.getValue(), resourcePatternCombo.getValue(), resourceName.getText())
.forEach(acl -> Platform.runLater(() -> aclList.add(new Acl(acl))));

if(substringSearch.isSelected())
{
adminClient.getACLsBySubstring(resourceTypeCombo.getValue(), resourcePatternCombo.getValue(), resourceName.getText(), principalName.getText())
.forEach(acl -> Platform.runLater(() -> aclList.add(new Acl(acl))));
}
else {
adminClient.getACLs(resourceTypeCombo.getValue(), resourcePatternCombo.getValue(), resourceName.getText(), principalName.getText())
.forEach(acl -> Platform.runLater(() -> aclList.add(new Acl(acl))));
}
Platform.runLater(() -> {
refreshRunning.setValue(true);
});
adminClient.getACLs(resourceTypeCombo.getValue(), resourcePatternCombo.getValue(), resourceName.getText())
.forEach(acl -> Platform.runLater(() -> aclList.add(new Acl(acl))));

Platform.runLater(() -> refreshRunning.setValue(false));
Platform.runLater(() -> resultView.setItems(FXCollections.observableArrayList(aclList)));
});
Expand All @@ -141,6 +150,13 @@ private void addACL(ActionEvent actionEvent)
CreateACLDialog.show(adminClient);
}

@FXML
private void resourceNameFieldkeyPressed(KeyEvent event){
if (event.getCode().equals(KeyCode.ENTER)) {
startSearch(null);
}
}

public void stop() {
adminClient = null;
}
Expand Down
26 changes: 24 additions & 2 deletions src/main/java/at/esque/kafka/cluster/KafkaesqueAdminClient.java
Expand Up @@ -77,6 +77,7 @@ public DescribeTopicWrapper describeTopic(String topic) {
DescribeTopicsResult describeResult = adminClient.describeTopics(Collections.singletonList(topic));
ConfigResource configResource = new ConfigResource(ConfigResource.Type.TOPIC, topic);
DescribeConfigsResult configsResult = adminClient.describeConfigs(Collections.singletonList(configResource));

try {
TopicDescription topicDescription = describeResult.values().get(topic).get(10, TimeUnit.SECONDS);
Config config = configsResult.values().get(configResource).get(10, TimeUnit.SECONDS);
Expand All @@ -103,13 +104,15 @@ public List<Lag> getConsumerGroups() {
return Collections.EMPTY_LIST;
}

public List<AclBinding> getACLs(ResourceType resourceType, PatternType resourcePattern, String resourceName) {
public List<AclBinding> getACLs(ResourceType resourceType, PatternType resourcePattern, String resourceName, String principalName) {
try {
if ("".equals(resourceName))
resourceName = null;
if ("".equals(principalName))
principalName = null;

AclBindingFilter aclBindingFilter = new AclBindingFilter(new ResourcePatternFilter(resourceType, resourceName, resourcePattern),
new AccessControlEntryFilter(null, null, AclOperation.ANY, AclPermissionType.ANY));
new AccessControlEntryFilter(principalName, null, AclOperation.ANY, AclPermissionType.ANY));

DescribeAclsResult describeAclsResult = adminClient.describeAcls(aclBindingFilter);

Expand All @@ -121,6 +124,25 @@ public List<AclBinding> getACLs(ResourceType resourceType, PatternType resourceP
return Collections.EMPTY_LIST;
}

public List<AclBinding> getACLsBySubstring(ResourceType resourceType, PatternType resourcePattern, String resourceName, String principalName) {
try {
AclBindingFilter aclBindingFilter = new AclBindingFilter(new ResourcePatternFilter(resourceType, null, resourcePattern),
new AccessControlEntryFilter(null, null, AclOperation.ANY, AclPermissionType.ANY));

DescribeAclsResult describeAclsResult = adminClient.describeAcls(aclBindingFilter);

return describeAclsResult.values().get().stream()
.filter(acl -> "".equals(resourceName) ? true : acl.pattern().name().contains(resourceName))
.filter(acl -> "".equals(principalName) ? true : acl.entry().principal().contains(principalName))
.collect(Collectors.toList());

} catch (Exception e) {
Platform.runLater(() -> ErrorAlert.show(e));
}
return Collections.EMPTY_LIST;
}


public void deleteAcl(AclBinding aclBinding) {
try {
AclBindingFilter aclBindingFilter = new AclBindingFilter(new ResourcePatternFilter(aclBinding.pattern().resourceType(), aclBinding.pattern().name(), aclBinding.pattern().patternType()),
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/at/esque/kafka/topics/DescribeTopicController.java
@@ -1,8 +1,15 @@
package at.esque.kafka.topics;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.text.Text;
import org.apache.kafka.clients.admin.ConfigEntry;
import org.apache.kafka.clients.admin.TopicDescription;
import org.apache.kafka.common.TopicPartitionInfo;
Expand All @@ -23,13 +30,26 @@ public class DescribeTopicController {
@FXML
public ListView<TopicPartitionInfo> partitionInfoList;

@FXML
public Button topicNameClpt;

public void setup(DescribeTopicWrapper describeTopicWrapper) {
TopicDescription topicDescription = describeTopicWrapper.getTopicDescription();
topicName.setText(topicDescription.name());
partitions.setText("" + topicDescription.partitions().size());
isInternal.setText("" + topicDescription.isInternal());
partitionInfoList.getItems().addAll(topicDescription.partitions());
showConfigsInListView(describeTopicWrapper.getConfigurations());

topicNameClpt.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
final Clipboard clipboard = Clipboard.getSystemClipboard();
final ClipboardContent content = new ClipboardContent();
content.putString(topicName.getText());
clipboard.setContent(content);
}
});
}

private void showConfigsInListView(Collection<ConfigEntry> configurations) {
Expand Down
28 changes: 23 additions & 5 deletions src/main/resources/fxml/aclViewer.fxml
Expand Up @@ -13,10 +13,10 @@
<?import org.kordamp.ikonli.javafx.FontIcon?>
<?import java.lang.String?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.control.ToggleButton?>
<BorderPane prefHeight="295.0" prefWidth="497.0" xmlns="http://javafx.com/javafx/11.0.1"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="at.esque.kafka.acl.viewer.AclViewerController">
<center>

<TableView fx:id="resultView" BorderPane.alignment="CENTER">
<columns>
<TableColumn fx:id="resourceTypeColumn" editable="false" prefWidth="70.0" text="Resource Type"/>
Expand All @@ -41,22 +41,36 @@
<ColumnConstraints hgrow="NEVER" maxWidth="50.0" minWidth="10.0" prefWidth="100.0"/>
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="40.0" vgrow="NEVER"/>
<RowConstraints minHeight="30.0" prefHeight="40.0" vgrow="NEVER"/>
<RowConstraints minHeight="10.0" prefHeight="60.0" vgrow="NEVER"/>
<RowConstraints minHeight="30.0" prefHeight="35.0" vgrow="NEVER"/>
<RowConstraints minHeight="30.0" prefHeight="35.0" vgrow="NEVER"/>
</rowConstraints>
<children>
<Label text="Resource Type:"/>
<Label text="Resource Name:" GridPane.rowIndex="1"/>
<ComboBox fx:id="resourceTypeCombo" maxWidth="1.7976931348623157E308" prefHeight="25.0"
prefWidth="176.0" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"/>
<TextField fx:id="resourceName" maxWidth="1.7976931348623157E308" prefHeight="25.0" prefWidth="275.0"
GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="1"/>
GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="1" onKeyPressed="#resourceNameFieldkeyPressed"/>
<Label prefHeight="17.0" prefWidth="100.0" text="Resource Pattern:" GridPane.columnIndex="2"/>
<ComboBox fx:id="resourcePatternCombo" maxWidth="1.7976931348623157E308" prefHeight="25.0"
prefWidth="176.0" GridPane.columnIndex="3" GridPane.hgrow="ALWAYS" GridPane.vgrow="ALWAYS"/>
<ToggleButton fx:id="substringSearch" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
mnemonicParsing="false" prefWidth="30.0"
GridPane.columnIndex="4" GridPane.rowIndex="1" GridPane.halignment="CENTER">
<styleClass>
<String fx:value="secondary"/>
</styleClass>
<tooltip>
<Tooltip text="Substring Search"/>
</tooltip>
<graphic>
<FontIcon iconColor="GRAY" iconLiteral="fa-asterisk" iconSize="20"/>
</graphic>
</ToggleButton>
<Button fx:id="searchButton" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
mnemonicParsing="false" onAction="#startSearch" prefWidth="30.0"
GridPane.columnIndex="4" GridPane.rowIndex="1" GridPane.halignment="CENTER" GridPane.columnSpan="1">
GridPane.columnIndex="4" GridPane.rowIndex="2" GridPane.halignment="CENTER" >
<styleClass>
<String fx:value="success"/>
</styleClass>
Expand All @@ -82,6 +96,10 @@
iconSize="20"/>
</graphic>
</Button>

<Label text="Principal Name:" GridPane.rowIndex="2"/>
<TextField fx:id="principalName" maxWidth="1.7976931348623157E308" prefHeight="25.0" prefWidth="275.0"
GridPane.columnIndex="1" GridPane.columnSpan="3" GridPane.rowIndex="2" onKeyPressed="#resourceNameFieldkeyPressed"/>
</children>
</GridPane>
</top>
Expand Down
15 changes: 15 additions & 0 deletions src/main/resources/fxml/describeTopic.fxml
Expand Up @@ -8,6 +8,11 @@
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Text?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Button?>
<?import org.kordamp.ikonli.javafx.FontIcon?>
<?import javafx.scene.control.Tooltip?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="at.esque.kafka.topics.DescribeTopicController">
Expand Down Expand Up @@ -50,7 +55,17 @@
<Insets left="20.0"/>
</GridPane.margin>
</Label>


<Label fx:id="topicName" text="TopicName" GridPane.columnIndex="1"/>
<Button fx:id="topicNameClpt" text="Copy" GridPane.columnIndex="2" maxHeight="20.0" maxWidth="15.0" minHeight="20.0" minWidth="15.0" mnemonicParsing="false" prefHeight="30.0" prefWidth="15.0">
<graphic>
<FontIcon iconLiteral="fa-copy" strokeType="OUTSIDE" strokeWidth="0.0"/>
</graphic>
<tooltip>
<Tooltip text="Copy topic name to clipboard"/>
</tooltip>
</Button>
<Label fx:id="partitions" text="Number of paritions" GridPane.columnIndex="1"
GridPane.rowIndex="1"/>
<Label fx:id="isInternal" text="is an internal topic" GridPane.columnIndex="1"
Expand Down

0 comments on commit 99051a3

Please sign in to comment.