Skip to content

Commit a3620d1

Browse files
authored
Add ability to modify a topics configuration via the UI. (#95)
* Add ability to modify configuration for topics * fix security requirements * tie in UI to be able to modify topic configs * restrict UI if not authorized
1 parent e4bb2d2 commit a3620d1

File tree

22 files changed

+437
-23
lines changed

22 files changed

+437
-23
lines changed

kafka-webview-ui/src/main/frontend/js/app.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,27 @@ var ApiClient = {
273273
}
274274
});
275275
},
276+
modifyTopicConfig: function(clusterId, topic, configName, configValue, callback) {
277+
var payloadJson = {
278+
topic: topic,
279+
config: {}
280+
};
281+
payloadJson['config'][configName] = configValue;
282+
283+
var payload = JSON.stringify(payloadJson);
284+
jQuery.ajax({
285+
type: 'POST',
286+
url: '/api/cluster/' + clusterId + '/modify/topic',
287+
data: payload,
288+
dataType: 'json',
289+
headers: ApiClient.getCsrfHeader(),
290+
success: callback,
291+
error: ApiClient.defaultErrorHandler,
292+
beforeSend: function(xhr) {
293+
xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');
294+
}
295+
});
296+
},
276297
defaultErrorHandler: function(jqXHR, textStatus, errorThrown) {
277298
// convert response to json
278299
var response = jQuery.parseJSON(jqXHR.responseText);

kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/configuration/SecurityConfig.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,10 @@ private void enableUserAuth(final HttpSecurity http) throws Exception {
119119
"/configuration/**",
120120

121121
// Create topic
122-
"/api/cluster/*/create/**"
122+
"/api/cluster/*/create/**",
123+
124+
// Modify topic
125+
"/api/cluster/*/modify/**"
123126
).hasRole("ADMIN")
124127

125128
// All other requests must be authenticated

kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/ApiController.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
package org.sourcelab.kafka.webview.ui.controller.api;
2626

2727
import org.sourcelab.kafka.webview.ui.controller.BaseController;
28+
import org.sourcelab.kafka.webview.ui.controller.api.exceptions.ApiException;
29+
import org.sourcelab.kafka.webview.ui.controller.api.exceptions.NotFoundApiException;
30+
import org.sourcelab.kafka.webview.ui.controller.api.requests.ConsumeRequest;
31+
import org.sourcelab.kafka.webview.ui.controller.api.requests.CreateTopicRequest;
32+
import org.sourcelab.kafka.webview.ui.controller.api.requests.ModifyTopicConfigRequest;
33+
import org.sourcelab.kafka.webview.ui.controller.api.responses.ResultResponse;
2834
import org.sourcelab.kafka.webview.ui.manager.kafka.KafkaOperations;
2935
import org.sourcelab.kafka.webview.ui.manager.kafka.KafkaOperationsFactory;
3036
import org.sourcelab.kafka.webview.ui.manager.kafka.SessionIdentifier;
@@ -330,6 +336,37 @@ public ResultResponse createTopic(@PathVariable final Long id, @RequestBody fina
330336
}
331337
}
332338

339+
/**
340+
* POST Modify a topic's configuration on cluster.
341+
* This should require ADMIN role.
342+
*/
343+
@ResponseBody
344+
@RequestMapping(path = "/cluster/{id}/modify/topic", method = RequestMethod.POST, produces = "application/json")
345+
public List<ConfigItem> modifyTopicConfig(
346+
@PathVariable final Long id,
347+
@RequestBody final ModifyTopicConfigRequest modifyTopicConfigRequest
348+
) {
349+
// Retrieve cluster
350+
final Cluster cluster = retrieveClusterById(id);
351+
352+
final String name = modifyTopicConfigRequest.getTopic();
353+
if (name == null || name.trim().isEmpty()) {
354+
throw new ApiException("ModifyTopic", "Invalid topic name");
355+
}
356+
357+
final Map<String, String> configEntries = modifyTopicConfigRequest.getConfig();
358+
if (configEntries == null || configEntries.isEmpty()) {
359+
throw new ApiException("ModifyTopic", "Invalid configuration defined");
360+
}
361+
362+
// Create new Operational Client
363+
try (final KafkaOperations operations = createOperationsClient(cluster)) {
364+
return operations.alterTopicConfig(name, configEntries).getConfigEntries();
365+
} catch (final Exception e) {
366+
throw new ApiException("ModifyTopic", e);
367+
}
368+
}
369+
333370
/**
334371
* GET Nodes within a cluster.
335372
*/

kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/ApiException.java renamed to kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/exceptions/ApiException.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* SOFTWARE.
2323
*/
2424

25-
package org.sourcelab.kafka.webview.ui.controller.api;
25+
package org.sourcelab.kafka.webview.ui.controller.api.exceptions;
2626

2727
/**
2828
* Represents an error that occurred within an API request.
@@ -41,7 +41,7 @@ public ApiException(final String type, final Throwable cause) {
4141
/**
4242
* Constructor.
4343
*/
44-
ApiException(final String type, final String message) {
44+
public ApiException(final String type, final String message) {
4545
super(message);
4646
this.type = type;
4747
}

kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/NotFoundApiException.java renamed to kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/exceptions/NotFoundApiException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* SOFTWARE.
2323
*/
2424

25-
package org.sourcelab.kafka.webview.ui.controller.api;
25+
package org.sourcelab.kafka.webview.ui.controller.api.exceptions;
2626

2727
/**
2828
* Error when requesting an object over the API that doesn't not exist.

kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/ConsumeRequest.java renamed to kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/requests/ConsumeRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* SOFTWARE.
2323
*/
2424

25-
package org.sourcelab.kafka.webview.ui.controller.api;
25+
package org.sourcelab.kafka.webview.ui.controller.api.requests;
2626

2727
import java.util.List;
2828
import java.util.Map;

kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/CreateTopicRequest.java renamed to kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/requests/CreateTopicRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* SOFTWARE.
2323
*/
2424

25-
package org.sourcelab.kafka.webview.ui.controller.api;
25+
package org.sourcelab.kafka.webview.ui.controller.api.requests;
2626

2727
/**
2828
* Represents a request to create a new topic.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* MIT License
3+
*
4+
* Copyright (c) 2017, 2018 SourceLab.org (https://github.com/Crim/kafka-webview/)
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package org.sourcelab.kafka.webview.ui.controller.api.requests;
26+
27+
import java.util.Map;
28+
29+
/**
30+
* Represents a request to modify a topic configuration.
31+
*/
32+
public class ModifyTopicConfigRequest {
33+
private String topic;
34+
private Map<String, String> config;
35+
36+
public String getTopic() {
37+
return topic;
38+
}
39+
40+
public Map<String, String> getConfig() {
41+
return config;
42+
}
43+
44+
@Override
45+
public String toString() {
46+
return "ModifyTopicConfigRequest{"
47+
+ "topic='" + topic + '\''
48+
+ ", config=" + config
49+
+ '}';
50+
}
51+
}

kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/ResultResponse.java renamed to kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/api/responses/ResultResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* SOFTWARE.
2323
*/
2424

25-
package org.sourcelab.kafka.webview.ui.controller.api;
25+
package org.sourcelab.kafka.webview.ui.controller.api.responses;
2626

2727
/**
2828
* Generic response object.

kafka-webview-ui/src/main/java/org/sourcelab/kafka/webview/ui/controller/stream/StreamController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
package org.sourcelab.kafka.webview.ui.controller.stream;
2626

2727
import org.sourcelab.kafka.webview.ui.controller.BaseController;
28-
import org.sourcelab.kafka.webview.ui.controller.api.ConsumeRequest;
28+
import org.sourcelab.kafka.webview.ui.controller.api.requests.ConsumeRequest;
2929
import org.sourcelab.kafka.webview.ui.manager.kafka.SessionIdentifier;
3030
import org.sourcelab.kafka.webview.ui.manager.kafka.ViewCustomizer;
3131
import org.sourcelab.kafka.webview.ui.manager.kafka.config.FilterDefinition;

0 commit comments

Comments
 (0)