Skip to content

Commit

Permalink
fix(ui): handle sche subject with special chars (#1354)
Browse files Browse the repository at this point in the history
close #1353

Co-authored-by: xinyu.liu <[email protected]>
  • Loading branch information
2 people authored and tchiotludo committed Apr 4, 2023
1 parent 35ef84a commit cd6cf2d
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 18 deletions.
2 changes: 1 addition & 1 deletion client/src/containers/Schema/SchemaDetail/Schema.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class Schema extends Root {

return (
<div>
<Header title={`Schema: ${schemaId}`} history={this.props.history} />
<Header title={`Schema: ${decodeURIComponent(schemaId)}`} history={this.props.history} />
<div className="tabs-container">
<ul className="nav nav-tabs" role="tablist">
{roles.registry['registry/update'] && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class SchemaVersions extends Root {
Do you want to delete version:{' '}
{
<code>
{schema.id} from {this.state.selectedSchema}
{schema.version} from {decodeURIComponent(this.state.selectedSchema)}
</code>
}{' '}
?
Expand Down
2 changes: 1 addition & 1 deletion client/src/containers/Schema/SchemaList/SchemaList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ class SchemaList extends Root {
}}
idCol="subject"
onDetails={subject => {
return `/ui/${selectedCluster}/schema/details/${subject}`;
return `/ui/${selectedCluster}/schema/details/${encodeURIComponent(subject)}`;
}}
actions={
roles.registry && roles.registry['registry/delete']
Expand Down
10 changes: 5 additions & 5 deletions client/src/utils/endpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,27 +199,27 @@ export const uriSchemaId = (clusterId, id) => {
};

export const uriSchemaVersions = (clusterId, subject) => {
return `${apiUrl}/${clusterId}/schema/${subject}/version`;
return `${apiUrl}/${clusterId}/schema/${encodeURIComponent(subject)}/version`;
};

export const uriDeleteSchema = (clusterId, subject) => {
return `${apiUrl}/${clusterId}/schema/${subject}`;
return `${apiUrl}/${clusterId}/schema/${encodeURIComponent(subject)}`;
};

export const uriPreferredSchemaForTopic = (clusterId, topicId) => {
return `${apiUrl}/${clusterId}/schema/topic/${topicId}`;
};

export const uriDeleteSchemaVersion = (clusterId, subject, version) => {
return `${apiUrl}/${clusterId}/schema/${subject}/version/${version}`;
return `${apiUrl}/${clusterId}/schema/${encodeURIComponent(subject)}/version/${version}`;
};

export const uriLatestSchemaVersion = (clusterId, subject) => {
return `${apiUrl}/${clusterId}/schema/${subject}`;
return `${apiUrl}/${clusterId}/schema/${encodeURIComponent(subject)}`;
};

export const uriUpdateSchema = (clusterId, subject) => {
return `${apiUrl}/${clusterId}/schema/${subject}`;
return `${apiUrl}/${clusterId}/schema/${encodeURIComponent(subject)}`;
};

export const uriSchemaCreate = clusterId => {
Expand Down
33 changes: 23 additions & 10 deletions src/main/java/org/akhq/controllers/SchemaController.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
import org.codehaus.httpcache4j.uri.URIBuilder;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
Expand All @@ -28,6 +31,14 @@
public class SchemaController extends AbstractController {
private final SchemaRegistryRepository schemaRepository;

private String decode(String value) {
try {
return URLDecoder.decode(value, StandardCharsets.UTF_8.toString());
} catch (UnsupportedEncodingException ex) {
throw new IllegalArgumentException(ex);
}
}

@Value("${akhq.pagination.page-size}")
private Integer pageSize;

Expand Down Expand Up @@ -87,19 +98,20 @@ public Schema create(
@Get("api/{cluster}/schema/{subject}")
@Operation(tags = {"schema registry"}, summary = "Retrieve a schema")
public Schema home(HttpRequest<?> request, String cluster, String subject) throws IOException, RestClientException {
return this.schemaRepository.getLatestVersion(cluster, subject);
return this.schemaRepository.getLatestVersion(cluster, decode(subject));
}

@Secured(Role.ROLE_REGISTRY_UPDATE)
@Post(value = "api/{cluster}/schema/{subject}")
@Operation(tags = {"schema registry"}, summary = "Update a schema")
public Schema updateSchema(String cluster, String subject, @Body Schema schema) throws Throwable {
if (!this.schemaRepository.exist(cluster, subject)) {
throw new IllegalArgumentException("Subject '" + subject + "' doesn't exits");
final String decodedSubject = decode(subject);
if (!this.schemaRepository.exist(cluster, decodedSubject)) {
throw new IllegalArgumentException("Subject '" + decodedSubject + "' doesn't exits");
}

if (!subject.equals(schema.getSubject())) {
throw new IllegalArgumentException("Invalid subject name '" + subject + "', doesn't egals '" + schema.getSubject() + "'");
if (!decodedSubject.equals(schema.getSubject())) {
throw new IllegalArgumentException("Invalid subject name '" + decodedSubject + "', doesn't egals '" + schema.getSubject() + "'");
}

return registerSchema(cluster, schema);
Expand Down Expand Up @@ -136,18 +148,19 @@ public Schema redirectId(
@Get("api/{cluster}/schema/{subject}/version")
@Operation(tags = {"schema registry"}, summary = "List all version for a schema")
public List<Schema> versions(HttpRequest<?> request, String cluster, String subject) throws IOException, RestClientException {
return this.schemaRepository.getAllVersions(cluster, subject);
return this.schemaRepository.getAllVersions(cluster, decode(subject));
}

@Secured(Role.ROLE_REGISTRY_DELETE)
@Delete("api/{cluster}/schema/{subject}")
@Operation(tags = {"schema registry"}, summary = "Delete a schema")
public HttpResponse<?> delete(String cluster, String subject) throws IOException, RestClientException {
if (!this.schemaRepository.exist(cluster, subject)) {
throw new IllegalArgumentException("Subject '" + subject + "' doesn't exits");
final String decodedSubject = decode(subject);
if (!this.schemaRepository.exist(cluster, decodedSubject)) {
throw new IllegalArgumentException("Subject '" + decodedSubject + "' doesn't exits");
}

this.schemaRepository.delete(cluster, subject);
this.schemaRepository.delete(cluster, decodedSubject);

return HttpResponse.noContent();
}
Expand All @@ -160,7 +173,7 @@ public HttpResponse<?> deleteVersion(
String subject,
Integer version
) throws IOException, RestClientException {
this.schemaRepository.deleteVersion(cluster, subject, version);
this.schemaRepository.deleteVersion(cluster, decode(subject), version);

return HttpResponse.noContent();
}
Expand Down

0 comments on commit cd6cf2d

Please sign in to comment.