ViewerController.java
/*
* Copyright (C) 2023 B3Partners B.V.
*
* SPDX-License-Identifier: MIT
*/
package org.tailormap.api.controller;
import static org.tailormap.api.util.Constants.UUID_REGEX;
import io.micrometer.core.annotation.Counted;
import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.Metrics;
import java.util.Locale;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.server.ResponseStatusException;
import org.tailormap.api.annotation.AppRestController;
import org.tailormap.api.persistence.Application;
import org.tailormap.api.persistence.Configuration;
import org.tailormap.api.persistence.Upload;
import org.tailormap.api.persistence.helper.ApplicationHelper;
import org.tailormap.api.persistence.helper.UploadHelper;
import org.tailormap.api.persistence.helper.ViewerResponseHelper;
import org.tailormap.api.prometheus.TagNames;
import org.tailormap.api.repository.ApplicationRepository;
import org.tailormap.api.repository.ConfigurationRepository;
import org.tailormap.api.security.AuthorisationService;
import org.tailormap.api.viewer.model.AppStyling;
import org.tailormap.api.viewer.model.MapResponse;
import org.tailormap.api.viewer.model.ViewerResponse;
@AppRestController
public class ViewerController implements TagNames {
private final ConfigurationRepository configurationRepository;
private final ApplicationRepository applicationRepository;
private final ApplicationHelper applicationHelper;
private final AuthorisationService authorisationService;
private final UploadHelper uploadHelper;
private final ViewerResponseHelper viewerResponseHelper;
public ViewerController(
ConfigurationRepository configurationRepository,
ApplicationRepository applicationRepository,
ApplicationHelper applicationHelper,
AuthorisationService authorisationService,
UploadHelper uploadHelper,
ViewerResponseHelper viewerResponseHelper) {
this.configurationRepository = configurationRepository;
this.applicationRepository = applicationRepository;
this.applicationHelper = applicationHelper;
this.authorisationService = authorisationService;
this.uploadHelper = uploadHelper;
this.viewerResponseHelper = viewerResponseHelper;
}
@GetMapping(path = "${tailormap-api.base-path}/app")
@Timed(value = "get_default_app", description = "Get default app")
@Counted(value = "get_default_app", description = "Count of get default app")
public ViewerResponse defaultApp() {
String defaultAppName = configurationRepository.get(Configuration.DEFAULT_APP);
Application app = applicationRepository.findByName(defaultAppName);
if (app == null) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
if (!this.authorisationService.userAllowedToViewApplication(app)) {
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
}
return viewer(app, ViewerResponse.KindEnum.APP);
}
// We can't parametrize viewerKind (/app/ and /service/) because they'd clash with /api/admin/...
// so name the paths separately
@GetMapping(
path = {"${tailormap-api.base-path}/app/{viewerName}", "${tailormap-api.base-path}/service/{viewerName}"})
@Timed(value = "get_named_app", description = "Get named app")
@Counted(value = "get_named_app", description = "Count of get named app")
public ViewerResponse viewer(@ModelAttribute Application app, @ModelAttribute ViewerResponse.KindEnum viewerKind) {
ViewerResponse viewerResponse =
viewerResponseHelper.getViewerResponse(app).kind(viewerKind);
AppStyling styling = viewerResponse.getStyling();
if (styling != null) {
styling.setLogo(uploadHelper.getUrlForImage(styling.getLogo(), Upload.CATEGORY_APP_LOGO));
}
// count/increment the number of times this viewer has been requested
Metrics.counter(
METRICS_APP_REQUEST_COUNTER_NAME,
METRICS_APP_TYPE_TAG,
viewerKind.name().toLowerCase(Locale.getDefault()),
METRICS_APP_NAME_TAG,
app.getName(),
METRICS_APP_ID_TAG,
app.getId().toString())
.increment();
return viewerResponse;
}
@GetMapping(
path = {
"${tailormap-api.base-path}/app/{viewerName}/map",
"${tailormap-api.base-path}/service/{viewerName}/map"
})
public MapResponse map(@ModelAttribute Application app) {
MapResponse mapResponse = applicationHelper.toMapResponse(app);
mapResponse.getAppLayers().stream()
.filter(l ->
l.getLegendImageUrl() != null && l.getLegendImageUrl().matches(UUID_REGEX))
.forEach(l -> l.setLegendImageUrl(
uploadHelper.getUrlForImage(l.getLegendImageUrl(), Upload.CATEGORY_LEGEND)));
return mapResponse;
}
}