Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/allow runtime configuration #2

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
5 changes: 5 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"production": true,
"apiBaseUrl": "https://jenkins-master-deephealth-unix01.ing.unimore.it/backend",
"clientId": "BnEOyrMrJ9qeMHeZO7lzF7kgpIFBLm2ZtBd8achT"
}
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ services:
restart: unless-stopped
environment:
- JAVA_OPTS="-Xmx4548m -Xss512k"
volumes:
- ./config.json:/usr/src/app/src/assets/config.json
144 changes: 80 additions & 64 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,52 +1,64 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DeepHealthComponent } from './components/deep-health/deep-health.component';
import { AppTabsComponent } from './components/app-tabs/app-tabs.component';
import { PowerUserComponent } from './components/power-user/power-user.component';
import { HttpClientModule, HTTP_INTERCEPTORS} from '@angular/common/http';
import { AppMaterialModule } from './app-material/app-material.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ProjectComponent } from './components/project/project.component';
import { ConfirmDialogComponent } from './components/confirm-dialog/confirm-dialog.component';
import { FormsModule } from '@angular/forms';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { TranslateService } from '@ngx-translate/core';
import { ConfirmDialogTrainComponent } from './components/confirm-dialog-train/confirm-dialog-train.component';
import { CreateProjectDialogComponent } from './components/create-project-dialog/create-project-dialog.component';
import { UploadDatasetsDialogComponent } from './components/upload-datasets-dialog/upload-datasets-dialog.component';
import { UpdateWeightDialogComponent } from './components/update-weight-dialog/update-weight-dialog.component';
import { ShowOutputDetailsDialogComponent } from './components/show-output-details-dialog/show-output-details-dialog.component';
import { InterceptorService } from './services/interceptor.service';
import { AuthService } from './services/auth.service';
import { OAuthModule } from 'angular-oauth2-oidc';
import { RegisterUserComponent } from './components/register-user/register-user.component';
import { LoginUserComponent } from './components/login-user/login-user.component';
import { ShowProfileDetailsDialogComponent } from './components/show-profile-details-dialog/show-profile-details-dialog.component';
import { AuthGuard } from './auth.guard';
import { ResetPasswordComponent } from './components/reset-password/reset-password.component';
import { FilterPipe } from './components/pipes/filter.pipe';
import { DeleteDialogComponent } from './components/delete-dialog/delete-dialog.component';
import { ProgressSpinnerDialogComponent } from './components/progress-spinner-dialog/progress-spinner-dialog.component';
import { ProcessFilterPipe } from './components/pipes/process-filter.pipe';
import { DropdownComponent } from './components/dynamic-components/dropdown/dropdown.component';
import { InputIntegerComponent } from './components/dynamic-components/input-integer/input-integer.component';
import { InputFloatComponent } from './components/dynamic-components/input-float/input-float.component';
import { InputTextComponent } from './components/dynamic-components/input-text/input-text.component';
import { BooleanComponent } from './components/dynamic-components/boolean/boolean.component';
import { HTTP_INTERCEPTORS, HttpClientModule } from "@angular/common/http";
import { RouterModule, Routes } from "@angular/router";
import { TranslateLoader, TranslateModule } from "@ngx-translate/core";

