Skip to content

Commit 07764dc

Browse files
authored
Merge pull request #47 from ccremer/angular-http
Implement client with Angular's HttpClient
2 parents 08816d6 + 1c46ff0 commit 07764dc

17 files changed

+210
-53
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/.angular
22
/dist
3+
/build
34
/node_modules
45
/playwright-report

packages/kubernetes-client-angular/projects/kubernetes-client-angular/README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,22 @@ import { NgModule } from '@angular/core'
4040
import { BrowserModule } from '@angular/platform-browser'
4141

4242
import { DefaultDataServiceFactory, EntityDataModule } from '@ngrx/data'
43-
import { HttpClientModule } from '@angular/common/http'
43+
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'
4444
import {
4545
DefaultEntityMetadataMap,
46+
KubernetesAuthorizerInterceptor,
4647
KubernetesDataServiceFactory,
4748
KubernetesDataServiceFactoryConfig,
4849
} from '@ccremer/kubernetes-client-angular'
4950
import { StoreModule } from '@ngrx/store'
5051
import { EffectsModule } from '@ngrx/effects'
52+
import { AppComponent } from './app.component'
5153

5254
@NgModule({
53-
declarations: [],
55+
declarations: [AppComponent],
5456
imports: [
5557
BrowserModule,
56-
HttpClientModule, // required by @ngrx/data
58+
HttpClientModule,
5759
StoreModule.forRoot(),
5860
EffectsModule.forRoot(),
5961
EntityDataModule.forRoot({
@@ -62,11 +64,13 @@ import { EffectsModule } from '@ngrx/effects'
6264
],
6365
providers: [
6466
{ provide: DefaultDataServiceFactory, useClass: KubernetesDataServiceFactory },
67+
{ provide: HTTP_INTERCEPTORS, useClass: KubernetesAuthorizerInterceptor, multi: true },
6568
{
6669
provide: KubernetesDataServiceFactoryConfig,
6770
useValue: {
6871
default: {
6972
usePatchInUpsert: true,
73+
usePatchInUpdate: false,
7074
},
7175
} satisfies KubernetesDataServiceFactoryConfig,
7276
},

packages/kubernetes-client-angular/projects/kubernetes-client-angular/examples/app.module.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,22 @@ import { NgModule } from '@angular/core'
22
import { BrowserModule } from '@angular/platform-browser'
33

44
import { DefaultDataServiceFactory, EntityDataModule } from '@ngrx/data'
5-
import { HttpClientModule } from '@angular/common/http'
5+
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http'
66
import {
77
DefaultEntityMetadataMap,
8+
KubernetesAuthorizerInterceptor,
89
KubernetesDataServiceFactory,
910
KubernetesDataServiceFactoryConfig,
1011
} from '@ccremer/kubernetes-client-angular'
1112
import { StoreModule } from '@ngrx/store'
1213
import { EffectsModule } from '@ngrx/effects'
14+
import { AppComponent } from './app.component'
1315

1416
@NgModule({
15-
declarations: [],
17+
declarations: [AppComponent],
1618
imports: [
1719
BrowserModule,
18-
HttpClientModule, // required by @ngrx/data
20+
HttpClientModule,
1921
StoreModule.forRoot(),
2022
EffectsModule.forRoot(),
2123
EntityDataModule.forRoot({
@@ -24,11 +26,13 @@ import { EffectsModule } from '@ngrx/effects'
2426
],
2527
providers: [
2628
{ provide: DefaultDataServiceFactory, useClass: KubernetesDataServiceFactory },
29+
{ provide: HTTP_INTERCEPTORS, useClass: KubernetesAuthorizerInterceptor, multi: true },
2730
{
2831
provide: KubernetesDataServiceFactoryConfig,
2932
useValue: {
3033
default: {
3134
usePatchInUpsert: true,
35+
usePatchInUpdate: false,
3236
},
3337
} satisfies KubernetesDataServiceFactoryConfig,
3438
},

packages/kubernetes-client-angular/projects/kubernetes-client-angular/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"type": "git",
1313
"url": "https://github.com/ccremer/kubernetes-client-browser"
1414
},
15+
"license": "Apache-2.0",
1516
"keywords": [
1617
"angular",
1718
"kubernetes",

packages/kubernetes-client-angular/projects/kubernetes-client-angular/src/lib/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ export abstract class DataServiceConfig {
66
* If true, the client will use the `patch` verb instead of `update` when doing an `upsert` call.
77
*/
88
usePatchInUpsert?: boolean
9+
/**
10+
* If true, the client will use the `patch` verb instead of `update` when doing an `update` call.
11+
*/
12+
usePatchInUpdate?: boolean
913
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Injectable, Optional } from '@angular/core'
2+
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'
3+
import { Observable } from 'rxjs'
4+
import { KubernetesAuthorizerService } from './kubernetes-authorizer.service'
5+
import { KubernetesDataServiceFactoryConfig } from './kubernetes-data-service-factory.service'
6+
7+
@Injectable()
8+
export class KubernetesAuthorizerInterceptor implements HttpInterceptor {
9+
constructor(
10+
private authorizer: KubernetesAuthorizerService,
11+
@Optional() private config?: KubernetesDataServiceFactoryConfig
12+
) {}
13+
14+
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
15+
const url = request.url
16+
const base = this.config?.basePath ?? ''
17+
console.log('url', url, 'token', this.authorizer.getToken())
18+
if (url.startsWith(`${base}/api/`) || url.startsWith(`${base}/apis/`)) {
19+
return next.handle(
20+
request.clone({
21+
setHeaders: { Authorization: `Bearer ${this.authorizer.getToken()}` },
22+
})
23+
)
24+
}
25+
return next.handle(request)
26+
}
27+
}
Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
11
import { Injectable } from '@angular/core'
2-
import { Authorizer, DefaultAuthorizer, NoopAuthorizer } from '@ccremer/kubernetes-client/fetch'
3-
import { Config } from '@ccremer/kubernetes-client/api'
42

5-
@Injectable({
6-
providedIn: 'root',
7-
})
8-
export class KubernetesAuthorizerService implements Authorizer {
9-
private wrapped: Authorizer = new NoopAuthorizer()
3+
@Injectable({ providedIn: 'root' })
4+
export class KubernetesAuthorizerService {
5+
private token = ''
106

11-
applyAuthorization(init: RequestInit): RequestInit {
12-
return this.wrapped.applyAuthorization(init)
7+
getToken(): string {
8+
return this.token
139
}
1410

15-
setToken(token: string, server = ''): void {
16-
this.wrapped = new DefaultAuthorizer(Config.FromToken(token, server))
17-
}
18-
19-
setAuthorizer(authorizer: Authorizer): void {
20-
this.wrapped = authorizer
11+
setToken(token: string): void {
12+
this.token = token
2113
}
2214
}

packages/kubernetes-client-angular/projects/kubernetes-client-angular/src/lib/kubernetes-data-service-factory.service.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,24 @@ import { Injectable, Optional } from '@angular/core'
22
import { KubeObject } from '@ccremer/kubernetes-client/types/core'
33
import { EntityCollectionDataService } from '@ngrx/data'
44
import { KubernetesDataService } from './kubernetes-data.service'
5-
import { Client, KubeClientBuilder } from '@ccremer/kubernetes-client/fetch'
6-
import { KubernetesAuthorizerService } from './kubernetes-authorizer.service'
75
import { KubernetesUrlGeneratorService } from './kubernetes-url-generator.service'
86
import { DataServiceConfig } from './config'
7+
import { HttpClient } from '@angular/common/http'
98

109
/**
1110
* Factory to create {@link EntityCollectionDataService} for Kubernetes resources.
1211
*/
1312
@Injectable()
1413
export class KubernetesDataServiceFactory {
15-
private readonly client: Client
16-
1714
constructor(
18-
private authorizer: KubernetesAuthorizerService,
1915
private urlGenerator: KubernetesUrlGeneratorService,
16+
private httpClient: HttpClient,
2017
@Optional() private config?: KubernetesDataServiceFactoryConfig
21-
) {
22-
this.client = new KubeClientBuilder().WithAuthorizer(this.authorizer).WithUrlGenerator(this.urlGenerator).Build()
23-
}
18+
) {}
2419

2520
create<T extends KubeObject>(entityName: string): EntityCollectionDataService<T> {
2621
const overrideConfig = this.config?.overrides ? this.config.overrides[entityName] : this.config?.default
27-
return new KubernetesDataService<T>(entityName, this.client, overrideConfig)
22+
return new KubernetesDataService<T>(entityName, this.httpClient, this.urlGenerator, overrideConfig)
2823
}
2924
}
3025

@@ -50,3 +45,21 @@ export abstract class KubernetesDataServiceFactoryConfig {
5045
[key: string]: DataServiceConfig
5146
}
5247
}
48+
49+
/**
50+
* Gets the {@link DataServiceConfig} for the given entity, with the default config as fallback.
51+
* @param config the config instance
52+
* @param entityName the entity name
53+
* @return the config in `overrides`, fallback to `default` or undefined if no default is set either.
54+
*/
55+
export function getDataServiceConfigOrDefault(
56+
entityName: string,
57+
config?: KubernetesDataServiceFactoryConfig
58+
): DataServiceConfig | undefined {
59+
if (!config) return undefined
60+
if (config.overrides) {
61+
const override = config.overrides[entityName]
62+
return override ? override : config.default
63+
}
64+
return config.default
65+
}

0 commit comments

Comments
 (0)