mstore list page

This commit is contained in:
Michele Artini 2023-02-08 12:23:53 +01:00
parent 1491e8a5d2
commit c9c0ac00b8
13 changed files with 312 additions and 309 deletions

View File

@ -7,7 +7,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
public class SwaggerController { public class SwaggerController {
@RequestMapping(value = { @RequestMapping(value = {
"/docs", "swagger-ui.html", "swagger-ui/" "/", "/docs", "swagger-ui.html", "swagger-ui/"
}) })
public String apiDoc() { public String apiDoc() {
return "redirect:swagger-ui/index.html"; return "redirect:swagger-ui/index.html";

View File

@ -12,7 +12,6 @@ import eu.dnetlib.dhp.schema.mdstore.MDStoreVersion;
import eu.dnetlib.dhp.schema.mdstore.MDStoreWithInfo; import eu.dnetlib.dhp.schema.mdstore.MDStoreWithInfo;
import eu.dnetlib.errors.MDStoreManagerException; import eu.dnetlib.errors.MDStoreManagerException;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
public class AbstractMDStoreController extends AbstractDnetController { public class AbstractMDStoreController extends AbstractDnetController {
@ -27,32 +26,26 @@ public class AbstractMDStoreController extends AbstractDnetController {
@Operation(summary = "Return a mdstores by id") @Operation(summary = "Return a mdstores by id")
@GetMapping("/mdstore/{mdId}") @GetMapping("/mdstore/{mdId}")
public MDStoreWithInfo getMdStore(@Parameter(name = "the mdstore identifier") @PathVariable final String mdId) throws MDStoreManagerException { public MDStoreWithInfo getMdStore(@PathVariable final String mdId) throws MDStoreManagerException {
return service.findMdStore(mdId); return service.findMdStore(mdId);
} }
@Operation(summary = "Increase the read count of the current mdstore")
@GetMapping("/mdstore/{mdId}/startReading")
public MDStoreVersion startReading(@Parameter(name = "the mdstore identifier") @PathVariable final String mdId) throws MDStoreManagerException {
return service.startReading(mdId);
}
@Operation(summary = "Create a new mdstore") @Operation(summary = "Create a new mdstore")
@PostMapping("/new/{format}/{layout}/{interpretation}") @PostMapping("/new/{format}/{layout}/{interpretation}")
public MDStoreWithInfo createMDStore( public MDStoreWithInfo createMDStore(
@Parameter(name = "mdstore format") @PathVariable final String format, @PathVariable final String format,
@Parameter(name = "mdstore layout") @PathVariable final String layout, @PathVariable final String layout,
@Parameter(name = "mdstore interpretation") @PathVariable final String interpretation, @PathVariable final String interpretation,
@Parameter(name = "datasource name") @RequestParam(required = true) final String dsName, @RequestParam(required = true) final String dsName,
@Parameter(name = "datasource id") @RequestParam(required = true) final String dsId, @RequestParam(required = true) final String dsId,
@Parameter(name = "api id") @RequestParam(required = true) final String apiId) throws MDStoreManagerException { @RequestParam(required = true) final String apiId) throws MDStoreManagerException {
final String id = service.createMDStore(format, layout, interpretation, dsName, dsId, apiId); final String id = service.createMDStore(format, layout, interpretation, dsName, dsId, apiId);
return service.findMdStore(id); return service.findMdStore(id);
} }
@Operation(summary = "Delete a mdstore by id") @Operation(summary = "Delete a mdstore by id")
@DeleteMapping("/mdstore/{mdId}") @DeleteMapping("/mdstore/{mdId}")
public StatusResponse delete(@Parameter(name = "the id of the mdstore that will be deleted") @PathVariable final String mdId) public StatusResponse delete(@PathVariable final String mdId)
throws MDStoreManagerException { throws MDStoreManagerException {
service.deleteMdStore(mdId); service.deleteMdStore(mdId);
@ -68,15 +61,15 @@ public class AbstractMDStoreController extends AbstractDnetController {
@Operation(summary = "Create a new preliminary version of a mdstore") @Operation(summary = "Create a new preliminary version of a mdstore")
@GetMapping("/mdstore/{mdId}/newVersion") @GetMapping("/mdstore/{mdId}/newVersion")
public MDStoreVersion prepareNewVersion( public MDStoreVersion prepareNewVersion(
@Parameter(name = "the id of the mdstore for which will be created a new version") @PathVariable final String mdId) { @PathVariable final String mdId) {
return service.prepareMdStoreVersion(mdId); return service.prepareMdStoreVersion(mdId);
} }
@Operation(summary = "Promote a preliminary version to current") @Operation(summary = "Promote a preliminary version to current")
@GetMapping("/version/{versionId}/commit/{size}") @GetMapping("/version/{versionId}/commit/{size}")
public MDStoreVersion commitVersion( public MDStoreVersion commitVersion(
@Parameter(name = "the id of the version that will be promoted to the current version") @PathVariable final String versionId, @PathVariable final String versionId,
@Parameter(name = "the size of the new current mdstore") @PathVariable final long size) throws MDStoreManagerException { @PathVariable final long size) throws MDStoreManagerException {
try { try {
return service.commitMdStoreVersion(versionId, size); return service.commitMdStoreVersion(versionId, size);
} finally { } finally {
@ -86,7 +79,7 @@ public class AbstractMDStoreController extends AbstractDnetController {
@Operation(summary = "Abort a preliminary version") @Operation(summary = "Abort a preliminary version")
@GetMapping("/version/{versionId}/abort") @GetMapping("/version/{versionId}/abort")
public StatusResponse commitVersion(@Parameter(name = "the id of the version to abort") @PathVariable final String versionId) public StatusResponse commitVersion(@PathVariable final String versionId)
throws MDStoreManagerException { throws MDStoreManagerException {
service.deleteMdStoreVersion(versionId, true); service.deleteMdStoreVersion(versionId, true);
@ -96,15 +89,15 @@ public class AbstractMDStoreController extends AbstractDnetController {
@Operation(summary = "Return an existing mdstore version") @Operation(summary = "Return an existing mdstore version")
@GetMapping("/version/{versionId}") @GetMapping("/version/{versionId}")
public MDStoreVersion getVersion(@Parameter(name = "the id of the version that has to be deleted") @PathVariable final String versionId) public MDStoreVersion getVersion(@PathVariable final String versionId)
throws MDStoreManagerException { throws MDStoreManagerException {
return service.findVersion(versionId); return service.findVersion(versionId);
} }
@Operation(summary = "Delete a mdstore version") @Operation(summary = "Delete a mdstore version")
@DeleteMapping("/version/{versionId}") @DeleteMapping("/version/{versionId}")
public StatusResponse deleteVersion(@Parameter(name = "the id of the version that has to be deleted") @PathVariable final String versionId, public StatusResponse deleteVersion(@PathVariable final String versionId,
@Parameter(name = "if true, the controls on writing and readcount values will be skipped") @RequestParam(required = false, defaultValue = "false") final boolean force) @RequestParam(required = false, defaultValue = "false") final boolean force)
throws MDStoreManagerException { throws MDStoreManagerException {
service.deleteMdStoreVersion(versionId, force); service.deleteMdStoreVersion(versionId, force);
@ -114,15 +107,13 @@ public class AbstractMDStoreController extends AbstractDnetController {
@Operation(summary = "Decrease the read count of a mdstore version") @Operation(summary = "Decrease the read count of a mdstore version")
@GetMapping("/version/{versionId}/endReading") @GetMapping("/version/{versionId}/endReading")
public MDStoreVersion endReading(@Parameter(name = "the id of the version that has been completely read") @PathVariable final String versionId) public MDStoreVersion endReading(@PathVariable final String versionId) throws MDStoreManagerException {
throws MDStoreManagerException {
return service.endReading(versionId); return service.endReading(versionId);
} }
@Operation(summary = "Reset the read count of a mdstore version") @Operation(summary = "Reset the read count of a mdstore version")
@GetMapping("/version/{versionId}/resetReading") @GetMapping("/version/{versionId}/resetReading")
public MDStoreVersion resetReading(@Parameter(name = "the id of the version") @PathVariable final String versionId) public MDStoreVersion resetReading(@PathVariable final String versionId) throws MDStoreManagerException {
throws MDStoreManagerException {
return service.resetReading(versionId); return service.resetReading(versionId);
} }

View File

@ -17,7 +17,7 @@ import eu.dnetlib.errors.MDStoreManagerException;
public class MDInspectorController { public class MDInspectorController {
@Autowired @Autowired
private MDStoreService databaseUtils; private MDStoreService service;
private static final Logger log = LoggerFactory.getLogger(MDInspectorController.class); private static final Logger log = LoggerFactory.getLogger(MDInspectorController.class);
@ -32,12 +32,12 @@ public class MDInspectorController {
if (isMdstoreId(id)) { if (isMdstoreId(id)) {
log.debug("MDSTORE: " + id); log.debug("MDSTORE: " + id);
md = databaseUtils.findMdStore(id); md = service.findMdStore(id);
ver = databaseUtils.findVersion(md.getCurrentVersion()); ver = service.findVersion(md.getCurrentVersion());
} else { } else {
log.debug("VERSION: " + id); log.debug("VERSION: " + id);
ver = databaseUtils.findVersion(id); ver = service.findVersion(id);
md = databaseUtils.findMdStore(ver.getMdstore()); md = service.findMdStore(ver.getMdstore());
} }
map.addAttribute("mdId", md.getId()); map.addAttribute("mdId", md.getId());

View File

@ -10,9 +10,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import eu.dnetlib.dhp.schema.mdstore.MDStoreVersion;
import eu.dnetlib.errors.MDStoreManagerException; import eu.dnetlib.errors.MDStoreManagerException;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
@RestController @RestController
@ -26,13 +26,19 @@ public class MDStoreApiController extends AbstractMDStoreController {
return service.listMdStoreIDs(); return service.listMdStoreIDs();
} }
@Operation(summary = "Increase the read count of the current mdstore")
@GetMapping("/mdstore/{mdId}/startReading")
public MDStoreVersion startReading(@PathVariable final String mdId) throws MDStoreManagerException {
return service.startReading(mdId);
}
@Operation(summary = "Fix the inconsistencies on HDFS") @Operation(summary = "Fix the inconsistencies on HDFS")
@GetMapping("/hdfs/inconsistencies") @GetMapping("/hdfs/inconsistencies")
public Set<String> fixHdfsInconsistencies( public Set<String> fixHdfsInconsistencies(
@Parameter(name = "force the deletion of hdfs paths") @RequestParam(required = false, defaultValue = "false") final boolean delete) @RequestParam(required = false, defaultValue = "false") final boolean forceDelete)
throws MDStoreManagerException { throws MDStoreManagerException {
return service.fixHdfsInconsistencies(delete); return service.fixHdfsInconsistencies(forceDelete);
} }
@Operation(summary = "Delete expired versions") @Operation(summary = "Delete expired versions")

View File

@ -1,12 +1,15 @@
package eu.dnetlib.data.mdstore; package eu.dnetlib.data.mdstore;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.transaction.Transactional; import javax.transaction.Transactional;
@ -51,12 +54,15 @@ public class MDStoreService {
private static final Logger log = LoggerFactory.getLogger(MDStoreService.class); private static final Logger log = LoggerFactory.getLogger(MDStoreService.class);
public Iterable<MDStoreWithInfo> listMdStores() { public List<MDStoreWithInfo> listMdStores() {
return mdstoreWithInfoRepository.findAll();
return StreamSupport.stream(mdstoreWithInfoRepository.findAll().spliterator(), false)
.sorted(Comparator.comparing((Function<MDStoreWithInfo, String>) md -> md.getDatasourceName()).thenComparing(md -> md.getId()))
.collect(Collectors.toList());
} }
public List<String> listMdStoreIDs() { public List<String> listMdStoreIDs() {
return mdstoreRepository.findAll().stream().map(MDStore::getId).collect(Collectors.toList()); return mdstoreRepository.findAll().stream().map(MDStore::getId).sorted().collect(Collectors.toList());
} }
public long countMdStores() { public long countMdStores() {
@ -64,7 +70,7 @@ public class MDStoreService {
} }
public Iterable<MDStoreVersion> listVersions(final String mdId) { public Iterable<MDStoreVersion> listVersions(final String mdId) {
return mdstoreVersionRepository.findByMdstore(mdId); return mdstoreVersionRepository.findByMdstoreOrderById(mdId);
} }
public List<String> listExpiredVersions() { public List<String> listExpiredVersions() {

View File

@ -14,6 +14,6 @@ public interface MDStoreVersionRepository extends JpaRepository<MDStoreVersion,
long countByMdstoreAndReadCountGreaterThan(String id, int count); long countByMdstoreAndReadCountGreaterThan(String id, int count);
Iterable<MDStoreVersion> findByMdstore(String mdId); Iterable<MDStoreVersion> findByMdstoreOrderById(String mdId);
} }

View File

@ -275,11 +275,15 @@ export class ISService {
}); });
} }
deleteMDStoreVersion(versionId:string, force:boolean, onSuccess: Function) { deleteMDStoreVersion(versionId:string, onSuccess: Function) {
let params = new HttpParams(); this.client.delete<any>('./ajax/mdstores/version/' + encodeURIComponent(versionId)).subscribe({
if (force) { params = params.append('force', true); } next: data => onSuccess(data),
error: error => this.showError(error)
this.client.delete<any>('./ajax/mdstores/version/' + encodeURIComponent(versionId), {params: params}).subscribe({ });
}
resetReadingMDStoreVersion(versionId:string, onSuccess: Function) {
this.client.get<any>('./ajax/mdstores/version/' + encodeURIComponent(versionId) + '/resetReading').subscribe({
next: data => onSuccess(data), next: data => onSuccess(data),
error: error => this.showError(error) error: error => this.showError(error)
}); });

View File

@ -1,50 +1,51 @@
<form [formGroup]="newMdstoreForm" (ngSubmit)="onSubmit()"> <form [formGroup]="newMdstoreForm" (ngSubmit)="onSubmit()">
<h1 mat-dialog-title>New MDStore</h1>
<div mat-dialog-content>
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
<mat-label>Format</mat-label>
<input matInput formControlName="format" />
<mat-error *ngIf="newMdstoreForm.get('format')?.invalid">This field is <strong>required</strong></mat-error>
</mat-form-field>
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;"> <h1 mat-dialog-title>New MDStore</h1>
<mat-label>Layout</mat-label>
<input matInput formControlName="layout" />
<mat-error *ngIf="newMdstoreForm.get('layout')?.invalid">This field is <strong>required</strong></mat-error>
</mat-form-field>
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;"> <div mat-dialog-content>
<mat-label>Interpretation</mat-label>
<input matInput formControlName="interpretation" />
<mat-error *ngIf="newMdstoreForm.get('interpretation')?.invalid">This field is <strong>required</strong></mat-error>
</mat-form-field>
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
<mat-label>Datasource Name</mat-label>
<input matInput formControlName="dsName" />
</mat-form-field>
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;"> <mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
<mat-label>Datasource ID</mat-label> <mat-label>Format</mat-label>
<input matInput formControlName="dsId" /> <input matInput formControlName="format" />
</mat-form-field> <mat-error *ngIf="newMdstoreForm.get('format')?.invalid">This field is <strong>required</strong></mat-error>
</mat-form-field>
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;"> <mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
<mat-label>API ID</mat-label> <mat-label>Layout</mat-label>
<input matInput formControlName="apiId" /> <input matInput formControlName="layout" />
</mat-form-field> <mat-error *ngIf="newMdstoreForm.get('layout')?.invalid">This field is <strong>required</strong></mat-error>
</mat-form-field>
</div> <mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
<mat-label>Interpretation</mat-label>
<div mat-dialog-actions> <input matInput formControlName="interpretation" />
<button mat-stroked-button color="primary" type="submit" [disabled]="!newMdstoreForm.valid">Submit</button> <mat-error *ngIf="newMdstoreForm.get('interpretation')?.invalid">This field is
<button mat-stroked-button color="primary" mat-dialog-close>Close</button> <strong>required</strong></mat-error>
<mat-error *ngIf="newMdstoreForm.errors?.['serverError']"> </mat-form-field>
{{ newMdstoreForm.errors?.['serverError'] }}
</mat-error> <mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
</div> <mat-label>Datasource Name</mat-label>
<input matInput formControlName="dsName" />
</form> </mat-form-field>
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
<mat-label>Datasource ID</mat-label>
<input matInput formControlName="dsId" />
</mat-form-field>
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%;">
<mat-label>API ID</mat-label>
<input matInput formControlName="apiId" />
</mat-form-field>
</div>
<div mat-dialog-actions>
<button mat-stroked-button color="primary" type="submit" [disabled]="!newMdstoreForm.valid">Submit</button>
<button mat-stroked-button color="primary" mat-dialog-close>Close</button>
<mat-error *ngIf="newMdstoreForm.errors?.['serverError']">
{{ newMdstoreForm.errors?.['serverError'] }}
</mat-error>
</div>
</form>

View File

@ -1,48 +1,45 @@
<h1 mat-dialog-title>MDStore Versions</h1> <h1 mat-dialog-title>MDStore Versions</h1>
<div mat-dialog-content> <div mat-dialog-content>
<p class="small" style="text-align: right;"> <div style="text-align: right;">
<input type="checkbox" [(ngModel)]="forceDelete" /> <button mat-stroked-button color="primary" (click)="reload()">refresh</button>
force delete </div>
</p> <table class="mdstore-table small">
<thead>
<table class="mdstore-table small"> <tr>
<thead> <th style="width: 50%">ID</th>
<tr> <th style="width: 20%; text-align: center;">Read Count</th>
<th style="width: 50%">ID</th> <th style="width: 20%; text-align: center;">Last Update</th>
<th style="width: 20%; text-align: center;">Read Count</th> <th style="width: 10%; text-align: right;">Size</th>
<th style="width: 20%; text-align: center;">Last Update</th> </tr>
<th style="width: 10%; text-align: right;">Size</th> </thead>
</tr> <tbody>
</thead> <tr *ngFor="let v of versions" [ngClass]="{'active-row': v.id == data.currentVersion}">
<tbody> <td title="{{v.hdfsPath}}">
<tr *ngFor="let v of versions" [ngClass]="{'active-row': v.id == data.currentVersion}"> <mat-icon fontIcon="edit" *ngIf="v.writing" title="writing..."></mat-icon>
<td> <b> {{v.id}}</b>
<mat-icon fontIcon="edit" *ngIf="v.writing" title="writing..."></mat-icon> <br />
<b> {{v.id}}</b> <span class="small"><b>Path:</b> {{v.hdfsPath}}</span><br />
<br /> <button mat-stroked-button color="primary" (click)="openInspectorPage(v)">inspect</button>
<span class="small"><b>Path:</b> {{v.hdfsPath}}</span><br /> <button mat-stroked-button color="basic" *ngIf="v.writing" (click)="commitVersion(v)">commit</button>
<button mat-stroked-button color="primary" (click)="openInspectorPage(v)">inspect</button> <button mat-stroked-button color="warn" *ngIf="v.writing" (click)="abortVersion(v)">abort</button>
<button mat-stroked-button color="basic" *ngIf="v.writing" <button mat-stroked-button color="warn" *ngIf="!v.writing && v.readCount == 0 && v.id != data.currentVersion"
(click)="commitVersion(v)">commit</button> (click)="deleteVersion(v)">delete</button>
<button mat-stroked-button color="warn" *ngIf="v.writing" </td>
ng-click="abortVersion(v.id)">abort</button> <td style="text-align: center;">
<button mat-stroked-button color="warn" *ngIf="v.id != data.currentVersion" {{v.readCount}}
ng-click="deleteVersion(v.id, forceVersionDelete)">delete</button> <button mat-stroked-button color="primary" (click)="resetReading(v)"
</td> [disabled]="v.readCount == 0">reset</button>
<td style="text-align: center;"> </td>
{{v.readCount}} <td style="text-align: center;" title="{{v.lastUpdate}}">{{v.lastUpdate | date:"MMM dd,
<button mat-stroked-button color="primary" (click)="resetReading(v)" yyyy 'at' HH:mm"}}</td>
[disabled]="v.readCount == 0">reset</button> <td style="text-align: right;">{{v.size}}</td>
</td> </tr>
<td style="text-align: center;" title="{{v.lastUpdate}}">{{v.lastUpdate | date:"MMM dd, yyyy 'at' HH:mm"}}</td> </tbody>
<td style="text-align: right;">{{v.size}}</td> </table>
</tr>
</tbody>
</table>
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button mat-stroked-button color="primary" mat-dialog-close>Close</button> <button mat-stroked-button color="primary" mat-dialog-close>Close</button>
</div> </div>

View File

@ -1,33 +1,33 @@
.mdstore-table { .mdstore-table {
margin-top: 1em; border-collapse: collapse;
margin-bottom: 1em;
border-collapse: collapse;
} }
.mdstore-table tr:not(:last-child) { .mdstore-table tr:not(:last-child) {
border-bottom: 1pt solid lightgrey; border-bottom: 1pt solid lightgrey;
} }
.mdstore-table th, .mdstore-table td{ .mdstore-table th,
text-align: left; .mdstore-table td {
font-size: 0.9em; text-align: left;
vertical-align: top; font-size: 0.9em;
padding-left: 1em; vertical-align: top;
padding-right: 1em; padding-left: 1em;
padding-right: 1em;
} }
.mdstore-table td button, .mdstore-table td a.mdc-button { .mdstore-table td button,
font-size: 0.8em !important; .mdstore-table td a.mdc-button {
padding: 0 !important; font-size: 0.8em !important;
height: 2.5em !important; padding: 0 !important;
height: 2.5em !important;
} }
.mdstore-table tr.active-row { .mdstore-table tr.active-row {
background-color: #daffda; background-color: #daffda;
} }
.mdstore-table mat-icon { .mdstore-table mat-icon {
width: 1em; width: 1em;
height: 1em; height: 1em;
font-size: 1em; font-size: 1em;
} }

View File

@ -1,60 +1,61 @@
<h2>Metadata Stores</h2> <h2>Metadata Stores</h2>
<button mat-stroked-button color="primary" (click)="openAddMdstoreDialog()">create a new mdstore</button> <button mat-stroked-button color="primary" (click)="openAddMdstoreDialog()">create a new mdstore</button>
<button mat-stroked-button color="primary" (click)="reload()">refresh</button>
<mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;"> <mat-form-field appearance="fill" floatLabel="always" style="width: 100%; margin-top: 10px;">
<mat-label><b>Filter</b> (Total: {{(mdstores | searchFilter: searchText).length}})</mat-label> <mat-label><b>Filter</b> (Total: {{(mdstores | searchFilter: searchText).length}})</mat-label>
<input matInput [(ngModel)]="searchText" placeholder="Filter..." autofocus /> <input matInput [(ngModel)]="searchText" placeholder="Filter..." autofocus />
</mat-form-field> </mat-form-field>
<mat-card *ngFor="let md of mdstores | searchFilter: searchText" style="margin-top: 10px;"> <mat-card *ngFor="let md of mdstores | searchFilter: searchText" style="margin-top: 10px;">
<mat-card-header> <mat-card-header>
<mat-card-title>{{md.id}}</mat-card-title> <mat-card-title>{{md.id}}</mat-card-title>
<mat-card-subtitle>{{md.datasourceName}}</mat-card-subtitle> <mat-card-subtitle>{{md.datasourceName}}</mat-card-subtitle>
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content style="padding-top: 1em; padding-bottom: 1em;">
<table class="mdstore-table"> <table class="mdstore-table">
<tr> <tr>
<th style="width: 30%">Format / Layout / Interpretation</th> <th style="width: 30%">Format / Layout / Interpretation</th>
<td style="width: 70%">{{md.format}} / {{md.layout}} / {{md.interpretation}}</td> <td style="width: 70%">{{md.format}} / {{md.layout}} / {{md.interpretation}}</td>
</tr> </tr>
<tr> <tr>
<th>Datasource</th> <th>Datasource</th>
<td> <td>
<b>Name:</b> {{md.datasourceName}}<br /> <b>Name:</b> {{md.datasourceName}}<br />
<b>ID:</b> {{md.datasourceId}}<br /> <b>ID:</b> {{md.datasourceId}}<br />
<b>API:</b> {{md.apiId}} <b>API:</b> {{md.apiId}}
</td> </td>
</tr> </tr>
<tr> <tr>
<th>Creation Date</th> <th>Creation Date</th>
<td>{{md.creationDate}}</td> <td>{{md.creationDate}}</td>
</tr> </tr>
<tr> <tr>
<th>Last Update</th> <th>Last Update</th>
<td>{{md.lastUpdate}}</td> <td>{{md.lastUpdate}}</td>
</tr> </tr>
<tr> <tr>
<th>Size</th> <th>Size</th>
<td>{{md.size}}</td> <td>{{md.size}}</td>
</tr> </tr>
<tr> <tr>
<th>HDFS Path</th> <th>HDFS Path</th>
<td>{{md.hdfsPath}}</td> <td>{{md.hdfsPath}}</td>
</tr> </tr>
<tr> <tr>
<th>Versions</th> <th>Versions</th>
<td> <td>
<a (click)="openVersionsDialog(md)">{{md.numberOfVersions}} version(s)</a> <a (click)="openVersionsDialog(md)">{{md.numberOfVersions}} version(s)</a>
/ /
<a (click)="createNewVersion(md)">prepare new version</a> <a (click)="createNewVersion(md)">prepare new version</a>
</td> </td>
</tr> </tr>
</table> </table>
</mat-card-content> </mat-card-content>
<mat-card-actions> <mat-card-actions>
<a [routerLink]="['/mdrecords/' + md.currentVersion + '/50']" mat-stroked-button color="primary">inspect</a> <a [routerLink]="['/mdrecords/' + md.currentVersion + '/50']" mat-stroked-button color="primary">inspect</a>
<button mat-stroked-button color="warn" (click)="deleteMdstore(md)">delete</button> <button mat-stroked-button color="warn" (click)="deleteMdstore(md)">delete</button>
<button mat-stroked-button color="info">zeppelin</button> <button mat-stroked-button color="info">zeppelin</button>
</mat-card-actions> </mat-card-actions>
</mat-card> </mat-card>

View File

@ -6,148 +6,148 @@ import { MDStore, MDStoreVersion } from '../common/is.model';
import { FormControl, FormGroup, Validators } from '@angular/forms'; import { FormControl, FormGroup, Validators } from '@angular/forms';
@Component({ @Component({
selector: 'app-mdstores', selector: 'app-mdstores',
templateUrl: './mdstores.component.html', templateUrl: './mdstores.component.html',
styleUrls: ['./mdstores.component.css'] styleUrls: ['./mdstores.component.css']
}) })
export class MdstoresComponent implements OnInit { export class MdstoresComponent implements OnInit {
mdstores:MDStore[] = []; mdstores: MDStore[] = [];
searchText:string = ''; searchText: string = '';
constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) {} constructor(public service: ISService, public route: ActivatedRoute, public dialog: MatDialog) { }
ngOnInit() { this.reload() } ngOnInit() { this.reload() }
reload() { this.service.loadMDStores((data: MDStore[]) => this.mdstores = data); } reload() { this.service.loadMDStores((data: MDStore[]) => this.mdstores = data); }
openVersionsDialog(md:MDStore): void { openVersionsDialog(md: MDStore): void {
const dialogRef = this.dialog.open(MDStoreVersionsDialog, { const dialogRef = this.dialog.open(MDStoreVersionsDialog, {
data: md, data: md,
width: '80%' width: '80%'
}); });
dialogRef.afterClosed().subscribe(result => { dialogRef.afterClosed().subscribe(result => {
if (result) this.reload(); if (result) this.reload();
}); });
} }
openAddMdstoreDialog(): void { openAddMdstoreDialog(): void {
const dialogRef = this.dialog.open(AddMDStoreDialog, { const dialogRef = this.dialog.open(AddMDStoreDialog, {
data: {}, data: {},
width: '80%' width: '80%'
}); });
dialogRef.afterClosed().subscribe(result => { dialogRef.afterClosed().subscribe(result => {
if (result) this.reload(); if (result) this.reload();
}); });
} }
createNewVersion(md:MDStore): void { createNewVersion(md: MDStore): void {
this.service.prepareNewMDStoreVersion(md.id, (data:MDStoreVersion) => { this.service.prepareNewMDStoreVersion(md.id, (data: MDStoreVersion) => {
md.numberOfVersions = md.numberOfVersions + 1; md.numberOfVersions = md.numberOfVersions + 1;
this.openVersionsDialog(md); this.openVersionsDialog(md);
}); });
} }
deleteMdstore(md:MDStore) { deleteMdstore(md: MDStore) {
if (confirm('Are you sure?')) { if (confirm('Are you sure?')) {
this.service.deleteMDStore(md.id, (data: void) => this.reload()); this.service.deleteMDStore(md.id, (data: void) => this.reload());
} }
} }
} }
@Component({ @Component({
selector: 'app-mdstore-inspector', selector: 'app-mdstore-inspector',
templateUrl: './mdstore-inspector.component.html', templateUrl: './mdstore-inspector.component.html',
styleUrls: ['./mdstores.component.css'] styleUrls: ['./mdstores.component.css']
}) })
export class MdstoreInspectorComponent { export class MdstoreInspectorComponent {
} }
@Component({ @Component({
selector: 'mdstores-versions-dialog', selector: 'mdstores-versions-dialog',
templateUrl: './mdstores-versions-dialog.html', templateUrl: './mdstores-versions-dialog.html',
styleUrls: ['./mdstores.component.css'] styleUrls: ['./mdstores.component.css']
}) })
export class MDStoreVersionsDialog { export class MDStoreVersionsDialog {
forceDelete:boolean = false;
versions:MDStoreVersion[] = [];
constructor(public dialogRef: MatDialogRef<MDStoreVersionsDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService, public router: Router) { versions: MDStoreVersion[] = [];
this.reload();
}
reload() { constructor(public dialogRef: MatDialogRef<MDStoreVersionsDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService, public router: Router) {
this.service.loadMDStoreVersions(this.data.id, (res:MDStoreVersion[]) => this.versions = res); this.reload();
} }
openInspectorPage(version:MDStoreVersion):void { reload() {
const url = this.router.serializeUrl( this.service.loadMDStoreVersions(this.data.id, (res: MDStoreVersion[]) => this.versions = res);
this.router.createUrlTree(['/mdrecords/' + encodeURIComponent(version.id) + '/50']) }
);
window.open(url, '_blank');
}
resetReading(version:MDStoreVersion):void { openInspectorPage(version: MDStoreVersion): void {
//TODO const url = this.router.serializeUrl(
} this.router.createUrlTree(['/mdrecords/' + encodeURIComponent(version.id) + '/50'])
);
window.open(url, '_blank');
}
commitVersion(version:MDStoreVersion):void { resetReading(version: MDStoreVersion): void {
let size:number = parseInt(prompt("New Size", "0") || "0"); this.service.resetReadingMDStoreVersion(version.id, (data: void) => version.readCount = 0);
if (size >= 0) { }
this.service.commitMDStoreVersion(version.id, size, (data:void) => {
this.reload();
//TODO this version should be promoved as current
});
}
}
abortVersion(version:MDStoreVersion):void { commitVersion(version: MDStoreVersion): void {
this.service.abortMDStoreVersion(version.id, (data:void) => this.reload()); let size: number = parseInt(prompt("New Size", "0") || "0");
} if (size >= 0) {
this.service.commitMDStoreVersion(version.id, size, (data: void) => {
this.data.currentVersion = version.id;
this.reload();
});
}
}
deleteVersion(version:MDStoreVersion):void { abortVersion(version: MDStoreVersion): void {
this.service.deleteMDStoreVersion(version.id, this.forceDelete, (data:void) => this.reload()); this.service.abortMDStoreVersion(version.id, (data: void) => this.reload());
} }
onNoClick(): void { deleteVersion(version: MDStoreVersion): void {
this.dialogRef.close(); this.service.deleteMDStoreVersion(version.id, (data: void) => this.reload());
} }
onNoClick(): void {
this.dialogRef.close();
}
} }
@Component({ @Component({
selector: 'add-mdstore-dialog', selector: 'add-mdstore-dialog',
templateUrl: './add-mdstore-dialog.html', templateUrl: './add-mdstore-dialog.html',
styleUrls: ['./mdstores.component.css'] styleUrls: ['./mdstores.component.css']
}) })
export class AddMDStoreDialog { export class AddMDStoreDialog {
newMdstoreForm = new FormGroup({ newMdstoreForm = new FormGroup({
format: new FormControl('', [Validators.required]), format: new FormControl('', [Validators.required]),
layout : new FormControl('', [Validators.required]), layout: new FormControl('', [Validators.required]),
interpretation : new FormControl('', [Validators.required]), interpretation: new FormControl('', [Validators.required]),
dsName : new FormControl(''), dsName: new FormControl(''),
dsId : new FormControl(''), dsId: new FormControl(''),
apiId : new FormControl(''), apiId: new FormControl(''),
}); });
constructor(public dialogRef: MatDialogRef<MDStoreVersionsDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
}
onSubmit():void { constructor(public dialogRef: MatDialogRef<MDStoreVersionsDialog>, @Inject(MAT_DIALOG_DATA) public data: any, public service: ISService) {
let format:string = this.newMdstoreForm.get('format')?.value!;
let layout:string = this.newMdstoreForm.get('layout')?.value!; }
let interpretation:string = this.newMdstoreForm.get('interpretation')?.value!;
let dsName:string = this.newMdstoreForm.get('dsName')?.value!; onSubmit(): void {
let dsId:string = this.newMdstoreForm.get('dsId')?.value!; let format: string = this.newMdstoreForm.get('format')?.value!;
let apiId:string = this.newMdstoreForm.get('apiId')?.value!; let layout: string = this.newMdstoreForm.get('layout')?.value!;
let interpretation: string = this.newMdstoreForm.get('interpretation')?.value!;
this.service.addMDStore(format, layout, interpretation, dsName, dsId, apiId, (data: void) => this.dialogRef.close(1), this.newMdstoreForm); let dsName: string = this.newMdstoreForm.get('dsName')?.value!;
} let dsId: string = this.newMdstoreForm.get('dsId')?.value!;
let apiId: string = this.newMdstoreForm.get('apiId')?.value!;
onNoClick(): void {
this.dialogRef.close(); this.service.addMDStore(format, layout, interpretation, dsName, dsId, apiId, (data: void) => this.dialogRef.close(1), this.newMdstoreForm);
} }
onNoClick(): void {
this.dialogRef.close();
}
} }

View File

@ -1,7 +1,4 @@
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module'; import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));