import { AppConfigService } from "./services/config.service";
import { AppMaterialModule } from "./app-material/app-material.module";
import { AppTabsComponent } from "./components/app-tabs/app-tabs.component";
import { AuthGuard } from "./auth.guard";
import { AuthService } from "./services/auth.service";
import { BooleanComponent } from "./components/dynamic-components/boolean/boolean.component";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { ConfirmDialogComponent } from "./components/confirm-dialog/confirm-dialog.component";
import { ConfirmDialogTrainComponent } from "./components/confirm-dialog-train/confirm-dialog-train.component";
import { CreateProjectDialogComponent } from "./components/create-project-dialog/create-project-dialog.component";
import { DeepHealthComponent } from "./components/deep-health/deep-health.component";
import { DeleteDialogComponent } from "./components/delete-dialog/delete-dialog.component";
import { DropdownComponent } from "./components/dynamic-components/dropdown/dropdown.component";
import { FilterPipe } from "./components/pipes/filter.pipe";
import { FormsModule } from "@angular/forms";
import { HttpClient } from "@angular/common/http";
import { InputFloatComponent } from "./components/dynamic-components/input-float/input-float.component";
import { InputIntegerComponent } from "./components/dynamic-components/input-integer/input-integer.component";
import { InputTextComponent } from "./components/dynamic-components/input-text/input-text.component";
import { InterceptorService } from "./services/interceptor.service";
import { LoginUserComponent } from "./components/login-user/login-user.component";
import { NgModule } from "@angular/core";
import { OAuthModule } from "angular-oauth2-oidc";
import { PowerUserComponent } from "./components/power-user/power-user.component";
import { ProcessFilterPipe } from "./components/pipes/process-filter.pipe";
import { ProgressSpinnerDialogComponent } from "./components/progress-spinner-dialog/progress-spinner-dialog.component";
import { ProjectComponent } from "./components/project/project.component";
import { ReactiveFormsModule } from "@angular/forms";
import { RegisterUserComponent } from "./components/register-user/register-user.component";
import { ResetPasswordComponent } from "./components/reset-password/reset-password.component";
import { ShowOutputDetailsDialogComponent } from "./components/show-output-details-dialog/show-output-details-dialog.component";
import { ShowProfileDetailsDialogComponent } from "./components/show-profile-details-dialog/show-profile-details-dialog.component";
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
import { TranslateService } from "@ngx-translate/core";
import { UpdateWeightDialogComponent } from "./components/update-weight-dialog/update-weight-dialog.component";
import { UploadDatasetsDialogComponent } from "./components/upload-datasets-dialog/upload-datasets-dialog.component";

export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
return new TranslateHttpLoader(http, "./assets/i18n/", ".json");
}

export function initConfig(appConfig: AppConfigService) {
return (): Promise<any> => {
return appConfig.loadConfig();
};
}

const routes: Routes = [
{ path: '', component: LoginUserComponent },
{ path: 'power-user', component: PowerUserComponent, canActivate: [AuthGuard] },
{ path: 'project', component: ProjectComponent, canActivate: [AuthGuard] },
{ path: 'register', component: RegisterUserComponent },
{ path: 'reset-password', component: ResetPasswordComponent }
{ path: "", component: LoginUserComponent },
{
path: "power-user",
component: PowerUserComponent,
canActivate: [AuthGuard],
},
{ path: "project", component: ProjectComponent, canActivate: [AuthGuard] },
{ path: "register", component: RegisterUserComponent },
{ path: "reset-password", component: ResetPasswordComponent },
];

@NgModule({
Expand All @@ -73,7 +85,7 @@ const routes: Routes = [
InputTextComponent,
InputIntegerComponent,
InputFloatComponent,
BooleanComponent
BooleanComponent,
],
imports: [
RouterModule.forRoot(routes),
Expand All @@ -86,18 +98,19 @@ const routes: Routes = [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [HttpClient]
}
useFactory: createTranslateLoader,
deps: [HttpClient],
},
}),
OAuthModule.forRoot()
OAuthModule.forRoot(),
],
exports: [RouterModule,
exports: [
RouterModule,
AppMaterialModule,
HttpClientModule,
FormsModule,
ReactiveFormsModule,
TranslateModule
TranslateModule,
],
entryComponents: [
ConfirmDialogComponent,
Expand All @@ -109,23 +122,26 @@ const routes: Routes = [
ShowProfileDetailsDialogComponent,
DeleteDialogComponent,
ProgressSpinnerDialogComponent,
DropdownComponent,
InputIntegerComponent,
InputFloatComponent,
DropdownComponent,
InputIntegerComponent,
InputFloatComponent,
InputTextComponent,
BooleanComponent
BooleanComponent,
],
providers: [AuthService, AuthGuard,
providers: [
AppConfigService,
AuthService,
AuthGuard,
{
provide: HTTP_INTERCEPTORS,
useClass: InterceptorService,
multi: true
}
]
provide: HTTP_INTERCEPTORS,
useClass: InterceptorService,
multi: true,
},
],
})
export class AppRoutingModule {
constructor(public translate: TranslateService) {
translate.setDefaultLang('en');
translate.use('en');
translate.setDefaultLang("en");
translate.use("en");
}
}
}
47 changes: 27 additions & 20 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { APP_INITIALIZER, NgModule } from "@angular/core";

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HeaderComponent } from './components/header/header.component';
import { FooterComponent } from './components/footer/footer.component';
import { AppComponent } from "./app.component";
import { AppConfigService } from "./services/config.service";
import { AppRoutingModule } from "./app-routing.module";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { BrowserModule } from "@angular/platform-browser";
import { FooterComponent } from "./components/footer/footer.component";
import { HeaderComponent } from "./components/header/header.component";

