From 8811c6d766192f7446378ea6dd2caee78d447207 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 14 Feb 2021 23:25:16 +0000 Subject: [PATCH 01/30] Remove unused code. --- front-end/src/app/components/simulation/simulation.component.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/front-end/src/app/components/simulation/simulation.component.ts b/front-end/src/app/components/simulation/simulation.component.ts index 6f25c29..76ee9b7 100644 --- a/front-end/src/app/components/simulation/simulation.component.ts +++ b/front-end/src/app/components/simulation/simulation.component.ts @@ -1,5 +1,4 @@ import {Component, OnInit} from '@angular/core'; -import {FactoryConfigAPIResource} from '../../models/factory-config.models'; import {SimulationAPIService} from '../../services/api/simulation/simulation-api.service'; @Component({ @@ -9,7 +8,6 @@ import {SimulationAPIService} from '../../services/api/simulation/simulation-api styleUrls: ['./simulation.component.scss'] }) export class SimulationComponent implements OnInit { - factoryConfigs: FactoryConfigAPIResource[]; constructor() { } From 0a1f5c743cbd8f44ca17e8579513ec993571d5b7 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 14 Feb 2021 23:25:29 +0000 Subject: [PATCH 02/30] Add sim detail view path. --- front-end/src/app/modules/app-routing.module.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/front-end/src/app/modules/app-routing.module.ts b/front-end/src/app/modules/app-routing.module.ts index 37f4b95..71bd8e1 100644 --- a/front-end/src/app/modules/app-routing.module.ts +++ b/front-end/src/app/modules/app-routing.module.ts @@ -11,6 +11,7 @@ import { SimulationListViewComponent } from '../components/simulation/simulation-list-view/simulation-list-view.component'; import {SimulationCreateViewComponent} from '../components/simulation/simulation-create-view/simulation-create-view.component'; +import {SimulationDetailViewComponent} from '../components/simulation/simulation-detail-view/simulation-detail-view.component'; const routes: Routes = [ @@ -31,6 +32,10 @@ const routes: Routes = [ path: '', component: SimulationListViewComponent }, + { + path: ':id', + component: SimulationDetailViewComponent + }, { path: paths.create, component: SimulationCreateViewComponent From 0d35f8341b1d29e5e7ab09668840ed0115a00651 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Mon, 15 Feb 2021 00:10:10 +0000 Subject: [PATCH 03/30] Started shaping simulation list -> detail view. --- .../simulation-detail-view.component.ts | 7 ++- .../simulation-list-view.component.html | 61 ++++++++++++------- .../simulation-list-view.component.scss | 7 +++ .../src/app/modules/app-routing.module.ts | 2 +- 4 files changed, 52 insertions(+), 25 deletions(-) diff --git a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts index f36da28..e08cc19 100644 --- a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts +++ b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts @@ -1,4 +1,5 @@ -import { Component, OnInit } from '@angular/core'; +import {Component, Input, OnInit} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; @Component({ selector: 'app-simulation-detail-view', @@ -7,7 +8,9 @@ import { Component, OnInit } from '@angular/core'; }) export class SimulationDetailViewComponent implements OnInit { - constructor() { } + constructor(private route: ActivatedRoute) { } + + @Input('simulation') ngOnInit(): void { } diff --git a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html index 362c8fe..fc24aba 100644 --- a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html +++ b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html @@ -1,26 +1,43 @@ +

Simulations

+
+
+ + + + Name: {{simulation.name}} + + + Description: {{simulation.description}} + + + analytics + + Some details of the run go here... + + + + + + + + + + + + + -
- -

Name: {{simulation.name}}

-

Description: {{simulation.description}}

- -
-

Factory configuration for experiment

-

Materials: {{factoryConfig.materials}}

-

Product code: {{factoryConfig.productCode}}

-

Empty code: {{factoryConfig.emptyCode}}

-

Pickup time: {{factoryConfig.pickupTime}}

-

Drop time: {{factoryConfig.dropTime}}

-

Build time: {{factoryConfig.buildTime}}

-

Number of conveyor belt slots: {{factoryConfig.numberOfConveyorBeltSlots}}

-

Number of worker pairs: {{factoryConfig.numberOfWorkerPairs}}

-

Number of simulation steps: {{factoryConfig.numberOfSimulationSteps}}

-
- -
-

Results of simulation

-

Efficiency: {{result.efficiency}}

+ + + + + + + + + +
- +
diff --git a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss index e69de29..291892a 100644 --- a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss +++ b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss @@ -0,0 +1,7 @@ +.simulation__list-container { + margin: 8px; +} + +.simulation__card-icon { + font-size: 4rem; +} diff --git a/front-end/src/app/modules/app-routing.module.ts b/front-end/src/app/modules/app-routing.module.ts index 71bd8e1..395b114 100644 --- a/front-end/src/app/modules/app-routing.module.ts +++ b/front-end/src/app/modules/app-routing.module.ts @@ -33,7 +33,7 @@ const routes: Routes = [ component: SimulationListViewComponent }, { - path: ':id', + path: 'detail/:id', component: SimulationDetailViewComponent }, { From 1c370032219751ecc40af8e21d3dfa8b5f5ef6ce Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Mon, 15 Feb 2021 00:17:33 +0000 Subject: [PATCH 04/30] styling --- .../simulation-list-view.component.html | 78 +++++++++---------- .../simulation-list-view.component.scss | 8 +- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html index fc24aba..4f44fa9 100644 --- a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html +++ b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html @@ -1,43 +1,43 @@
-

Simulations

-
-
- - - - Name: {{simulation.name}} - - - Description: {{simulation.description}} - - - analytics - - Some details of the run go here... - - - - - - - - - - - - - +

Simulations

+
+
+ + + + Name: {{simulation.name}} + + + Description: {{simulation.description}} + + + analytics + + Some details of the run go here... + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + +
-
diff --git a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss index 291892a..518af0a 100644 --- a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss +++ b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss @@ -1,7 +1,13 @@ .simulation__list-container { - margin: 8px; + padding: 8px; +} + +.simulation__card { + min-height: 300px; } .simulation__card-icon { font-size: 4rem; } + + From af2794b0ad2b87ce584eda9bd13457ab1ec6d547 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Mon, 15 Feb 2021 00:17:44 +0000 Subject: [PATCH 05/30] empty lines --- .../simulation-list-view/simulation-list-view.component.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss index 518af0a..57a4619 100644 --- a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss +++ b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss @@ -9,5 +9,3 @@ .simulation__card-icon { font-size: 4rem; } - - From 1b4dc71fccf00035a0de4c8a9d3e60382a7ecead Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Tue, 16 Feb 2021 22:09:01 +0000 Subject: [PATCH 06/30] Styled simulation's list. --- .../simulation-list-view.component.html | 27 ++++--------------- .../simulation-list-view.component.scss | 7 +++++ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html index 4f44fa9..31dd32e 100644 --- a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html +++ b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.html @@ -2,39 +2,22 @@

Simulations

- + - Name: {{simulation.name}} + {{simulation.name}} - Description: {{simulation.description}} + {{simulation.description}} analytics Some details of the run go here... - - - - - - - - - - - - - - - - - - + - + diff --git a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss index 57a4619..eb562aa 100644 --- a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss +++ b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss @@ -1,3 +1,5 @@ +@import "~src/app/styles/app-theme"; + .simulation__list-container { padding: 8px; } @@ -9,3 +11,8 @@ .simulation__card-icon { font-size: 4rem; } + + +.simulation__detail-button { + background: $warn; +} From 6c30a3198e832ad086c305569082f0bb686766ed Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Tue, 16 Feb 2021 23:06:25 +0000 Subject: [PATCH 07/30] Use proper routerLink. --- .../components/navigation/navigation.component.html | 12 ++++++------ .../simulation-list-view.component.html | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/front-end/src/app/components/navigation/navigation.component.html b/front-end/src/app/components/navigation/navigation.component.html index f5c2c39..ee5a8ef 100644 --- a/front-end/src/app/components/navigation/navigation.component.html +++ b/front-end/src/app/components/navigation/navigation.component.html @@ -3,7 +3,7 @@ From f805d285b12f38696ed2f04f78b862837c6d9bed Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Tue, 16 Feb 2021 23:06:40 +0000 Subject: [PATCH 08/30] Add get method. --- .../app/services/api/api-resources/api-resources.service.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/front-end/src/app/services/api/api-resources/api-resources.service.ts b/front-end/src/app/services/api/api-resources/api-resources.service.ts index 52adb77..1600cc8 100644 --- a/front-end/src/app/services/api/api-resources/api-resources.service.ts +++ b/front-end/src/app/services/api/api-resources/api-resources.service.ts @@ -15,6 +15,10 @@ export abstract class ApiResourcesService { protected url: string = API_URL, ) { } + get(id: number, requestOptions?: RequestOptions): Observable { + return this.httpClient.get(this.getUrl(this.endpoint, id), requestOptions); + } + list(requestOptions?: RequestOptions): Observable { return this.httpClient.get(this.getUrl(this.endpoint), requestOptions); } From 8a49c07d6591419cb39502e859989a3e0b2178c3 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Tue, 16 Feb 2021 23:07:00 +0000 Subject: [PATCH 09/30] Style detail view button same as others. --- .../simulation-list-view/simulation-list-view.component.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss index eb562aa..f086b2b 100644 --- a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss +++ b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.scss @@ -12,7 +12,6 @@ font-size: 4rem; } - .simulation__detail-button { background: $warn; } From 4ef6a341098ca59212ad2fde9b4b351ba9a6d827 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Tue, 16 Feb 2021 23:13:05 +0000 Subject: [PATCH 10/30] NAvigate to detail view on creating new sim. --- .../simulation-create-view.component.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/front-end/src/app/components/simulation/simulation-create-view/simulation-create-view.component.ts b/front-end/src/app/components/simulation/simulation-create-view/simulation-create-view.component.ts index b83bffa..d69449f 100644 --- a/front-end/src/app/components/simulation/simulation-create-view/simulation-create-view.component.ts +++ b/front-end/src/app/components/simulation/simulation-create-view/simulation-create-view.component.ts @@ -2,6 +2,7 @@ import {Component} from '@angular/core'; import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms'; import {SimulationAPIService} from '../../../services/api/simulation/simulation-api.service'; import {NotificationService} from '../../../services/notification/notification.service'; +import {ActivatedRoute, Router} from '@angular/router'; @Component({ selector: 'app-simulation-create-view', @@ -12,6 +13,8 @@ export class SimulationCreateViewComponent { appearance = 'standard'; constructor( + private activatedRoute: ActivatedRoute, + private router: Router, private fb: FormBuilder, private simulationAPIService: SimulationAPIService, private notificationService: NotificationService @@ -60,9 +63,8 @@ export class SimulationCreateViewComponent { onSubmit() { this.simulationAPIService.create(this.simulationForm.value).subscribe( data => { - this.simulationForm.get('name').reset(); - this.simulationForm.get('description').reset(); this.notificationService.showSuccess('Created simulation successfully!'); + this.router.navigate([`../detail/${data.id}`], {relativeTo: this.activatedRoute}); }, error => { this.notificationService.showFailure('Failed to create simulation! Please try again.'); From 5ca95a990730bc2f0d6055810dcc3b3165ffb29f Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Tue, 16 Feb 2021 23:13:16 +0000 Subject: [PATCH 11/30] Add more detail. --- .../simulation-detail-view.component.html | 4 ++++ .../simulation-detail-view.component.ts | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.html b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.html index 313908c..897ae0d 100644 --- a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.html +++ b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.html @@ -1 +1,5 @@

simulation-detail-view works!

+
+

{{simulation.name}}

+

{{simulation.description}}

+
diff --git a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts index e08cc19..f77f88d 100644 --- a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts +++ b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts @@ -1,5 +1,9 @@ import {Component, Input, OnInit} from '@angular/core'; -import {ActivatedRoute} from '@angular/router'; +import {ActivatedRoute, ParamMap} from '@angular/router'; +import {SimulationAPIService} from '../../../services/api/simulation/simulation-api.service'; +import {Observable} from 'rxjs'; +import {SimulationAPIResource} from '../../../models/simulation.models'; +import {switchMap} from 'rxjs/operators'; @Component({ selector: 'app-simulation-detail-view', @@ -8,11 +12,19 @@ import {ActivatedRoute} from '@angular/router'; }) export class SimulationDetailViewComponent implements OnInit { - constructor(private route: ActivatedRoute) { } + constructor( + private activatedRoute: ActivatedRoute, + private simulationAPIService: SimulationAPIService + ) { } + + simulation$: Observable @Input('simulation') ngOnInit(): void { + this.simulation$ = this.activatedRoute.paramMap.pipe( + switchMap((params: ParamMap) => this.simulationAPIService.get(parseInt(params.get('id')))) + ); } } From 82295a52dcfc636c76d85a8bb4dfcd75ca600acd Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Wed, 17 Feb 2021 00:01:29 +0000 Subject: [PATCH 12/30] Fix tests and lints --- .../navigation/navigation.component.spec.ts | 3 ++- .../simulation-create-view.component.spec.ts | 11 ++++++++++- .../simulation-detail-view.component.spec.ts | 15 ++++++++++++++- .../simulation-detail-view.component.ts | 4 ++-- .../simulation-list-view.component.spec.ts | 10 +++++++++- 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/front-end/src/app/components/navigation/navigation.component.spec.ts b/front-end/src/app/components/navigation/navigation.component.spec.ts index e015200..241dad4 100644 --- a/front-end/src/app/components/navigation/navigation.component.spec.ts +++ b/front-end/src/app/components/navigation/navigation.component.spec.ts @@ -2,6 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NavigationComponent } from './navigation.component'; import {MatToolbarModule} from '@angular/material/toolbar'; +import {RouterTestingModule} from '@angular/router/testing'; describe('NavigationComponent', () => { let component: NavigationComponent; @@ -10,7 +11,7 @@ describe('NavigationComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ NavigationComponent ], - imports: [MatToolbarModule], + imports: [MatToolbarModule, RouterTestingModule], }) .compileComponents(); })); diff --git a/front-end/src/app/components/simulation/simulation-create-view/simulation-create-view.component.spec.ts b/front-end/src/app/components/simulation/simulation-create-view/simulation-create-view.component.spec.ts index b53aeed..e2cb856 100644 --- a/front-end/src/app/components/simulation/simulation-create-view/simulation-create-view.component.spec.ts +++ b/front-end/src/app/components/simulation/simulation-create-view/simulation-create-view.component.spec.ts @@ -8,6 +8,8 @@ import {MatInputModule} from '@angular/material/input'; import {MatIconModule} from '@angular/material/icon'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; import {MatSnackBarModule} from '@angular/material/snack-bar'; +import {ActivatedRoute, Router} from '@angular/router'; +import {RouterTestingModule} from '@angular/router/testing'; describe('SimulationCreateViewComponent', () => { let component: SimulationCreateViewComponent; @@ -23,9 +25,16 @@ describe('SimulationCreateViewComponent', () => { ReactiveFormsModule, BrowserAnimationsModule, MatSnackBarModule, + RouterTestingModule ], declarations: [ SimulationCreateViewComponent ], - providers: [FormBuilder] + providers: [ + FormBuilder, + { + provide: ActivatedRoute, + useValue: {} + } + ] }) .compileComponents(); })); diff --git a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.spec.ts b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.spec.ts index 47869d9..f400d49 100644 --- a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.spec.ts +++ b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.spec.ts @@ -1,6 +1,9 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { SimulationDetailViewComponent } from './simulation-detail-view.component'; +import {ActivatedRoute} from '@angular/router'; +import {HttpClientTestingModule} from '@angular/common/http/testing'; +import {of} from 'rxjs'; describe('SimulationDetailViewComponent', () => { let component: SimulationDetailViewComponent; @@ -8,7 +11,17 @@ describe('SimulationDetailViewComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ SimulationDetailViewComponent ] + imports: [HttpClientTestingModule], + declarations: [ SimulationDetailViewComponent ], + providers: [ + { + provide: ActivatedRoute, + useValue: { + paramMap: of({}) + } + } + ] + }) .compileComponents(); })); diff --git a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts index f77f88d..a0cfb23 100644 --- a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts +++ b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts @@ -17,13 +17,13 @@ export class SimulationDetailViewComponent implements OnInit { private simulationAPIService: SimulationAPIService ) { } - simulation$: Observable + simulation$: Observable; @Input('simulation') ngOnInit(): void { this.simulation$ = this.activatedRoute.paramMap.pipe( - switchMap((params: ParamMap) => this.simulationAPIService.get(parseInt(params.get('id')))) + switchMap((params: ParamMap) => this.simulationAPIService.get(parseInt(params.get('id'), 10))) ); } diff --git a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.spec.ts b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.spec.ts index 2a5b2a1..bc2c1a6 100644 --- a/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.spec.ts +++ b/front-end/src/app/components/simulation/simulation-list-view/simulation-list-view.component.spec.ts @@ -2,6 +2,9 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { SimulationListViewComponent } from './simulation-list-view.component'; import {HttpClientTestingModule} from '@angular/common/http/testing'; +import {MatCardModule} from '@angular/material/card'; +import {MatIconModule} from '@angular/material/icon'; +import {RouterTestingModule} from '@angular/router/testing'; describe('SimulationListViewComponent', () => { let component: SimulationListViewComponent; @@ -10,7 +13,12 @@ describe('SimulationListViewComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ SimulationListViewComponent ], - imports: [HttpClientTestingModule], + imports: [ + HttpClientTestingModule, + MatCardModule, + MatIconModule, + RouterTestingModule + ], }) .compileComponents(); })); From 4b8ef0f0557d7ff5aad10dd8aa421d65bdaee9b0 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Wed, 17 Feb 2021 00:03:36 +0000 Subject: [PATCH 13/30] Remove useless input. --- .../simulation-detail-view/simulation-detail-view.component.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts index a0cfb23..824021a 100644 --- a/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts +++ b/front-end/src/app/components/simulation/simulation-detail-view/simulation-detail-view.component.ts @@ -19,8 +19,6 @@ export class SimulationDetailViewComponent implements OnInit { simulation$: Observable; - @Input('simulation') - ngOnInit(): void { this.simulation$ = this.activatedRoute.paramMap.pipe( switchMap((params: ParamMap) => this.simulationAPIService.get(parseInt(params.get('id'), 10))) From faf4023c972cfa8d6584df2e8953538051a7b453 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sat, 6 Mar 2021 20:07:19 +0000 Subject: [PATCH 14/30] Add celery to project. --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 094dc36..79a8adb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ apipkg==1.5 atomicwrites==1.3.0 attrs==19.2.0 +celery==5.0.5 certifi==2019.9.11 coverage==4.5.4 Django==3.1.5 From cc043b29e24dd4785c1f778c2ed146b9ec847c16 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sat, 6 Mar 2021 22:30:16 +0000 Subject: [PATCH 15/30] Add celery to project. --- factory_simulator/__init__.py | 5 +++++ factory_simulator/celery.py | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 factory_simulator/celery.py diff --git a/factory_simulator/__init__.py b/factory_simulator/__init__.py index e69de29..ba0cace 100644 --- a/factory_simulator/__init__.py +++ b/factory_simulator/__init__.py @@ -0,0 +1,5 @@ +# This will make sure the app is always imported when +# Django starts so that shared_task will use this app. +from .celery import celery_app + +__all__ = ('celery_app',) diff --git a/factory_simulator/celery.py b/factory_simulator/celery.py new file mode 100644 index 0000000..fe35ef7 --- /dev/null +++ b/factory_simulator/celery.py @@ -0,0 +1,17 @@ +import os + +from celery import Celery + +# set the default Django settings module for the 'celery' program. +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'factory_simulator.settings') + +celery_app = Celery('factory_simulator') + +# Using a string here means the worker doesn't have to serialize +# the configuration object to child processes. +# - namespace='CELERY' means all celery-related configuration keys +# should have a `CELERY_` prefix. +celery_app.config_from_object('django.conf:settings', namespace='CELERY') + +# Load task modules from all registered Django app configs. +celery_app.autodiscover_tasks() From 075ac642443c21a6cdbfe37aed741903a70bc10d Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sat, 6 Mar 2021 22:30:48 +0000 Subject: [PATCH 16/30] Add temporary code to trigger simulations from the UI. --- api/views/simulation.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/api/views/simulation.py b/api/views/simulation.py index 674fe16..2d3e375 100644 --- a/api/views/simulation.py +++ b/api/views/simulation.py @@ -2,8 +2,21 @@ from api.serializers.simulation import SimulationSerializer from simulation.models.simulation import Simulation +from simulation.tasks.tasks import run_simulation class SimulationViewSet(viewsets.ModelViewSet): serializer_class = SimulationSerializer queryset = Simulation.objects.prefetch_related('factory_configs', 'results') + + def create(self, request, *args, **kwargs): + response = super().create(request, *args, **kwargs) + + # TODO: create a dedicated endpoint for starting simulation and use it in the detail view in UI once the objects + # are successfully persisted - give a button. Initially just to run 1 factory config. Once we can do that - + # enable running each config in a simulation separately and have a run-all button as well. + + # TODO: move starting of the simulation into a dedicated endpoint away from here! + run_simulation.delay(response.data['id']) + + return response From de5c4d68881f8f523ff04c859696a3c3934d39be Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sat, 6 Mar 2021 22:31:04 +0000 Subject: [PATCH 17/30] Add basic celery settings. --- factory_simulator/settings.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/factory_simulator/settings.py b/factory_simulator/settings.py index 1840d86..9de845f 100644 --- a/factory_simulator/settings.py +++ b/factory_simulator/settings.py @@ -155,6 +155,11 @@ ), } +# Celery configuration +CELERY_TASK_IGNORE_RESULT = False +CELERY_TASK_SOFT_TIME_LIMIT = 4 * 60 * 60 +CELERY_TASK_TIME_LIMIT = 6 * 60 * 60 + INTERNAL_IPS = [ '127.0.0.1', ] From a9398408500b0658629dd0812d272413eef23009 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sat, 6 Mar 2021 22:31:41 +0000 Subject: [PATCH 18/30] Add run_simulation task. --- simulation/tasks/__init__.py | 0 simulation/tasks/tasks.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 simulation/tasks/__init__.py create mode 100644 simulation/tasks/tasks.py diff --git a/simulation/tasks/__init__.py b/simulation/tasks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/simulation/tasks/tasks.py b/simulation/tasks/tasks.py new file mode 100644 index 0000000..e3b18e0 --- /dev/null +++ b/simulation/tasks/tasks.py @@ -0,0 +1,31 @@ +from factory_simulator.celery import celery_app +from simulation.domain_models.conveyor_belt import ConveyorBelt +from simulation.domain_models.factory_floor import FactoryFloor +from simulation.domain_models.feeder import RandomizedFeeder +from simulation.domain_models.receiver import Receiver +from simulation.models.simulation import Simulation + + +@celery_app.task +def run_simulation(simulation_id: str): + # TODO: confirm how many queries this makes if there are multiple factory configs! + simulation = Simulation.objects.select_related().prefetch_related('factory_configs', 'results').get(id=simulation_id) + factory_configs = simulation.factory_configs.all() + + # TODO: this should be run per factory config once all deemed ok. + factory_config = factory_configs[0] + + # TODO: feeder type should be configurable from the front end + feeder = RandomizedFeeder(item_names=(*factory_config.materials, factory_config.empty_code)) + receiver = Receiver() + factory_floor = FactoryFloor( + feeder=feeder, + receiver=receiver, + conveyor_belt=ConveyorBelt(factory_config=factory_config), + factory_config=factory_config + ) + factory_floor.add_workers() + + factory_floor.run() + + print(receiver.received_item_names) From 4d6d65bc65c78fd7079207a39788325f1cf449e3 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sat, 27 Mar 2021 19:46:27 +0000 Subject: [PATCH 19/30] Add redis to project as a result backend. --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 79a8adb..e76be38 100644 --- a/requirements.txt +++ b/requirements.txt @@ -39,6 +39,7 @@ pytest-xdist==1.30.0 python-dateutil==2.8.0 python-decouple==3.1 pytz==2019.2 +redis==3.5.3 six==1.12.0 sqlparse==0.3.0 text-unidecode==1.3 From b3bdbdf245015601d5ff7e79cf39ab2078784f83 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sat, 27 Mar 2021 19:46:47 +0000 Subject: [PATCH 20/30] Add celery broker url and backend to settings.py --- factory_simulator/settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/factory_simulator/settings.py b/factory_simulator/settings.py index 9de845f..c2a786e 100644 --- a/factory_simulator/settings.py +++ b/factory_simulator/settings.py @@ -159,6 +159,8 @@ CELERY_TASK_IGNORE_RESULT = False CELERY_TASK_SOFT_TIME_LIMIT = 4 * 60 * 60 CELERY_TASK_TIME_LIMIT = 6 * 60 * 60 +CELERY_BROKER_URL = config('CELERY_BROKER_URL') +CELERY_RESULT_BACKEND = config('CELERY_RESULT_BACKEND') INTERNAL_IPS = [ '127.0.0.1', From daef827e6fbd7a11ef6ac6514dd353e9867c4f20 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 28 Mar 2021 14:08:49 +0100 Subject: [PATCH 21/30] Configure celery to send events. --- factory_simulator/settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/factory_simulator/settings.py b/factory_simulator/settings.py index c2a786e..62e2e10 100644 --- a/factory_simulator/settings.py +++ b/factory_simulator/settings.py @@ -159,6 +159,8 @@ CELERY_TASK_IGNORE_RESULT = False CELERY_TASK_SOFT_TIME_LIMIT = 4 * 60 * 60 CELERY_TASK_TIME_LIMIT = 6 * 60 * 60 +CELERY_TASK_SEND_SENT_EVENT = True +CELERY_WORKER_SEND_TASK_EVENTS = True CELERY_BROKER_URL = config('CELERY_BROKER_URL') CELERY_RESULT_BACKEND = config('CELERY_RESULT_BACKEND') From a28375cda6993f8a1f37894836c9ddba51554e6a Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 28 Mar 2021 15:48:58 +0100 Subject: [PATCH 22/30] Create helpers to construct broker and backend urls. --- factory_simulator/celery.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/factory_simulator/celery.py b/factory_simulator/celery.py index fe35ef7..68a8954 100644 --- a/factory_simulator/celery.py +++ b/factory_simulator/celery.py @@ -15,3 +15,22 @@ # Load task modules from all registered Django app configs. celery_app.autodiscover_tasks() + + +def get_celery_broker_url( + broker: str, + broker_username: str, + broker_password: str, + broker_host: str, + broker_port: str, + broker_virtual_host: str +) -> str: + return f'{broker}://{broker_username}:{broker_password}@{broker_host}:{broker_port}/{broker_virtual_host}' + + +def get_celery_result_backend_url( + result_backend: str, + result_backend_host: str, + result_backend_db: str, +) -> str: + return f'{result_backend}://{result_backend_host}/{result_backend_db}' From e06a90b6573b47e3a82d8463c5f3c6603ac2b8a5 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 28 Mar 2021 15:49:33 +0100 Subject: [PATCH 23/30] Update settings to construct broker and backend urls dynamically. --- factory_simulator/settings.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/factory_simulator/settings.py b/factory_simulator/settings.py index 62e2e10..3d2a83d 100644 --- a/factory_simulator/settings.py +++ b/factory_simulator/settings.py @@ -14,6 +14,7 @@ from decouple import config # Build paths inside the project like this: os.path.join(BASE_DIR, ...) +from factory_simulator.celery import get_celery_broker_url, get_celery_result_backend_url BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -161,8 +162,19 @@ CELERY_TASK_TIME_LIMIT = 6 * 60 * 60 CELERY_TASK_SEND_SENT_EVENT = True CELERY_WORKER_SEND_TASK_EVENTS = True -CELERY_BROKER_URL = config('CELERY_BROKER_URL') -CELERY_RESULT_BACKEND = config('CELERY_RESULT_BACKEND') +CELERY_BROKER_URL = get_celery_broker_url( + broker=config('BROKER'), + broker_username=config('BROKER_USERNAME'), + broker_password=config('BROKER_PASSWORD'), + broker_host=config('BROKER_HOST'), + broker_port=config('BROKER_PORT'), + broker_virtual_host=config('BROKER_VIRTUAL_HOST'), +) +CELERY_RESULT_BACKEND = get_celery_result_backend_url( + result_backend=config('RESULT_BACKEND'), + result_backend_host=config('RESULT_BACKEND_HOST'), + result_backend_db=config('RESULT_BACKEND_DB'), +) INTERNAL_IPS = [ '127.0.0.1', From c6aaffcfe0c79a17cfec28b200045341c9a6b807 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 28 Mar 2021 15:49:56 +0100 Subject: [PATCH 24/30] Fill in env vars for celery worker. --- kubernetes/celery-worker/config-map.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 kubernetes/celery-worker/config-map.yaml diff --git a/kubernetes/celery-worker/config-map.yaml b/kubernetes/celery-worker/config-map.yaml new file mode 100644 index 0000000..66da170 --- /dev/null +++ b/kubernetes/celery-worker/config-map.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: celery-worker-config + namespace: default +data: + BROKER: "amqp" + BROKER_USERNAME: "guest" + BROKER_PASSWORD: "guest" + BROKER_HOST: "localhost" + BROKER_PORT: "5672" + BROKER_VIRTUAL_HOST: "/" + RESULT_BACKEND: "redis" + RESULT_BACKEND_HOST: "localhost" + RESULT_BACKEND_DB: "0" From 239944f7f855b7ef26eb550879cfbab6b7cf2dbf Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 28 Mar 2021 15:50:14 +0100 Subject: [PATCH 25/30] Use env vars for celery. --- kubernetes/django-backend/deployment.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kubernetes/django-backend/deployment.yaml b/kubernetes/django-backend/deployment.yaml index c4fc950..dcc0d31 100644 --- a/kubernetes/django-backend/deployment.yaml +++ b/kubernetes/django-backend/deployment.yaml @@ -44,6 +44,8 @@ spec: envFrom: - configMapRef: name: django-backend-config + - configMapRef: + name: celery-worker-config volumeMounts: - mountPath: /var/lib/busybox name: postgres-volume-mount From c9fac1a7795754ff7487a1306e406157c0e96c7c Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 28 Mar 2021 15:50:32 +0100 Subject: [PATCH 26/30] Create deployment for celery worker. --- kubernetes/celery-worker/deployment.yaml | 46 ++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 kubernetes/celery-worker/deployment.yaml diff --git a/kubernetes/celery-worker/deployment.yaml b/kubernetes/celery-worker/deployment.yaml new file mode 100644 index 0000000..ededbe2 --- /dev/null +++ b/kubernetes/celery-worker/deployment.yaml @@ -0,0 +1,46 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: factory-simulator-celery-worker + labels: + app: factory-simulator-celery-worker +spec: + replicas: 1 + selector: + matchLabels: + app: factory-simulator-celery-worker + template: + metadata: + labels: + app: factory-simulator-celery-worker + spec: + containers: + - name: django-backend + image: kilthar/factory-simulator-django:latest + imagePullPolicy: Always + command: ["celery", "-A", "factory_simulator", "worker", "-l", "INFO"] + env: + - name: DEBUG + value: "False" + - name: ALLOWED_HOSTS + value: "factory-simulator.com" + - name: SECRET_KEY + valueFrom: + secretKeyRef: + name: django-backend-secrets + key: SECRET_KEY + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: postgres-secrets + key: POSTGRES_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: postgres-secrets + key: POSTGRES_PASSWORD + envFrom: + - configMapRef: + name: django-backend-config + - configMapRef: + name: celery-worker-config From e3db6a5d9de72f88c792a6d67909eb39b04acf88 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 28 Mar 2021 16:17:09 +0100 Subject: [PATCH 27/30] Update broker and result backend hosts. --- kubernetes/celery-worker/config-map.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubernetes/celery-worker/config-map.yaml b/kubernetes/celery-worker/config-map.yaml index 66da170..647b624 100644 --- a/kubernetes/celery-worker/config-map.yaml +++ b/kubernetes/celery-worker/config-map.yaml @@ -7,9 +7,9 @@ data: BROKER: "amqp" BROKER_USERNAME: "guest" BROKER_PASSWORD: "guest" - BROKER_HOST: "localhost" + BROKER_HOST: rabbitmq-broker-service BROKER_PORT: "5672" BROKER_VIRTUAL_HOST: "/" RESULT_BACKEND: "redis" - RESULT_BACKEND_HOST: "localhost" + RESULT_BACKEND_HOST: redis-result-backend-service RESULT_BACKEND_DB: "0" From bbed7a795e7b1d35c4adae8f35a3b9469df0e42e Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 28 Mar 2021 16:17:46 +0100 Subject: [PATCH 28/30] Configure rabbitmq broker deployment. --- kubernetes/rabbitmq-broker/deployment.yaml | 27 ++++++++++++++++++++++ kubernetes/rabbitmq-broker/services.yaml | 18 +++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 kubernetes/rabbitmq-broker/deployment.yaml create mode 100644 kubernetes/rabbitmq-broker/services.yaml diff --git a/kubernetes/rabbitmq-broker/deployment.yaml b/kubernetes/rabbitmq-broker/deployment.yaml new file mode 100644 index 0000000..3c855e5 --- /dev/null +++ b/kubernetes/rabbitmq-broker/deployment.yaml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: factory-simulator-rabbitmq-broker + labels: + app: factory-simulator-rabbitmq-broker +spec: + replicas: 1 + selector: + matchLabels: + app: factory-simulator-rabbitmq-broker + template: + metadata: + labels: + app: factory-simulator-rabbitmq-broker + spec: + containers: + - name: rabbitmq-broker + image: rabbitmq:3-management + imagePullPolicy: IfNotPresent + ports: + - name: amqp + containerPort: 5672 + - name: management + containerPort: 15672 + - name: prometheus + containerPort: 15692 diff --git a/kubernetes/rabbitmq-broker/services.yaml b/kubernetes/rabbitmq-broker/services.yaml new file mode 100644 index 0000000..30fd3dc --- /dev/null +++ b/kubernetes/rabbitmq-broker/services.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: rabbitmq-broker-service +spec: + type: ClusterIP + selector: + app: factory-simulator-rabbitmq-broker + ports: + - name: amqp + protocol: TCP + port: 5672 + - name: management + protocol: TCP + port: 15672 + - name: prometheus + protocol: TCP + port: 15692 From c9bbcb8b93c557866cc0a35cf0214a93503dfcbe Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 28 Mar 2021 16:19:43 +0100 Subject: [PATCH 29/30] Configure redis deployment. --- .../redis-result-backend/deployment.yaml | 22 +++++++++++++++++++ kubernetes/redis-result-backend/services.yaml | 12 ++++++++++ 2 files changed, 34 insertions(+) create mode 100644 kubernetes/redis-result-backend/deployment.yaml create mode 100644 kubernetes/redis-result-backend/services.yaml diff --git a/kubernetes/redis-result-backend/deployment.yaml b/kubernetes/redis-result-backend/deployment.yaml new file mode 100644 index 0000000..7e437e2 --- /dev/null +++ b/kubernetes/redis-result-backend/deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: factory-simulator-redis-result-backend + labels: + app: factory-simulator-redis-result-backend +spec: + replicas: 1 + selector: + matchLabels: + app: factory-simulator-redis-result-backend + template: + metadata: + labels: + app: factory-simulator-redis-result-backend + spec: + containers: + - name: redis-result-backend + image: redis + imagePullPolicy: IfNotPresent + ports: + - containerPort: 6379 diff --git a/kubernetes/redis-result-backend/services.yaml b/kubernetes/redis-result-backend/services.yaml new file mode 100644 index 0000000..6133d97 --- /dev/null +++ b/kubernetes/redis-result-backend/services.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: redis-result-backend-service +spec: + type: ClusterIP + selector: + app: factory-simulator-redis-result-backend + ports: + - protocol: TCP + port: 6379 + targetPort: 6379 From bdf9818ace77318321c27e9433eeb92d7c376441 Mon Sep 17 00:00:00 2001 From: Tomasz-Kluczkowski Date: Sun, 28 Mar 2021 17:10:39 +0100 Subject: [PATCH 30/30] Add env vars. --- kubernetes/postgres/migration-job.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kubernetes/postgres/migration-job.yaml b/kubernetes/postgres/migration-job.yaml index 5dbc9fe..7d5836e 100644 --- a/kubernetes/postgres/migration-job.yaml +++ b/kubernetes/postgres/migration-job.yaml @@ -35,4 +35,6 @@ spec: envFrom: - configMapRef: name: django-backend-config + - configMapRef: + name: celery-worker-config restartPolicy: Never