Skip to content

Commit

Permalink
Merge pull request #356 from Consdata/IKC-384-custom-base-href
Browse files Browse the repository at this point in the history
IKC-384 Custom context path
  • Loading branch information
pbelke authored May 24, 2024
2 parents 4b52d43 + 46cfd34 commit f606c39
Show file tree
Hide file tree
Showing 23 changed files with 64 additions and 54 deletions.
11 changes: 7 additions & 4 deletions docs/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,15 @@ If you run Kafka in terminal (not using docker) you can:
Kouncil will be available via: http://localhost:8080/login


If you run Kafka using docker container you have to put both containers in the same network so they can reach out to each other. Firstly create new network using docker network create --driver bridge <network_name>. And than use this network name in run command/docker compose files:
For example for Kouncil docker run command will look like this
If you run Kafka using docker container you have to put both containers in the same network, so they can reach out to each other. Firstly create new network using
```bash
docker network create --driver bridge <network_name>
```
Then use this network name in run command/docker compose files, for example Kouncil docker run command will look like this:
```bash
docker run -p 80:8080 -e bootstrapServers="<container_name>:9092" --network="kouncil" -e kouncil.auth.active-provider="inmemory" consdata/kouncil:latest
docker run -p 80:8080 -e bootstrapServers="<container_name>:9092" --network="<network_name>" -e kouncil.auth.active-provider="inmemory" consdata/kouncil:latest
```
Also you should use Kafka docker container name as IP address (see <container_name>)
Also, you should use Kafka docker container name as IP address (see <container_name>)

## I logged in and I see only brokers and consumer groups.

Expand Down
2 changes: 1 addition & 1 deletion docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* [JMX](configuration/JMX.md)
* [Logging](configuration/LOGGING.md)
* [Websocket](configuration/WEBSOCKET.md)
* [Custom base path](configuration/CUSTOM_BASE_PATH.md)
* [Custom context path](configuration/CUSTOM_CONTEXT_PATH.md)


* [Features](FEATURES.md)
Expand Down
8 changes: 0 additions & 8 deletions docs/configuration/CUSTOM_BASE_PATH.md

This file was deleted.

8 changes: 8 additions & 0 deletions docs/configuration/CUSTOM_CONTEXT_PATH.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Custom context path