export function initConfigService(appConfig: AppConfigService) {
return (): Promise<any> => {
return appConfig.loadConfig();
};
}

@NgModule({
declarations: [
AppComponent,
HeaderComponent,
FooterComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule
declarations: [AppComponent, HeaderComponent, FooterComponent],
imports: [BrowserModule, AppRoutingModule, BrowserAnimationsModule],

providers: [
AppConfigService,
{
provide: APP_INITIALIZER,
useFactory: initConfigService,
deps: [AppConfigService],
multi: true,
},
],

providers: [],
bootstrap: [AppComponent]
bootstrap: [AppComponent],
})
export class AppModule { }
export class AppModule {}
16 changes: 7 additions & 9 deletions src/app/auth.guard.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './services/auth.service';
import { CanActivate, Router } from "@angular/router";

import { AuthService } from "./services/auth.service";
import { Injectable } from "@angular/core";

@Injectable({
providedIn: 'root'
providedIn: "root",
})
export class AuthGuard implements CanActivate {
constructor(private _authService: AuthService, private _router: Router) {

}
constructor(private _authService: AuthService, private _router: Router) {}

canActivate(): boolean {
if (this._authService.getAuthorizationToken()) {
return true;
} else {
this._router.navigate(['']);
this._router.navigate([""]);
return false;
}
}

}
27 changes: 18 additions & 9 deletions src/app/services/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpResponse, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment.prod';
import { HttpClient, HttpHeaders, HttpResponse } from "@angular/common/http";

import { AppConfigService } from "../services/config.service";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";

@Injectable()
export class AuthService {
apiUrl = environment.apiBaseUrl;
clientID = environment.clientId;
constructor(
private httpClient: HttpClient,
private config: AppConfigService
) {}

get apiUrl() {
return this.config.getConfig()["apiBaseUrl"];
}

constructor(private httpClient: HttpClient) { }
get clientID() {
return this.config.getConfig()["clientId"];
}

public getAuthorizationToken(): string {
return localStorage.getItem('accessToken');
return localStorage.getItem("accessToken");
}

public getRefreshToken(): string {
return localStorage.getItem('refreshToken');
return localStorage.getItem("refreshToken");
}

refreshToken(): Observable<HttpResponse<any>> {
Expand Down
11 changes: 11 additions & 0 deletions src/app/services/config.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { AppConfigService } from './config.service';
import { TestBed } from '@angular/core/testing';

describe('AppConfigService', () => {
beforeEach(() => TestBed.configureTestingModule({}));

it('should be created', () => {
const service: AppConfigService = TestBed.get(AppConfigService);
expect(service).toBeTruthy();
});
});
32 changes: 32 additions & 0 deletions src/app/services/config.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { environment } from "../../environments/environment";

@Injectable({
providedIn: "root",
})
export class AppConfigService {
private config: any = { ...environment };
constructor(private http: HttpClient) {}

public async loadConfig() {
if ("configFile" in environment) {
const data = await this.http
.get(environment["configFile"])
.toPromise()
.then((config) => {
this.config = Object.assign({}, environment, config);
console.debug(
"Configuration updated from " + environment["configFile"]
);
})
.catch((reason) => {
console.warn("Unable to load configuration from server", reason);
});
}
}

public getConfig() {
return this.config;
}
}
16 changes: 12 additions & 4 deletions src/app/services/data.service.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import { HttpClient, HttpResponse } from '@angular/common/http';

import { AppConfigService } from './config.service';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient, HttpResponse } from '@angular/common/http';
import { environment } from '../../environments/environment.prod';
import { Weight } from '../components/power-user/power-user.component';

@Injectable({
providedIn: 'root'
})

export class DataService {
apiUrl = environment.apiBaseUrl;

constructor(private httpClient: HttpClient) { }
constructor(
private httpClient: HttpClient,
private config: AppConfigService
) {}

get apiUrl() {
return this.config.getConfig()["apiBaseUrl"];
}


allowedProperties(modelId, propertyId, datasetId): Observable<HttpResponse<any>> {
let url = this.apiUrl.concat("/allowedProperties?model_id=");
Expand Down
Loading