If you want to expose Kouncil in custom context path you need to set Spring's `kouncil.context-path` parameter.
In docker run command it will look like this
```bash
docker run -d -p 80:8080 -e bootstrapServers="kafka1:9092" -e kouncil.context-path="/console" consdata/kouncil:latest
```
After that, visit [http://localhost/console](http://localhost/console) in your browser, and you should be greeted by a login screen.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class KouncilConfigurationController {

private final KouncilConfiguration kouncilConfiguration;

@Value("${server.servlet.context-path:}")
@Value("${kouncil.context-path:}")
private String contextPath;

@RolesAllowed({ADMIN_ROLE, EDITOR_ROLE, VIEWER_ROLE})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
})
.and()
.authorizeRequests()
.antMatchers("/api/info/version", "/api/login", "/api/activeProvider", "/*", "/assets/**").permitAll()
.antMatchers("/api/info/version", "/api/login", "/api/activeProvider", "/api/context-path", "/*", "/assets/**").permitAll()
.anyRequest().authenticated();
return http.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
})
.and()
.authorizeRequests()
.antMatchers("/api/info/version", "/api/firstTimeLogin", "/api/login", "/api/activeProvider", "/*", "/assets/**").permitAll()
.antMatchers("/api/info/version", "/api/firstTimeLogin", "/api/login", "/api/activeProvider", "/api/context-path","/*", "/assets/**")
.permitAll()
.anyRequest().authenticated();
return http.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
})
.and()
.authorizeRequests()
.antMatchers("/api/info/version", "/api/login", "/api/activeProvider", "/*", "/assets/**").permitAll()
.antMatchers("/api/info/version", "/api/login", "/api/activeProvider", "/api/context-path", "/*", "/assets/**").permitAll()
.anyRequest().authenticated();
return http.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ export class BrokerBackendService implements BrokerService {

getBrokerConfig$(serverId: string, id: string): Observable<BrokerConfig[]> {
const params = new HttpParams().set('serverId', serverId);
return this.http.get<BrokerConfig[]>(`./api/configs/${id}`, {params});
return this.http.get<BrokerConfig[]>(`/api/configs/${id}`, {params});
}

getBrokers$(serverId: string): Observable<Brokers> {
const params = new HttpParams().set('serverId', serverId);
return this.http.get<Brokers>(`./api/brokers`, {params});
return this.http.get<Brokers>(`/api/brokers`, {params});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ export class ConsumerGroupBackendService implements ConsumerGroupService {

getConsumerGroup$(serverId: string, groupId: string): Observable<ConsumerGroupResponse> {
const params = new HttpParams().set('serverId', serverId);
return this.http.get<ConsumerGroupResponse>(`./api/consumer-group/${groupId}`, {params});
return this.http.get<ConsumerGroupResponse>(`/api/consumer-group/${groupId}`, {params});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ export class ConsumerGroupsBackendService implements ConsumerGroupsService {
): Observable<Record<string, unknown>> {
const params = new HttpParams().set('serverId', serverId);
return this.http.delete<Record<string, unknown>>(
`./api/consumer-group/${value}`,
`/api/consumer-group/${value}`,
{ params }
);
}

getConsumerGroups$(serverId: string): Observable<ConsumerGroupsResponse> {
const params = new HttpParams().set('serverId', serverId);
return this.http.get<ConsumerGroupsResponse>(`./api/consumer-groups`, {
return this.http.get<ConsumerGroupsResponse>(`/api/consumer-groups`, {
params,
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export class NavbarComponent implements OnInit, AfterViewInit {
ngOnInit(): void {
switch (environment.backend) {
case Backend.SERVER: {
this.backendVersion$ = this.http.get(`./api/info/version`, {responseType: 'text'});
this.backendVersion$ = this.http.get(`/api/info/version`, {responseType: 'text'});
break;
}
case Backend.DEMO: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export class SurveyBackendService implements SurveyService {
}

fetchSurveyBasePath$(): Observable<boolean> {
return this.http.get('./api/survey/config', {responseType: 'text'}).pipe(map((basePath) => {
return this.http.get('/api/survey/config', {responseType: 'text'}).pipe(map((basePath) => {
this.surveyBasePath = basePath;
return this.surveyBasePath.length > 0;
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export class TopicBackendService implements TopicService {
getMessages(serverId: string, topicName: string, offset?: number): void {
let url;
if (typeof this.selectedPartition !== 'undefined') {
url = `./api/topic/messages/${topicName}/${this.selectedPartition}`;
url = `/api/topic/messages/${topicName}/${this.selectedPartition}`;
} else {
url = `./api/topic/messages/${topicName}/all`;
url = `/api/topic/messages/${topicName}/all`;
}
const paging = this.paginationChanged$.getValue();
let params = new HttpParams()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class TrackBackendService extends TrackService {
}

getEvents$(serverId: string, trackFilter: TrackFilter, asyncHandle?: string): Observable<MessageData[]> {
const url = this.asyncEnabled ? './api/track/async' : './api/track/sync';
const url = this.asyncEnabled ? '/api/track/async' : '/api/track/sync';
const params = new HttpParams()
.set('serverId', serverId)
.set('topicNames', trackFilter.topics.join(','))
Expand Down
2 changes: 1 addition & 1 deletion kouncil-frontend/apps/kouncil/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<title>Kouncil</title>
<base href="./">
<base href="/">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="assets/kouncil-favicon.png">
Expand Down
12 changes: 9 additions & 3 deletions kouncil-frontend/apps/kouncil/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@ import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

import {environment} from './environments/environment';
import {AppModule} from './app/app.module';
import {APP_BASE_HREF} from '@angular/common';

if (environment.production) {
enableProdMode();
}

platformBrowserDynamic()
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
fetch('/api/context-path')
.then(response => response.text())
.then(response => {
platformBrowserDynamic([{provide: APP_BASE_HREF, useValue: response}])
.bootstrapModule(AppModule)
.catch((err) => console.error(err));
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class AuthBackendService implements AuthService {
}

login$(user: User): Observable<boolean> {
return this.http.post<boolean>('./api/login', user).pipe(map(data => {
return this.http.post<boolean>('/api/login', user).pipe(map(data => {
this.setAuthenticated(data);
localStorage.setItem(this.IS_LOGGED_IN, data.toString());
this.generateUserId();
Expand All @@ -43,38 +43,38 @@ export class AuthBackendService implements AuthService {
}

logout$(): Observable<void> {
return this.http.get<void>('./api/logout').pipe(map(() => {
return this.http.get<void>('/api/logout').pipe(map(() => {
localStorage.removeItem(this.IS_LOGGED_IN);
this.setAuthenticated(false);
}));
}

sso$(provider: string): Observable<void> {
window.open(`${this.baseUrl}${this.contextPath}/oauth2/authorization/${provider}`, '_self');
window.open(`${this.baseUrl}/oauth2/authorization/${provider}`, '_self');
localStorage.setItem('selectedProvider', provider);
return of(undefined);
}

fetchToken$(code: string, state: string, provider: string): Observable<void> {
return this.http.get<void>(`./login/oauth2/code/${provider}?code=${code}&state=${state}`).pipe(map(() => {
return this.http.get<void>(`/login/oauth2/code/${provider}?code=${code}&state=${state}`).pipe(map(() => {
this.setAuthenticated(true);
localStorage.setItem(this.IS_LOGGED_IN, 'true');
localStorage.removeItem('selectedProvider');
}));
}

changeDefaultPassword$(newPassword: string): Observable<void> {
return this.http.post<void>('./api/changeDefaultPassword', newPassword);
return this.http.post<void>('/api/changeDefaultPassword', newPassword);
}

firstTimeLogin$(username: string): Observable<boolean> {
return this.http.get<boolean>(`./api/firstTimeLogin/${username}`).pipe(map(isFirstTime => {
return this.http.get<boolean>(`/api/firstTimeLogin/${username}`).pipe(map(isFirstTime => {
return isFirstTime;
}));
}

skipChange$(): Observable<void> {
return this.http.get<void>('./api/skipChangeDefaultPassword');
return this.http.get<void>('/api/skipChangeDefaultPassword');
}

clearLoggedIn(): void {
Expand All @@ -83,19 +83,19 @@ export class AuthBackendService implements AuthService {
}

ssoProviders$(): Observable<Array<string>> {
return this.http.get<Array<string>>('./api/ssoproviders').pipe(map((providers) => {
return this.http.get<Array<string>>('/api/ssoproviders').pipe(map((providers) => {
return providers;
}));
}

activeProvider$(): Observable<string> {
return this.http.get('./api/activeProvider', {responseType: 'text'}).pipe(map((providers) => {
return this.http.get('/api/activeProvider', {responseType: 'text'}).pipe(map((providers) => {
return providers;
}));
}

getUserRoles$(): Observable<void> {
return this.http.get<Array<KouncilRole>>('./api/userRoles').pipe(map((userRoles) => {
return this.http.get<Array<KouncilRole>>('/api/userRoles').pipe(map((userRoles) => {
this.userRoles = userRoles;
localStorage.setItem(this.USER_ROLES, JSON.stringify(this.userRoles));
}));
Expand All @@ -116,13 +116,13 @@ export class AuthBackendService implements AuthService {
}

getInstallationId$(): void {
this.http.get('./api/installationId', {responseType: 'text'}).subscribe((installationId) => {
this.http.get('/api/installationId', {responseType: 'text'}).subscribe((installationId) => {
localStorage.setItem('installationId', installationId);
});
}

fetchContextPath$(): void {
this.http.get('./api/context-path', {responseType: 'text'}).subscribe((contextPath) => {
this.http.get('/api/context-path', {responseType: 'text'}).subscribe((contextPath) => {
this.contextPath = contextPath;
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class ServersBackendService extends ServersService {

load(): Promise<boolean> {
return new Promise((resolve) => {
this.http.get(`./api/connection`).subscribe((value) => {
this.http.get(`/api/connection`).subscribe((value) => {
if (value != null) {
const lastSelectedServer = localStorage.getItem('lastSelectedServer');
for (const key in value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class SendBackendService implements SendService {
send$(serverId: string, count: number, messageData: MessageData): Observable<Record<string, unknown>> {
const params = new HttpParams().set('serverId', serverId);
return this.http.post<Record<string, unknown>>(
`./api/topic/send/${messageData.topicName}/${count}`,
`/api/topic/send/${messageData.topicName}/${count}`,
messageData,
{params}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class TopicsBackendService implements TopicsService {

getTopics$(serverId: string): Observable<Topics> {
const params = new HttpParams().set('serverId', serverId);
return this.http.get<Topics>(`./api/topics`, {params});
return this.http.get<Topics>(`/api/topics`, {params});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class ResendBackendService {
resend$(serverId: string, resendDataModel: ResendDataModel): Observable<Record<string, unknown>> {
const params = new HttpParams().set('serverId', serverId);
return this.http.post<Record<string, unknown>>(
`./api/topic/resend`,
`/api/topic/resend`,
resendDataModel,
{ params }
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,35 @@ export class SchemaRegistryBackendService implements SchemaRegistryService {
}

getSchemasConfiguration$(): Observable<SchemasConfiguration[]> {
return this.httpClient.get<SchemasConfiguration[]>(`./api/schemas/configs`);
return this.httpClient.get<SchemasConfiguration[]>(`/api/schemas/configs`);
}

getLatestSchemas$(serverId: string, topicName: string): Observable<Schemas> {
const params = new HttpParams().set('serverId', serverId);
return this.httpClient.get<Schemas>(`./api/schemas/latest/${topicName}`, {params});
return this.httpClient.get<Schemas>(`/api/schemas/latest/${topicName}`, {params});
}

loadAllSchemasForServer$(selectedServerId: string, topics: string[]): Observable<Schema[]> {
const params = new HttpParams()
.set('topicNames', topics.join(','));

return this.httpClient.get<Schema[]>(`./api/schemas/${selectedServerId}`, {params});
return this.httpClient.get<Schema[]>(`/api/schemas/${selectedServerId}`, {params});
}

deleteSchema$(selectedServerId: string, subject: string, version: string): Observable<void> {
return this.httpClient.delete<void>(`./api/schemas/${selectedServerId}/${subject}/${version}`);
return this.httpClient.delete<void>(`/api/schemas/${selectedServerId}/${subject}/${version}`);
}

getSchemaVersion$(selectedServerId: string, subjectName: string, version: number): Observable<Schema> {
return this.httpClient.get<Schema>(`./api/schemas/${selectedServerId}/${subjectName}/${version}`);
return this.httpClient.get<Schema>(`/api/schemas/${selectedServerId}/${subjectName}/${version}`);
}

addNewSchemaVersion$(model: Schema, selectedServerId: string): Observable<void> {
return this.httpClient.put<void>(`./api/schemas/${selectedServerId}`, model);
return this.httpClient.put<void>(`/api/schemas/${selectedServerId}`, model);
}

addNewSchema$(model: Schema, selectedServerId: string): Observable<void> {
return this.httpClient.post<void>(`./api/schemas/${selectedServerId}`, model);
return this.httpClient.post<void>(`/api/schemas/${selectedServerId}`, model);
}
}

0 comments on commit f606c39

Please sign in to comment.