1
2
3
4
5
6 package org.tailormap.api.configuration.dev;
7
8 import static org.tailormap.api.persistence.json.GeoServiceProtocol.WMS;
9 import static org.tailormap.api.persistence.json.GeoServiceProtocol.WMTS;
10 import static org.tailormap.api.persistence.json.GeoServiceProtocol.XYZ;
11 import static org.tailormap.api.security.AuthorizationService.ACCESS_TYPE_READ;
12 import static org.tailormap.api.util.Constants.TEST_TASK_TYPE;
13
14 import com.fasterxml.jackson.databind.ObjectMapper;
15 import java.lang.invoke.MethodHandles;
16 import java.time.OffsetDateTime;
17 import java.time.ZoneId;
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.NoSuchElementException;
23 import org.quartz.SchedulerException;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import org.springframework.beans.factory.annotation.Value;
27 import org.springframework.boot.SpringApplication;
28 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
29 import org.springframework.boot.context.event.ApplicationReadyEvent;
30 import org.springframework.context.ApplicationContext;
31 import org.springframework.context.event.EventListener;
32 import org.springframework.core.io.ClassPathResource;
33 import org.springframework.transaction.annotation.Transactional;
34 import org.tailormap.api.geotools.featuresources.FeatureSourceFactoryHelper;
35 import org.tailormap.api.geotools.featuresources.JDBCFeatureSourceHelper;
36 import org.tailormap.api.geotools.featuresources.WFSFeatureSourceHelper;
37 import org.tailormap.api.persistence.Application;
38 import org.tailormap.api.persistence.Catalog;
39 import org.tailormap.api.persistence.Configuration;
40 import org.tailormap.api.persistence.GeoService;
41 import org.tailormap.api.persistence.Group;
42 import org.tailormap.api.persistence.SearchIndex;
43 import org.tailormap.api.persistence.TMFeatureSource;
44 import org.tailormap.api.persistence.TMFeatureType;
45 import org.tailormap.api.persistence.Upload;
46 import org.tailormap.api.persistence.User;
47 import org.tailormap.api.persistence.helper.GeoServiceHelper;
48 import org.tailormap.api.persistence.json.AdminAdditionalProperty;
49 import org.tailormap.api.persistence.json.AppContent;
50 import org.tailormap.api.persistence.json.AppLayerSettings;
51 import org.tailormap.api.persistence.json.AppSettings;
52 import org.tailormap.api.persistence.json.AppTreeLayerNode;
53 import org.tailormap.api.persistence.json.AppTreeLevelNode;
54 import org.tailormap.api.persistence.json.AppTreeNode;
55 import org.tailormap.api.persistence.json.AttributeSettings;
56 import org.tailormap.api.persistence.json.AuthorizationRule;
57 import org.tailormap.api.persistence.json.AuthorizationRuleDecision;
58 import org.tailormap.api.persistence.json.Bounds;
59 import org.tailormap.api.persistence.json.CatalogNode;
60 import org.tailormap.api.persistence.json.FeatureTypeRef;
61 import org.tailormap.api.persistence.json.FeatureTypeTemplate;
62 import org.tailormap.api.persistence.json.GeoServiceDefaultLayerSettings;
63 import org.tailormap.api.persistence.json.GeoServiceLayerSettings;
64 import org.tailormap.api.persistence.json.GeoServiceSettings;
65 import org.tailormap.api.persistence.json.JDBCConnectionProperties;
66 import org.tailormap.api.persistence.json.ServiceAuthentication;
67 import org.tailormap.api.persistence.json.TailormapObjectRef;
68 import org.tailormap.api.persistence.json.TileLayerHiDpiMode;
69 import org.tailormap.api.repository.ApplicationRepository;
70 import org.tailormap.api.repository.CatalogRepository;
71 import org.tailormap.api.repository.ConfigurationRepository;
72 import org.tailormap.api.repository.FeatureSourceRepository;
73 import org.tailormap.api.repository.GeoServiceRepository;
74 import org.tailormap.api.repository.GroupRepository;
75 import org.tailormap.api.repository.SearchIndexRepository;
76 import org.tailormap.api.repository.UploadRepository;
77 import org.tailormap.api.repository.UserRepository;
78 import org.tailormap.api.scheduling.PocTask;
79 import org.tailormap.api.scheduling.TMJobDataMap;
80 import org.tailormap.api.scheduling.TaskCreator;
81 import org.tailormap.api.security.InternalAdminAuthentication;
82 import org.tailormap.api.solr.SolrHelper;
83 import org.tailormap.api.solr.SolrService;
84 import org.tailormap.api.viewer.model.AppStyling;
85 import org.tailormap.api.viewer.model.Component;
86 import org.tailormap.api.viewer.model.ComponentConfig;
87
88
89
90
91
92 @org.springframework.context.annotation.Configuration
93 @ConditionalOnProperty(name = "tailormap-api.database.populate-testdata", havingValue = "true")
94 public class PopulateTestData {
95
96 private static final Logger logger =
97 LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
98 private final ApplicationContext appContext;
99 private final UserRepository userRepository;
100 private final GroupRepository groupRepository;
101 private final CatalogRepository catalogRepository;
102 private final GeoServiceRepository geoServiceRepository;
103 private final GeoServiceHelper geoServiceHelper;
104 private final SolrService solrService;
105 private final TaskCreator taskCreator;
106 private final FeatureSourceRepository featureSourceRepository;
107 private final ApplicationRepository applicationRepository;
108 private final ConfigurationRepository configurationRepository;
109 private final SearchIndexRepository searchIndexRepository;
110 private final FeatureSourceFactoryHelper featureSourceFactoryHelper;
111 private final UploadRepository uploadRepository;
112
113 @Value("${spatial.dbs.connect:false}")
114 private boolean connectToSpatialDbs;
115
116 @Value("${spatial.dbs.localhost:true}")
117 private boolean connectToSpatialDbsAtLocalhost;
118
119 @Value("${tailormap-api.database.populate-testdata.admin-hashed-password}")
120 private String adminHashedPassword;
121
122 @Value("${tailormap-api.database.populate-testdata.exit:false}")
123 private boolean exit;
124
125 @Value("${MAP5_URL:#{null}}")
126 private String map5url;
127
128 public PopulateTestData(
129 ApplicationContext appContext,
130 UserRepository userRepository,
131 GroupRepository groupRepository,
132 CatalogRepository catalogRepository,
133 GeoServiceRepository geoServiceRepository,
134 GeoServiceHelper geoServiceHelper,
135 SolrService solrService,
136 TaskCreator taskCreator,
137 FeatureSourceRepository featureSourceRepository,
138 ApplicationRepository applicationRepository,
139 ConfigurationRepository configurationRepository,
140 FeatureSourceFactoryHelper featureSourceFactoryHelper,
141 SearchIndexRepository searchIndexRepository,
142 UploadRepository uploadRepository) {
143 this.appContext = appContext;
144 this.userRepository = userRepository;
145 this.groupRepository = groupRepository;
146 this.catalogRepository = catalogRepository;
147 this.geoServiceRepository = geoServiceRepository;
148 this.geoServiceHelper = geoServiceHelper;
149 this.solrService = solrService;
150 this.taskCreator = taskCreator;
151 this.featureSourceRepository = featureSourceRepository;
152 this.applicationRepository = applicationRepository;
153 this.configurationRepository = configurationRepository;
154 this.featureSourceFactoryHelper = featureSourceFactoryHelper;
155 this.searchIndexRepository = searchIndexRepository;
156 this.uploadRepository = uploadRepository;
157 }
158
159 @EventListener(ApplicationReadyEvent.class)
160 @Transactional
161 public void populate() throws Exception {
162 InternalAdminAuthentication.setInSecurityContext();
163 try {
164
165
166 createTestUsersAndGroups();
167 createTestConfiguration();
168 try {
169 createSolrIndex();
170 } catch (Exception e) {
171 logger.error("Exception creating Solr Index for testdata (continuing)", e);
172 }
173 createPocTasks();
174 } finally {
175 InternalAdminAuthentication.clearSecurityContextAuthentication();
176 }
177 if (exit) {
178
179
180 new Thread(
181 () -> {
182 try {
183 Thread.sleep(5000);
184 } catch (InterruptedException ignored) {
185
186 }
187 SpringApplication.exit(appContext, () -> 0);
188 System.exit(0);
189 })
190 .start();
191 }
192 }
193
194 public void createTestUsersAndGroups() throws NoSuchElementException {
195 Group groupFoo = new Group().setName("test-foo").setDescription("Used for integration tests.");
196 groupRepository.save(groupFoo);
197
198 AdminAdditionalProperty gp1 = new AdminAdditionalProperty();
199 gp1.setKey("group-property");
200 gp1.setValue(Boolean.TRUE);
201 gp1.setIsPublic(true);
202 AdminAdditionalProperty gp2 = new AdminAdditionalProperty();
203 gp2.setKey("group-private-property");
204 gp2.setValue(999.9);
205 gp2.setIsPublic(false);
206 Group groupBar =
207 new Group()
208 .setName("test-bar")
209 .setDescription("Used for integration tests.")
210 .setAdditionalProperties(List.of(gp1, gp2));
211 groupRepository.save(groupBar);
212
213 Group groupBaz = new Group().setName("test-baz").setDescription("Used for integration tests.");
214 groupRepository.save(groupBaz);
215
216
217 User u = new User().setUsername("user").setPassword("{noop}user").setEmail("user@example.com");
218 u.getGroups().addAll(List.of(groupFoo, groupBar, groupBaz));
219 userRepository.save(u);
220
221
222 AdminAdditionalProperty up1 = new AdminAdditionalProperty();
223 up1.setKey("some-property");
224 up1.setValue("some-value");
225 up1.setIsPublic(true);
226 AdminAdditionalProperty up2 = new AdminAdditionalProperty();
227 up2.setKey("admin-property");
228 up2.setValue("private-value");
229 up2.setIsPublic(false);
230 u =
231 new User()
232 .setUsername("tm-admin")
233 .setPassword(adminHashedPassword)
234 .setAdditionalProperties(List.of(up1, up2));
235 u.getGroups().add(groupRepository.findById(Group.ADMIN).orElseThrow());
236 u.getGroups().add(groupBar);
237 userRepository.save(u);
238 }
239
240 @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
241 public void createTestConfiguration() throws Exception {
242
243 Catalog catalog = catalogRepository.findById(Catalog.MAIN).orElseThrow();
244 CatalogNode rootCatalogNode = catalog.getNodes().get(0);
245 CatalogNode catalogNode = new CatalogNode().id("test").title("Test services");
246 rootCatalogNode.addChildrenItem(catalogNode.getId());
247 catalog.getNodes().add(catalogNode);
248
249 List<AuthorizationRule> rule =
250 List.of(
251 new AuthorizationRule()
252 .groupName(Group.ANONYMOUS)
253 .decisions(Map.of(ACCESS_TYPE_READ, AuthorizationRuleDecision.ALLOW)));
254
255 List<AuthorizationRule> ruleLoggedIn =
256 List.of(
257 new AuthorizationRule()
258 .groupName(Group.AUTHENTICATED)
259 .decisions(Map.of(ACCESS_TYPE_READ, AuthorizationRuleDecision.ALLOW)));
260
261 String osmAttribution =
262 "© [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors";
263
264 Bounds rdTileGridExtent =
265 new Bounds().minx(-285401.92).maxx(595401.92).miny(22598.08).maxy(903401.92);
266
267 Upload legend =
268 new Upload()
269 .setCategory(Upload.CATEGORY_LEGEND)
270 .setFilename("gemeentegebied-legend.png")
271 .setMimeType("image/png")
272 .setContent(
273 new ClassPathResource("test/gemeentegebied-legend.png").getContentAsByteArray())
274 .setLastModified(OffsetDateTime.now(ZoneId.systemDefault()));
275 uploadRepository.save(legend);
276
277 Collection<GeoService> services =
278 List.of(
279 new GeoService()
280 .setId("demo")
281 .setProtocol(WMS)
282 .setTitle("Demo")
283 .setPublished(true)
284 .setAuthorizationRules(rule)
285 .setUrl("https://demo.tailormap.com/geoserver/geodata/ows?SERVICE=WMS"),
286 new GeoService()
287 .setId("osm")
288 .setProtocol(XYZ)
289 .setTitle("OSM")
290 .setUrl("https://tile.openstreetmap.org/{z}/{x}/{y}.png")
291 .setAuthorizationRules(rule)
292 .setSettings(
293 new GeoServiceSettings()
294 .xyzCrs("EPSG:3857")
295 .layerSettings(
296 Map.of(
297 "xyz",
298 new GeoServiceLayerSettings()
299 .attribution(osmAttribution)
300 .maxZoom(19)))),
301
302 new GeoService()
303 .setId("snapshot-geoserver")
304 .setProtocol(WMS)
305 .setTitle("Test GeoServer")
306 .setUrl("https://snapshot.tailormap.nl/geoserver/wms")
307 .setAuthorizationRules(rule)
308 .setPublished(true),
309 new GeoService()
310 .setId("filtered-snapshot-geoserver")
311 .setProtocol(WMS)
312 .setTitle("Test GeoServer (with authorization rules)")
313 .setUrl("https://snapshot.tailormap.nl/geoserver/wms")
314 .setAuthorizationRules(
315 List.of(
316 new AuthorizationRule()
317 .groupName("test-foo")
318 .decisions(Map.of(ACCESS_TYPE_READ, AuthorizationRuleDecision.ALLOW)),
319 new AuthorizationRule()
320 .groupName("test-baz")
321 .decisions(Map.of(ACCESS_TYPE_READ, AuthorizationRuleDecision.ALLOW))))
322 .setSettings(
323 new GeoServiceSettings()
324 .layerSettings(
325 Map.of(
326 "BGT",
327 new GeoServiceLayerSettings()
328 .addAuthorizationRulesItem(
329 new AuthorizationRule()
330 .groupName("test-foo")
331 .decisions(
332 Map.of(
333 ACCESS_TYPE_READ,
334 AuthorizationRuleDecision.DENY)))
335 .addAuthorizationRulesItem(
336 new AuthorizationRule()
337 .groupName("test-baz")
338 .decisions(
339 Map.of(
340 ACCESS_TYPE_READ,
341 AuthorizationRuleDecision.ALLOW))))))
342 .setPublished(true),
343 new GeoService()
344 .setId("snapshot-geoserver-proxied")
345 .setProtocol(WMS)
346 .setTitle("Test GeoServer (proxied)")
347 .setUrl("https://snapshot.tailormap.nl/geoserver/wms")
348 .setAuthorizationRules(rule)
349 .setSettings(new GeoServiceSettings().useProxy(true)),
350 new GeoService()
351 .setId("openbasiskaart")
352 .setProtocol(WMTS)
353 .setTitle("Openbasiskaart")
354 .setUrl("https://www.openbasiskaart.nl/mapcache/wmts")
355 .setAuthorizationRules(rule)
356 .setSettings(
357 new GeoServiceSettings()
358 .defaultLayerSettings(
359 new GeoServiceDefaultLayerSettings().attribution(osmAttribution))
360 .layerSettings(
361 Map.of(
362 "osm",
363 new GeoServiceLayerSettings()
364 .title("Openbasiskaart")
365 .hiDpiDisabled(false)
366 .hiDpiMode(TileLayerHiDpiMode.SUBSTITUTELAYERSHOWNEXTZOOMLEVEL)
367 .hiDpiSubstituteLayer("osm-hq")))),
368 new GeoService()
369 .setId("openbasiskaart-proxied")
370 .setProtocol(WMTS)
371 .setTitle("Openbasiskaart (proxied)")
372 .setUrl("https://www.openbasiskaart.nl/mapcache/wmts")
373 .setAuthorizationRules(rule)
374
375
376 .setAuthentication(
377 new ServiceAuthentication()
378 .method(ServiceAuthentication.MethodEnum.PASSWORD)
379 .username("test")
380 .password("test"))
381 .setSettings(
382 new GeoServiceSettings()
383 .useProxy(true)
384 .defaultLayerSettings(
385 new GeoServiceDefaultLayerSettings().attribution(osmAttribution))
386 .layerSettings(
387 Map.of(
388 "osm",
389 new GeoServiceLayerSettings()
390 .hiDpiDisabled(false)
391 .hiDpiMode(TileLayerHiDpiMode.SUBSTITUTELAYERSHOWNEXTZOOMLEVEL)
392 .hiDpiSubstituteLayer("osm-hq")))),
393 new GeoService()
394 .setId("openbasiskaart-tms")
395 .setProtocol(XYZ)
396 .setTitle("Openbasiskaart (TMS)")
397 .setUrl("https://openbasiskaart.nl/mapcache/tms/1.0.0/osm@rd/{z}/{x}/{-y}.png")
398 .setAuthorizationRules(rule)
399 .setSettings(
400 new GeoServiceSettings()
401 .xyzCrs("EPSG:28992")
402 .defaultLayerSettings(
403 new GeoServiceDefaultLayerSettings().attribution(osmAttribution))
404 .layerSettings(
405 Map.of(
406 "xyz",
407 new GeoServiceLayerSettings()
408 .maxZoom(15)
409 .tileGridExtent(rdTileGridExtent)
410 .hiDpiDisabled(false)
411 .hiDpiMode(TileLayerHiDpiMode.SUBSTITUTELAYERTILEPIXELRATIOONLY)
412 .hiDpiSubstituteLayer(
413 "https://openbasiskaart.nl/mapcache/tms/1.0.0/osm-hq@rd-hq/{z}/{x}/{-y}.png")))),
414 new GeoService()
415 .setId("pdok-hwh-luchtfotorgb")
416 .setProtocol(WMTS)
417 .setTitle("PDOK HWH luchtfoto")
418 .setUrl("https://service.pdok.nl/hwh/luchtfotorgb/wmts/v1_0")
419 .setAuthorizationRules(rule)
420 .setPublished(true)
421 .setSettings(
422 new GeoServiceSettings()
423 .defaultLayerSettings(
424 new GeoServiceDefaultLayerSettings()
425 .attribution("© [Beeldmateriaal.nl](https://beeldmateriaal.nl)")
426 .hiDpiDisabled(false))
427 .putLayerSettingsItem(
428 "Actueel_orthoHR", new GeoServiceLayerSettings().title("Luchtfoto"))),
429 new GeoService()
430 .setId("b3p-mapproxy-luchtfoto")
431 .setProtocol(XYZ)
432 .setTitle("Luchtfoto (TMS)")
433 .setUrl("https://mapproxy.b3p.nl/tms/1.0.0/luchtfoto/EPSG28992/{z}/{x}/{-y}.jpeg")
434 .setAuthorizationRules(rule)
435 .setPublished(true)
436 .setSettings(
437 new GeoServiceSettings()
438 .xyzCrs("EPSG:28992")
439 .defaultLayerSettings(
440 new GeoServiceDefaultLayerSettings()
441 .attribution("© [Beeldmateriaal.nl](https://beeldmateriaal.nl)")
442 .hiDpiDisabled(false))
443 .layerSettings(
444 Map.of(
445 "xyz",
446 new GeoServiceLayerSettings()
447 .maxZoom(14)
448 .tileGridExtent(rdTileGridExtent)
449 .hiDpiMode(TileLayerHiDpiMode.SHOWNEXTZOOMLEVEL)))),
450 new GeoService()
451 .setId("at-basemap")
452 .setProtocol(WMTS)
453 .setTitle("basemap.at")
454 .setUrl("https://basemap.at/wmts/1.0.0/WMTSCapabilities.xml")
455 .setAuthorizationRules(rule)
456 .setPublished(true)
457 .setSettings(
458 new GeoServiceSettings()
459 .defaultLayerSettings(
460 new GeoServiceDefaultLayerSettings()
461 .attribution("© [basemap.at](https://basemap.at)")
462 .hiDpiDisabled(true))
463 .layerSettings(
464 Map.of(
465 "geolandbasemap",
466 new GeoServiceLayerSettings()
467 .title("Basemap")
468 .hiDpiDisabled(false)
469 .hiDpiMode(TileLayerHiDpiMode.SUBSTITUTELAYERTILEPIXELRATIOONLY)
470 .hiDpiSubstituteLayer("bmaphidpi"),
471 "bmaporthofoto30cm",
472 new GeoServiceLayerSettings()
473 .title("Orthophoto")
474 .hiDpiDisabled(false)))),
475 new GeoService()
476 .setId("pdok-kadaster-bestuurlijkegebieden")
477 .setProtocol(WMS)
478 .setUrl(
479 "https://service.pdok.nl/kadaster/bestuurlijkegebieden/wms/v1_0?service=WMS")
480 .setAuthorizationRules(rule)
481 .setSettings(
482 new GeoServiceSettings()
483 .defaultLayerSettings(
484 new GeoServiceDefaultLayerSettings()
485 .description("This layer shows an administrative boundary."))
486
487 .serverType(GeoServiceSettings.ServerTypeEnum.MAPSERVER)
488 .useProxy(true)
489 .putLayerSettingsItem(
490 "Gemeentegebied",
491 new GeoServiceLayerSettings().legendImageId(legend.getId().toString())))
492 .setPublished(true)
493 .setTitle("PDOK Kadaster bestuurlijke gebieden"),
494 new GeoService()
495 .setId("bestuurlijkegebieden-proxied")
496 .setProtocol(WMS)
497 .setUrl(
498 "https://service.pdok.nl/kadaster/bestuurlijkegebieden/wms/v1_0?service=WMS")
499 .setAuthorizationRules(rule)
500
501
502
503 .setAuthentication(
504 new ServiceAuthentication()
505 .method(ServiceAuthentication.MethodEnum.PASSWORD)
506 .username("test")
507 .password("test"))
508 .setSettings(
509 new GeoServiceSettings()
510
511 .serverType(GeoServiceSettings.ServerTypeEnum.MAPSERVER)
512 .useProxy(true))
513 .setPublished(true)
514 .setTitle("Bestuurlijke gebieden (proxied met auth)")
515
516 );
517
518 if (map5url != null) {
519 GeoServiceLayerSettings osmAttr = new GeoServiceLayerSettings().attribution(osmAttribution);
520 GeoServiceLayerSettings map5Attr =
521 new GeoServiceLayerSettings()
522 .attribution("Kaarten: [Map5.nl](https://map5.nl), data: " + osmAttribution);
523 services = new ArrayList<>(services);
524 services.add(
525 new GeoService()
526 .setId("map5")
527 .setProtocol(WMTS)
528 .setTitle("Map5")
529 .setUrl(map5url)
530 .setAuthorizationRules(rule)
531 .setSettings(
532 new GeoServiceSettings()
533 .defaultLayerSettings(
534 new GeoServiceDefaultLayerSettings().hiDpiDisabled(true))
535 .layerSettings(
536 Map.of(
537 "openlufo",
538 new GeoServiceLayerSettings()
539 .attribution(
540 "© [Beeldmateriaal.nl](https://beeldmateriaal.nl), "
541 + osmAttribution),
542 "luforoadslabels", osmAttr,
543 "map5topo",
544 new GeoServiceLayerSettings()
545 .attribution(map5Attr.getAttribution())
546 .hiDpiDisabled(false)
547 .hiDpiMode(
548 TileLayerHiDpiMode.SUBSTITUTELAYERSHOWNEXTZOOMLEVEL)
549 .hiDpiSubstituteLayer("map5topo_hq"),
550 "map5topo_gray", map5Attr,
551 "map5topo_simple", map5Attr,
552 "map5topo_simple_gray", map5Attr,
553 "opensimpletopo", osmAttr,
554 "opensimpletopo_gray", osmAttr,
555 "opentopo", osmAttr,
556 "opentopo_gray", osmAttr))));
557 }
558
559 for (GeoService geoService : services) {
560 geoServiceHelper.loadServiceCapabilities(geoService);
561
562 geoServiceRepository.save(geoService);
563 catalogNode.addItemsItem(
564 new TailormapObjectRef()
565 .kind(TailormapObjectRef.KindEnum.GEO_SERVICE)
566 .id(geoService.getId()));
567 }
568
569 CatalogNode wfsFeatureSourceCatalogNode =
570 new CatalogNode().id("wfs_feature_sources").title("WFS feature sources");
571 rootCatalogNode.addChildrenItem(wfsFeatureSourceCatalogNode.getId());
572 catalog.getNodes().add(wfsFeatureSourceCatalogNode);
573
574 services.stream()
575 .filter(s -> s.getProtocol() == WMS)
576 .forEach(
577 s -> {
578 geoServiceHelper.findAndSaveRelatedWFS(s);
579 List<TMFeatureSource> linkedSources =
580 featureSourceRepository.findByLinkedServiceId(s.getId());
581 for (TMFeatureSource linkedSource : linkedSources) {
582 wfsFeatureSourceCatalogNode.addItemsItem(
583 new TailormapObjectRef()
584 .kind(TailormapObjectRef.KindEnum.FEATURE_SOURCE)
585 .id(linkedSource.getId().toString()));
586 }
587 });
588
589 String geodataPassword = "980f1c8A-25933b2";
590
591 Map<String, TMFeatureSource> featureSources =
592 Map.of(
593 "postgis",
594 new TMFeatureSource()
595 .setProtocol(TMFeatureSource.Protocol.JDBC)
596 .setTitle("PostGIS")
597 .setJdbcConnection(
598 new JDBCConnectionProperties()
599 .dbtype(JDBCConnectionProperties.DbtypeEnum.POSTGIS)
600 .host(connectToSpatialDbsAtLocalhost ? "127.0.0.1" : "postgis")
601 .port(connectToSpatialDbsAtLocalhost ? 54322 : 5432)
602 .database("geodata")
603 .schema("public")
604 .additionalProperties(
605 Map.of("connectionOptions", "?ApplicationName=tailormap-api")))
606 .setAuthentication(
607 new ServiceAuthentication()
608 .method(ServiceAuthentication.MethodEnum.PASSWORD)
609 .username("geodata")
610 .password(geodataPassword)),
611 "postgis_osm",
612 new TMFeatureSource()
613 .setProtocol(TMFeatureSource.Protocol.JDBC)
614 .setTitle("PostGIS OSM")
615 .setJdbcConnection(
616 new JDBCConnectionProperties()
617 .dbtype(JDBCConnectionProperties.DbtypeEnum.POSTGIS)
618 .host(connectToSpatialDbsAtLocalhost ? "127.0.0.1" : "postgis")
619 .port(connectToSpatialDbsAtLocalhost ? 54322 : 5432)
620 .database("geodata")
621 .schema("osm")
622 .additionalProperties(
623 Map.of("connectionOptions", "?ApplicationName=tailormap-api")))
624 .setAuthentication(
625 new ServiceAuthentication()
626 .method(ServiceAuthentication.MethodEnum.PASSWORD)
627 .username("geodata")
628 .password(geodataPassword)),
629 "oracle",
630 new TMFeatureSource()
631 .setProtocol(TMFeatureSource.Protocol.JDBC)
632 .setTitle("Oracle")
633 .setJdbcConnection(
634 new JDBCConnectionProperties()
635 .dbtype(JDBCConnectionProperties.DbtypeEnum.ORACLE)
636 .host(connectToSpatialDbsAtLocalhost ? "127.0.0.1" : "oracle")
637 .database("/FREEPDB1")
638 .schema("GEODATA")
639 .additionalProperties(
640 Map.of("connectionOptions", "?oracle.jdbc.J2EE13Compliant=true")))
641 .setAuthentication(
642 new ServiceAuthentication()
643 .method(ServiceAuthentication.MethodEnum.PASSWORD)
644 .username("geodata")
645 .password(geodataPassword)),
646 "sqlserver",
647 new TMFeatureSource()
648 .setProtocol(TMFeatureSource.Protocol.JDBC)
649 .setTitle("MS SQL Server")
650 .setJdbcConnection(
651 new JDBCConnectionProperties()
652 .dbtype(JDBCConnectionProperties.DbtypeEnum.SQLSERVER)
653 .host(connectToSpatialDbsAtLocalhost ? "127.0.0.1" : "sqlserver")
654 .database("geodata")
655 .schema("dbo")
656 .additionalProperties(Map.of("connectionOptions", ";encrypt=false")))
657 .setAuthentication(
658 new ServiceAuthentication()
659 .method(ServiceAuthentication.MethodEnum.PASSWORD)
660 .username("geodata")
661 .password(geodataPassword)),
662 "pdok-kadaster-bestuurlijkegebieden",
663 new TMFeatureSource()
664 .setProtocol(TMFeatureSource.Protocol.WFS)
665 .setUrl(
666 "https://service.pdok.nl/kadaster/bestuurlijkegebieden/wfs/v1_0?VERSION=2.0.0")
667 .setTitle("Bestuurlijke gebieden")
668 .setNotes(
669 "Overzicht van de bestuurlijke indeling van Nederland in gemeenten en provincies alsmede de rijksgrens. Gegevens zijn afgeleid uit de Basisregistratie Kadaster (BRK)."));
670 featureSourceRepository.saveAll(featureSources.values());
671
672 new WFSFeatureSourceHelper()
673 .loadCapabilities(featureSources.get("pdok-kadaster-bestuurlijkegebieden"));
674 geoServiceRepository
675 .findById("pdok-kadaster-bestuurlijkegebieden")
676 .ifPresent(
677 geoService -> {
678 geoService
679 .getSettings()
680 .getLayerSettings()
681 .put(
682 "Provinciegebied",
683 new GeoServiceLayerSettings()
684 .description(
685 "The administrative boundary of Dutch Provinces, connected to a WFS.")
686 .featureType(
687 new FeatureTypeRef()
688 .featureSourceId(
689 featureSources
690 .get("pdok-kadaster-bestuurlijkegebieden")
691 .getId())
692 .featureTypeName("bestuurlijkegebieden:Provinciegebied"))
693 .title("Provinciegebied (WFS)"));
694 geoServiceRepository.save(geoService);
695 });
696
697 geoServiceRepository
698 .findById("bestuurlijkegebieden-proxied")
699 .ifPresent(
700 geoService -> {
701 geoService
702 .getSettings()
703 .getLayerSettings()
704 .put(
705 "Provinciegebied",
706 new GeoServiceLayerSettings()
707 .featureType(
708 new FeatureTypeRef()
709 .featureSourceId(
710 featureSources
711 .get("pdok-kadaster-bestuurlijkegebieden")
712 .getId())
713 .featureTypeName("bestuurlijkegebieden:Provinciegebied"))
714 .title("Provinciegebied (WFS, proxied met auth)"));
715 geoServiceRepository.save(geoService);
716 });
717
718 CatalogNode featureSourceCatalogNode =
719 new CatalogNode().id("feature_sources").title("Test feature sources");
720 rootCatalogNode.addChildrenItem(featureSourceCatalogNode.getId());
721 catalog.getNodes().add(featureSourceCatalogNode);
722
723 for (TMFeatureSource featureSource : featureSources.values()) {
724 featureSourceCatalogNode.addItemsItem(
725 new TailormapObjectRef()
726 .kind(TailormapObjectRef.KindEnum.FEATURE_SOURCE)
727 .id(featureSource.getId().toString()));
728 }
729 catalogRepository.save(catalog);
730
731 if (connectToSpatialDbs) {
732 featureSources
733 .values()
734 .forEach(
735 fs -> {
736 try {
737 if (fs.getProtocol() == TMFeatureSource.Protocol.JDBC) {
738 new JDBCFeatureSourceHelper().loadCapabilities(fs);
739 } else if (fs.getProtocol() == TMFeatureSource.Protocol.WFS) {
740 new WFSFeatureSourceHelper().loadCapabilities(fs);
741 }
742 } catch (Exception e) {
743 logger.error(
744 "Error loading capabilities for feature source {}", fs.getTitle(), e);
745 }
746 });
747
748 services.stream()
749
750
751 .filter(s -> s.getId().startsWith("snapshot-geoserver"))
752 .forEach(
753 s ->
754 s.getSettings()
755 .layerSettings(
756 Map.of(
757 "postgis:begroeidterreindeel",
758 new GeoServiceLayerSettings()
759 .description(
760 """
761 This layer shows data from https:
762
763 https:
764 .featureType(
765 new FeatureTypeRef()
766 .featureSourceId(featureSources.get("postgis").getId())
767 .featureTypeName("begroeidterreindeel")),
768 "sqlserver:wegdeel",
769 new GeoServiceLayerSettings()
770 .attribution(
771 "CC BY 4.0 [BGT/Kadaster](https://www.nationaalgeoregister.nl/geonetwork/srv/api/records/2cb4769c-b56e-48fa-8685-c48f61b9a319)")
772 .description(
773 """
774 This layer shows data from [MS SQL Server](https:
775
776 https:
777 .featureType(
778 new FeatureTypeRef()
779 .featureSourceId(featureSources.get("sqlserver").getId())
780 .featureTypeName("wegdeel")),
781 "oracle:WATERDEEL",
782 new GeoServiceLayerSettings()
783 .description("This layer shows data from Oracle Spatial.")
784 .featureType(
785 new FeatureTypeRef()
786 .featureSourceId(featureSources.get("oracle").getId())
787 .featureTypeName("WATERDEEL")),
788 "postgis:osm_polygon",
789 new GeoServiceLayerSettings()
790 .description("This layer shows OSM data from postgis.")
791 .featureType(
792 new FeatureTypeRef()
793 .featureSourceId(
794 featureSources.get("postgis_osm").getId())
795 .featureTypeName("osm_polygon")))));
796 }
797
798 featureSources.get("pdok-kadaster-bestuurlijkegebieden").getFeatureTypes().stream()
799 .filter(ft -> ft.getName().equals("bestuurlijkegebieden:Provinciegebied"))
800 .findFirst()
801 .ifPresent(
802 ft -> {
803 ft.getSettings().addHideAttributesItem("identificatie");
804 ft.getSettings().addHideAttributesItem("ligtInLandCode");
805 ft.getSettings().addHideAttributesItem("fuuid");
806 ft.getSettings()
807 .putAttributeSettingsItem("naam", new AttributeSettings().title("Naam"));
808 ft.getSettings()
809 .setTemplate(
810 new FeatureTypeTemplate()
811 .templateLanguage("simple")
812 .markupLanguage("markdown")
813 .template(
814 """
815 ### Provincie
816 Deze provincie heet **{{naam}}** en ligt in _{{ligtInLandNaam}}_.
817
818 | Attribuut | Waarde |
819 | --------- | ------------------ |
820 | `code` | {{code}} |
821 | `naam` | {{naam}} |
822 | `ligt in` | {{ligtInLandNaam}} |"""));
823 });
824
825 featureSources.get("postgis").getFeatureTypes().stream()
826 .filter(ft -> ft.getName().equals("begroeidterreindeel"))
827 .findFirst()
828 .ifPresent(
829 ft -> {
830 ft.getSettings().addHideAttributesItem("terminationdate");
831 ft.getSettings().addHideAttributesItem("geom_kruinlijn");
832 ft.getSettings()
833 .putAttributeSettingsItem("gmlid", new AttributeSettings().title("GML ID"));
834 ft.getSettings()
835 .putAttributeSettingsItem(
836 "identificatie", new AttributeSettings().title("Identificatie"));
837 ft.getSettings()
838 .putAttributeSettingsItem(
839 "tijdstipregistratie", new AttributeSettings().title("Registratie"));
840 ft.getSettings()
841 .putAttributeSettingsItem(
842 "eindregistratie", new AttributeSettings().title("Eind registratie"));
843 ft.getSettings()
844 .putAttributeSettingsItem("class", new AttributeSettings().title("Klasse"));
845 ft.getSettings()
846 .putAttributeSettingsItem(
847 "bronhouder", new AttributeSettings().title("Bronhouder"));
848 ft.getSettings()
849 .putAttributeSettingsItem(
850 "inonderzoek", new AttributeSettings().title("In onderzoek"));
851 ft.getSettings()
852 .putAttributeSettingsItem(
853 "relatievehoogteligging",
854 new AttributeSettings().title("Relatieve hoogteligging"));
855 ft.getSettings()
856 .putAttributeSettingsItem(
857 "bgt_status", new AttributeSettings().title("BGT status"));
858 ft.getSettings()
859 .putAttributeSettingsItem(
860 "plus_status", new AttributeSettings().title("Plus-status"));
861 ft.getSettings()
862 .putAttributeSettingsItem(
863 "plus_fysiekvoorkomen",
864 new AttributeSettings().title("Plus-fysiek voorkomen"));
865 ft.getSettings()
866 .putAttributeSettingsItem(
867 "begroeidterreindeeloptalud", new AttributeSettings().title("Op talud"));
868 ft.getSettings().addAttributeOrderItem("identificatie");
869 ft.getSettings().addAttributeOrderItem("bronhouder");
870 ft.getSettings().addAttributeOrderItem("class");
871 });
872
873 Upload logo =
874 new Upload()
875 .setCategory(Upload.CATEGORY_APP_LOGO)
876 .setFilename("gradient.svg")
877 .setMimeType("image/svg+xml")
878 .setContent(new ClassPathResource("test/gradient-logo.svg").getContentAsByteArray())
879 .setLastModified(OffsetDateTime.now(ZoneId.systemDefault()));
880 uploadRepository.save(logo);
881
882 List<AppTreeNode> baseNodes =
883 List.of(
884 new AppTreeLayerNode()
885 .objectType("AppTreeLayerNode")
886 .id("lyr:openbasiskaart:osm")
887 .serviceId("openbasiskaart")
888 .layerName("osm")
889 .visible(true),
890 new AppTreeLayerNode()
891 .objectType("AppTreeLayerNode")
892 .id("lyr:pdok-hwh-luchtfotorgb:Actueel_orthoHR")
893 .serviceId("pdok-hwh-luchtfotorgb")
894 .layerName("Actueel_orthoHR")
895 .visible(false));
896
897 Application app =
898 new Application()
899 .setName("default")
900 .setTitle("Tailormap demo")
901 .setCrs("EPSG:28992")
902 .setAuthorizationRules(rule)
903 .setComponents(
904 List.of(
905 new Component().type("EDIT").config(new ComponentConfig().enabled(true)),
906 new Component()
907 .type("COORDINATE_LINK_WINDOW")
908 .config(
909 new ComponentConfig()
910 .enabled(true)
911 .putAdditionalProperty(
912 "urls",
913 List.of(
914 Map.of(
915 "id",
916 "google-maps",
917 "url",
918 "https://www.google.com/maps/@[lat],[lon],18z",
919 "alias",
920 "Google Maps",
921 "projection",
922 "EPSG:4326"),
923 Map.of(
924 "id",
925 "tm-demo",
926 "url",
927 "https://demo.tailormap.com/#@[X],[Y],18",
928 "alias",
929 "Tailormap demo",
930 "projection",
931 "EPSG:28992"))))))
932 .setContentRoot(
933 new AppContent()
934 .addBaseLayerNodesItem(
935 new AppTreeLevelNode()
936 .objectType("AppTreeLevelNode")
937 .id("root-base-layers")
938 .root(true)
939 .title("Base layers")
940 .childrenIds(
941 List.of(
942 "lyr:openbasiskaart:osm",
943 "lyr:pdok-hwh-luchtfotorgb:Actueel_orthoHR",
944 "lyr:openbasiskaart-proxied:osm",
945 "lyr:openbasiskaart-tms:xyz",
946 "lyr:b3p-mapproxy-luchtfoto:xyz")))
947 .addBaseLayerNodesItem(
948
949
950 new AppTreeLayerNode()
951 .objectType("AppTreeLayerNode")
952 .id("lyr:openbasiskaart-proxied:osm")
953 .serviceId("openbasiskaart-proxied")
954 .layerName("osm")
955 .visible(false))
956 .addBaseLayerNodesItem(
957 new AppTreeLayerNode()
958 .objectType("AppTreeLayerNode")
959 .id("lyr:openbasiskaart-tms:xyz")
960 .serviceId("openbasiskaart-tms")
961 .layerName("xyz")
962 .visible(false))
963 .addBaseLayerNodesItem(
964 new AppTreeLayerNode()
965 .objectType("AppTreeLayerNode")
966 .id("lyr:b3p-mapproxy-luchtfoto:xyz")
967 .serviceId("b3p-mapproxy-luchtfoto")
968 .layerName("xyz")
969 .visible(false))
970 .addLayerNodesItem(
971 new AppTreeLevelNode()
972 .objectType("AppTreeLevelNode")
973 .id("root")
974 .root(true)
975 .title("Layers")
976 .childrenIds(
977 List.of(
978 "lyr:pdok-kadaster-bestuurlijkegebieden:Provinciegebied",
979 "lyr:bestuurlijkegebieden-proxied:Provinciegebied",
980 "lyr:pdok-kadaster-bestuurlijkegebieden:Gemeentegebied",
981 "lyr:snapshot-geoserver:postgis:begroeidterreindeel",
982 "lyr:snapshot-geoserver:sqlserver:wegdeel",
983 "lyr:snapshot-geoserver:oracle:WATERDEEL",
984 "lyr:snapshot-geoserver:BGT",
985 "lvl:proxied",
986 "lvl:osm",
987 "lvl:archeo")))
988 .addLayerNodesItem(
989 new AppTreeLayerNode()
990 .objectType("AppTreeLayerNode")
991 .id("lyr:pdok-kadaster-bestuurlijkegebieden:Provinciegebied")
992 .serviceId("pdok-kadaster-bestuurlijkegebieden")
993 .layerName("Provinciegebied")
994 .visible(true))
995
996
997
998 .addLayerNodesItem(
999 new AppTreeLayerNode()
1000 .objectType("AppTreeLayerNode")
1001 .id("lyr:bestuurlijkegebieden-proxied:Provinciegebied")
1002 .serviceId("bestuurlijkegebieden-proxied")
1003 .layerName("Provinciegebied")
1004 .visible(false))
1005 .addLayerNodesItem(
1006 new AppTreeLayerNode()
1007 .objectType("AppTreeLayerNode")
1008 .id("lyr:pdok-kadaster-bestuurlijkegebieden:Gemeentegebied")
1009 .serviceId("pdok-kadaster-bestuurlijkegebieden")
1010 .layerName("Gemeentegebied")
1011 .visible(true))
1012 .addLayerNodesItem(
1013 new AppTreeLayerNode()
1014 .objectType("AppTreeLayerNode")
1015 .id("lyr:snapshot-geoserver:postgis:begroeidterreindeel")
1016 .serviceId("snapshot-geoserver")
1017 .layerName("postgis:begroeidterreindeel")
1018 .visible(true))
1019 .addLayerNodesItem(
1020 new AppTreeLayerNode()
1021 .objectType("AppTreeLayerNode")
1022 .id("lyr:snapshot-geoserver:sqlserver:wegdeel")
1023 .serviceId("snapshot-geoserver")
1024 .layerName("sqlserver:wegdeel")
1025 .visible(true))
1026 .addLayerNodesItem(
1027 new AppTreeLayerNode()
1028 .objectType("AppTreeLayerNode")
1029 .id("lyr:snapshot-geoserver:oracle:WATERDEEL")
1030 .serviceId("snapshot-geoserver")
1031 .layerName("oracle:WATERDEEL")
1032 .visible(true))
1033 .addLayerNodesItem(
1034 new AppTreeLayerNode()
1035 .objectType("AppTreeLayerNode")
1036 .id("lyr:snapshot-geoserver:BGT")
1037 .serviceId("snapshot-geoserver")
1038 .layerName("BGT")
1039 .visible(false))
1040 .addLayerNodesItem(
1041 new AppTreeLevelNode()
1042 .objectType("AppTreeLevelNode")
1043 .id("lvl:proxied")
1044 .title("Proxied")
1045 .childrenIds(
1046 List.of(
1047 "lyr:snapshot-geoserver-proxied:postgis:begroeidterreindeel")))
1048 .addLayerNodesItem(
1049 new AppTreeLayerNode()
1050 .objectType("AppTreeLayerNode")
1051 .id("lyr:snapshot-geoserver-proxied:postgis:begroeidterreindeel")
1052 .serviceId("snapshot-geoserver-proxied")
1053 .layerName("postgis:begroeidterreindeel")
1054 .visible(false))
1055 .addLayerNodesItem(
1056 new AppTreeLevelNode()
1057 .objectType("AppTreeLevelNode")
1058 .id("lvl:osm")
1059 .title("OSM")
1060 .childrenIds(List.of("lyr:snapshot-geoserver:postgis:osm_polygon")))
1061 .addLayerNodesItem(
1062 new AppTreeLayerNode()
1063 .objectType("AppTreeLayerNode")
1064 .id("lyr:snapshot-geoserver:postgis:osm_polygon")
1065 .serviceId("snapshot-geoserver")
1066 .layerName("postgis:osm_polygon")
1067 .visible(false))
1068 .addLayerNodesItem(
1069 new AppTreeLevelNode()
1070 .objectType("AppTreeLevelNode")
1071 .id("lvl:archeo")
1072 .title("Archeology")
1073 .childrenIds(List.of("lyr:demo:geomorfologie")))
1074 .addLayerNodesItem(
1075 new AppTreeLayerNode()
1076 .objectType("AppTreeLayerNode")
1077 .id("lyr:demo:geomorfologie")
1078 .serviceId("demo")
1079 .layerName("geomorfologie")
1080 .visible(true)))
1081 .setStyling(new AppStyling().logo(logo.getId().toString()))
1082 .setSettings(
1083 new AppSettings()
1084 .putLayerSettingsItem(
1085 "lyr:openbasiskaart:osm", new AppLayerSettings().title("Openbasiskaart"))
1086 .putLayerSettingsItem(
1087 "lyr:pdok-hwh-luchtfotorgb:Actueel_orthoHR",
1088 new AppLayerSettings().title("Luchtfoto"))
1089 .putLayerSettingsItem(
1090 "lyr:openbasiskaart-proxied:osm",
1091 new AppLayerSettings().title("Openbasiskaart (proxied)"))
1092 .putLayerSettingsItem(
1093 "lyr:snapshot-geoserver:oracle:WATERDEEL",
1094 new AppLayerSettings()
1095 .opacity(50)
1096 .title("Waterdeel overridden title")
1097 .editable(true)
1098 .description(
1099 "This is the layer description from the app layer setting.")
1100 .attribution(
1101 "CC BY 4.0 [BGT/Kadaster](https://www.nationaalgeoregister.nl/geonetwork/srv/api/records/2cb4769c-b56e-48fa-8685-c48f61b9a319)"))
1102 .putLayerSettingsItem(
1103 "lyr:snapshot-geoserver:postgis:osm_polygon",
1104 new AppLayerSettings()
1105 .description("OpenStreetMap polygon data in EPSG:3857")
1106 .opacity(60)
1107 .editable(true)
1108 .title("OSM Polygon (EPSG:3857)")
1109 .attribution(
1110 "© [OpenStreetMap](https://www.openstreetmap.org/copyright) contributors"))
1111 .putLayerSettingsItem(
1112 "lyr:snapshot-geoserver:postgis:begroeidterreindeel",
1113 new AppLayerSettings()
1114 .editable(true)
1115 .addHideAttributesItem("begroeidterreindeeloptalud")
1116 .addReadOnlyAttributesItem("eindregistratie"))
1117 .putLayerSettingsItem(
1118 "lyr:snapshot-geoserver:sqlserver:wegdeel",
1119 new AppLayerSettings().editable(true))
1120 .putLayerSettingsItem(
1121 "lyr:snapshot-geoserver-proxied:postgis:begroeidterreindeel",
1122 new AppLayerSettings().editable(false)));
1123
1124 app.getContentRoot().getBaseLayerNodes().addAll(baseNodes);
1125 app.setInitialExtent(new Bounds().minx(130011d).miny(458031d).maxx(132703d).maxy(459995d));
1126 app.setMaxExtent(new Bounds().minx(-285401d).miny(22598d).maxx(595401d).maxy(903401d));
1127
1128 if (map5url != null) {
1129 AppTreeLevelNode root = (AppTreeLevelNode) app.getContentRoot().getBaseLayerNodes().get(0);
1130 List<String> childrenIds = new ArrayList<>(root.getChildrenIds());
1131 childrenIds.add("lyr:map5:map5topo");
1132 childrenIds.add("lyr:map5:map5topo_simple");
1133 childrenIds.add("lvl:luchtfoto-labels");
1134 root.setChildrenIds(childrenIds);
1135 app.getSettings()
1136 .putLayerSettingsItem("lyr:map5:map5topo", new AppLayerSettings().title("Map5"))
1137 .putLayerSettingsItem(
1138 "lyr:map5:map5topo_simple", new AppLayerSettings().title("Map5 simple"));
1139 app.getContentRoot()
1140 .addBaseLayerNodesItem(
1141 new AppTreeLayerNode()
1142 .objectType("AppTreeLayerNode")
1143 .id("lyr:map5:map5topo")
1144 .serviceId("map5")
1145 .layerName("map5topo")
1146 .visible(false))
1147 .addBaseLayerNodesItem(
1148 new AppTreeLayerNode()
1149 .objectType("AppTreeLayerNode")
1150 .id("lyr:map5:map5topo_simple")
1151 .serviceId("map5")
1152 .layerName("map5topo_simple")
1153 .visible(false))
1154 .addBaseLayerNodesItem(
1155 new AppTreeLevelNode()
1156 .objectType("AppTreeLevelNode")
1157 .id("lvl:luchtfoto-labels")
1158 .title("Luchtfoto met labels")
1159 .addChildrenIdsItem("lyr:map5:luforoadslabels")
1160 .addChildrenIdsItem("lyr:pdok-hwh-luchtfotorgb:Actueel_orthoHR2"))
1161 .addBaseLayerNodesItem(
1162 new AppTreeLayerNode()
1163 .objectType("AppTreeLayerNode")
1164 .id("lyr:map5:luforoadslabels")
1165 .serviceId("map5")
1166 .layerName("luforoadslabels")
1167 .visible(false))
1168 .addBaseLayerNodesItem(
1169 new AppTreeLayerNode()
1170 .objectType("AppTreeLayerNode")
1171 .id("lyr:pdok-hwh-luchtfotorgb:Actueel_orthoHR2")
1172 .serviceId("pdok-hwh-luchtfotorgb")
1173 .layerName("Actueel_orthoHR")
1174 .visible(false));
1175 }
1176
1177 applicationRepository.save(app);
1178
1179 app =
1180 new Application()
1181 .setName("base")
1182 .setTitle("Service base app")
1183 .setCrs("EPSG:28992")
1184 .setAuthorizationRules(rule)
1185 .setContentRoot(
1186 new AppContent()
1187 .addBaseLayerNodesItem(
1188 new AppTreeLevelNode()
1189 .objectType("AppTreeLevelNode")
1190 .id("root-base-layers")
1191 .root(true)
1192 .title("Base layers")
1193 .childrenIds(
1194 List.of(
1195 "lyr:openbasiskaart:osm",
1196 "lyr:pdok-hwh-luchtfotorgb:Actueel_orthoHR"))));
1197 app.getContentRoot().getBaseLayerNodes().addAll(baseNodes);
1198 applicationRepository.save(app);
1199
1200 app =
1201 new Application()
1202 .setName("secured")
1203 .setTitle("secured app")
1204 .setCrs("EPSG:28992")
1205 .setAuthorizationRules(ruleLoggedIn)
1206 .setContentRoot(
1207 new AppContent()
1208 .addBaseLayerNodesItem(
1209 new AppTreeLevelNode()
1210 .objectType("AppTreeLevelNode")
1211 .id("root-base-layers")
1212 .root(true)
1213 .title("Base layers")
1214 .childrenIds(
1215 List.of(
1216 "lyr:openbasiskaart:osm",
1217 "lyr:pdok-hwh-luchtfotorgb:Actueel_orthoHR",
1218 "lyr:openbasiskaart-proxied:osm")))
1219 .addBaseLayerNodesItem(
1220 new AppTreeLayerNode()
1221 .objectType("AppTreeLayerNode")
1222 .id("lyr:openbasiskaart-proxied:osm")
1223 .serviceId("openbasiskaart-proxied")
1224 .layerName("osm")
1225 .visible(false))
1226 .addLayerNodesItem(
1227 new AppTreeLevelNode()
1228 .objectType("AppTreeLevelNode")
1229 .id("root")
1230 .root(true)
1231 .title("Layers")
1232 .childrenIds(
1233 List.of(
1234 "lyr:pdok-kadaster-bestuurlijkegebieden:Provinciegebied",
1235 "lyr:pdok-kadaster-bestuurlijkegebieden:Gemeentegebied",
1236 "lvl:proxied")))
1237 .addLayerNodesItem(
1238 new AppTreeLayerNode()
1239 .objectType("AppTreeLayerNode")
1240 .id("lyr:pdok-kadaster-bestuurlijkegebieden:Gemeentegebied")
1241 .serviceId("pdok-kadaster-bestuurlijkegebieden")
1242 .layerName("Gemeentegebied")
1243 .visible(true))
1244 .addLayerNodesItem(
1245 new AppTreeLayerNode()
1246 .objectType("AppTreeLayerNode")
1247 .id("lyr:pdok-kadaster-bestuurlijkegebieden:Provinciegebied")
1248 .serviceId("pdok-kadaster-bestuurlijkegebieden")
1249 .layerName("Provinciegebied")
1250 .visible(false))
1251 .addLayerNodesItem(
1252 new AppTreeLevelNode()
1253 .objectType("AppTreeLevelNode")
1254 .id("lvl:proxied")
1255 .title("Proxied")
1256 .childrenIds(
1257 List.of(
1258 "lyr:snapshot-geoserver-proxied:postgis:begroeidterreindeel")))
1259 .addLayerNodesItem(
1260 new AppTreeLayerNode()
1261 .objectType("AppTreeLayerNode")
1262 .id("lyr:snapshot-geoserver-proxied:postgis:begroeidterreindeel")
1263 .serviceId("snapshot-geoserver-proxied")
1264 .layerName("postgis:begroeidterreindeel")
1265 .visible(false)))
1266 .setSettings(
1267 new AppSettings()
1268 .putLayerSettingsItem(
1269 "lyr:openbasiskaart-proxied:osm",
1270 new AppLayerSettings().title("Openbasiskaart (proxied)")));
1271
1272 app.getContentRoot().getBaseLayerNodes().addAll(baseNodes);
1273 applicationRepository.save(app);
1274
1275 app =
1276 new Application()
1277 .setName("secured-auth")
1278 .setTitle("secured (with authorizations)")
1279 .setCrs("EPSG:28992")
1280 .setAuthorizationRules(
1281 List.of(
1282 new AuthorizationRule()
1283 .groupName("test-foo")
1284 .decisions(Map.of(ACCESS_TYPE_READ, AuthorizationRuleDecision.ALLOW)),
1285 new AuthorizationRule()
1286 .groupName("test-bar")
1287 .decisions(Map.of(ACCESS_TYPE_READ, AuthorizationRuleDecision.ALLOW))))
1288 .setContentRoot(
1289 new AppContent()
1290 .addLayerNodesItem(
1291 new AppTreeLevelNode()
1292 .objectType("AppTreeLevelNode")
1293 .id("root")
1294 .root(true)
1295 .title("Layers")
1296 .childrenIds(List.of("lyr:needs-auth", "lyr:public")))
1297 .addLayerNodesItem(
1298 new AppTreeLevelNode()
1299 .objectType("AppTreeLevelNode")
1300 .id("lvl:public")
1301 .title("Public")
1302 .childrenIds(List.of("lyr:snapshot-geoserver:BGT")))
1303 .addLayerNodesItem(
1304 new AppTreeLevelNode()
1305 .objectType("AppTreeLevelNode")
1306 .id("lvl:needs-auth")
1307 .title("Needs auth")
1308 .childrenIds(
1309 List.of(
1310 "lyr:filtered-snapshot-geoserver:BGT",
1311 "lyr:filtered-snapshot-geoserver:postgis:begroeidterreindeel")))
1312 .addLayerNodesItem(
1313 new AppTreeLayerNode()
1314 .objectType("AppTreeLayerNode")
1315 .id("lyr:filtered-snapshot-geoserver:BGT")
1316 .serviceId("filtered-snapshot-geoserver")
1317 .layerName("BGT")
1318 .visible(true))
1319 .addLayerNodesItem(
1320 new AppTreeLayerNode()
1321 .objectType("AppTreeLayerNode")
1322 .id("lyr:filtered-snapshot-geoserver:postgis:begroeidterreindeel")
1323 .serviceId("filtered-snapshot-geoserver")
1324 .layerName("postgis:begroeidterreindeel")
1325 .visible(true))
1326 .addLayerNodesItem(
1327 new AppTreeLayerNode()
1328 .objectType("AppTreeLayerNode")
1329 .id("lyr:snapshot-geoserver:BGT")
1330 .serviceId("snapshot-geoserver")
1331 .layerName("BGT")
1332 .visible(true)));
1333
1334 applicationRepository.save(app);
1335
1336 app =
1337 new Application()
1338 .setName("austria")
1339 .setCrs("EPSG:3857")
1340 .setAuthorizationRules(rule)
1341 .setTitle("Austria")
1342 .setInitialExtent(
1343 new Bounds().minx(987982d).miny(5799551d).maxx(1963423d).maxy(6320708d))
1344 .setMaxExtent(new Bounds().minx(206516d).miny(5095461d).maxx(3146930d).maxy(7096232d))
1345 .setContentRoot(
1346 new AppContent()
1347 .addBaseLayerNodesItem(
1348 new AppTreeLevelNode()
1349 .objectType("AppTreeLevelNode")
1350 .id("root-base-layers")
1351 .root(true)
1352 .title("Base layers")
1353 .childrenIds(
1354 List.of(
1355 "lyr:at-basemap:geolandbasemap",
1356 "lyr:at-basemap:orthofoto",
1357 "lvl:orthofoto-labels",
1358 "lyr:osm:xyz")))
1359 .addBaseLayerNodesItem(
1360 new AppTreeLayerNode()
1361 .objectType("AppTreeLayerNode")
1362 .id("lyr:at-basemap:geolandbasemap")
1363 .serviceId("at-basemap")
1364 .layerName("geolandbasemap")
1365 .visible(true))
1366 .addBaseLayerNodesItem(
1367 new AppTreeLayerNode()
1368 .objectType("AppTreeLayerNode")
1369 .id("lyr:at-basemap:orthofoto")
1370 .serviceId("at-basemap")
1371 .layerName("bmaporthofoto30cm")
1372 .visible(false))
1373 .addBaseLayerNodesItem(
1374 new AppTreeLevelNode()
1375 .objectType("AppTreeLevelNode")
1376 .id("lvl:orthofoto-labels")
1377 .title("Orthophoto with labels")
1378 .childrenIds(
1379 List.of(
1380 "lyr:at-basemap:bmapoverlay", "lyr:at-basemap:orthofoto_2")))
1381 .addBaseLayerNodesItem(
1382 new AppTreeLayerNode()
1383 .objectType("AppTreeLayerNode")
1384 .id("lyr:at-basemap:bmapoverlay")
1385 .serviceId("at-basemap")
1386 .layerName("bmapoverlay")
1387 .visible(false))
1388 .addBaseLayerNodesItem(
1389 new AppTreeLayerNode()
1390 .objectType("AppTreeLayerNode")
1391 .id("lyr:at-basemap:orthofoto_2")
1392 .serviceId("at-basemap")
1393 .layerName("bmaporthofoto30cm")
1394 .visible(false))
1395 .addBaseLayerNodesItem(
1396 new AppTreeLayerNode()
1397 .objectType("AppTreeLayerNode")
1398 .id("lyr:osm:xyz")
1399 .serviceId("osm")
1400 .layerName("xyz")
1401 .visible(false)));
1402
1403 applicationRepository.save(app);
1404
1405 Configuration config = new Configuration();
1406 config.setKey(Configuration.DEFAULT_APP);
1407 config.setValue("default");
1408 configurationRepository.save(config);
1409 config = new Configuration();
1410 config.setKey(Configuration.DEFAULT_BASE_APP);
1411 config.setValue("base");
1412 configurationRepository.save(config);
1413
1414 config = new Configuration();
1415 config.setKey("test");
1416 config.setAvailableForViewer(true);
1417 config.setValue("test value");
1418 config.setJsonValue(
1419 new ObjectMapper().readTree("{ \"someProperty\": 1, \"nestedObject\": { \"num\": 42 } }"));
1420 configurationRepository.save(config);
1421
1422 logger.info("Test entities created");
1423 }
1424
1425 @Transactional
1426 public void createSolrIndex() throws Exception {
1427 if (connectToSpatialDbs) {
1428
1429
1430 featureSourceRepository.flush();
1431
1432 logger.info("Creating Solr index");
1433 @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
1434 final String solrUrl =
1435 "http://" + (connectToSpatialDbsAtLocalhost ? "127.0.0.1" : "solr") + ":8983/solr/";
1436 this.solrService.setSolrUrl(solrUrl);
1437 SolrHelper solrHelper = new SolrHelper(this.solrService.getSolrClientForIndexing());
1438 GeoService geoService = geoServiceRepository.findById("snapshot-geoserver").orElseThrow();
1439 Application defaultApp = applicationRepository.findByName("default");
1440
1441 TMFeatureType begroeidterreindeelFT =
1442 geoService.findFeatureTypeForLayer(
1443 geoService.findLayer("postgis:begroeidterreindeel"), featureSourceRepository);
1444
1445 TMFeatureType wegdeelFT =
1446 geoService.findFeatureTypeForLayer(
1447 geoService.findLayer("sqlserver:wegdeel"), featureSourceRepository);
1448
1449 try (solrHelper) {
1450
1451 SearchIndex begroeidterreindeelIndex = null;
1452 if (begroeidterreindeelFT != null) {
1453 begroeidterreindeelIndex =
1454 new SearchIndex()
1455 .setName("Begroeidterreindeel")
1456 .setFeatureTypeId(begroeidterreindeelFT.getId())
1457 .setSearchFieldsUsed(List.of("class", "plus_fysiekvoorkomen", "bronhouder"))
1458 .setSearchDisplayFieldsUsed(List.of("class", "plus_fysiekvoorkomen"));
1459 begroeidterreindeelIndex = searchIndexRepository.save(begroeidterreindeelIndex);
1460 solrHelper.addFeatureTypeIndex(
1461 begroeidterreindeelIndex, begroeidterreindeelFT, featureSourceFactoryHelper);
1462 begroeidterreindeelIndex = searchIndexRepository.save(begroeidterreindeelIndex);
1463 }
1464
1465 SearchIndex wegdeelIndex = null;
1466 if (wegdeelFT != null) {
1467 wegdeelIndex =
1468 new SearchIndex()
1469 .setName("Wegdeel")
1470 .setFeatureTypeId(wegdeelFT.getId())
1471 .setSearchFieldsUsed(
1472 List.of(
1473 "function_",
1474 "plus_fysiekvoorkomenwegdeel",
1475 "surfacematerial",
1476 "bronhouder"))
1477 .setSearchDisplayFieldsUsed(List.of("function_", "plus_fysiekvoorkomenwegdeel"));
1478 wegdeelIndex = searchIndexRepository.save(wegdeelIndex);
1479 solrHelper.addFeatureTypeIndex(wegdeelIndex, wegdeelFT, featureSourceFactoryHelper);
1480 wegdeelIndex = searchIndexRepository.save(wegdeelIndex);
1481 }
1482
1483 AppTreeLayerNode begroeidTerreindeelLayerNode =
1484 defaultApp
1485 .getAllAppTreeLayerNode()
1486 .filter(
1487 node ->
1488 node.getId().equals("lyr:snapshot-geoserver:postgis:begroeidterreindeel"))
1489 .findFirst()
1490 .orElse(null);
1491
1492 if (begroeidTerreindeelLayerNode != null && begroeidterreindeelIndex != null) {
1493 defaultApp
1494 .getAppLayerSettings(begroeidTerreindeelLayerNode)
1495 .setSearchIndexId(begroeidterreindeelIndex.getId());
1496 }
1497
1498 AppTreeLayerNode wegdeel =
1499 defaultApp
1500 .getAllAppTreeLayerNode()
1501 .filter(node -> node.getId().equals("lyr:snapshot-geoserver:sqlserver:wegdeel"))
1502 .findFirst()
1503 .orElse(null);
1504
1505 if (wegdeel != null && wegdeelIndex != null) {
1506 defaultApp.getAppLayerSettings(wegdeel).setSearchIndexId(wegdeelIndex.getId());
1507 }
1508
1509 applicationRepository.save(defaultApp);
1510 }
1511 }
1512 }
1513
1514 private void createPocTasks() {
1515 logger.info("Creating POC tasks");
1516 try {
1517 logger.info(
1518 "Created minutely task with key: {}",
1519 taskCreator.createTask(
1520 PocTask.class,
1521 new TMJobDataMap(
1522 Map.of(
1523 "type", TEST_TASK_TYPE,
1524 "foo", "bar",
1525 "description", "POC task that runs every minute")),
1526 "0 0/1 * 1/1 * ? *"));
1527 logger.info(
1528 "Created hourly task with key: {}",
1529 taskCreator.createTask(
1530 PocTask.class,
1531 new TMJobDataMap(
1532 Map.of(
1533 "type",
1534 TEST_TASK_TYPE,
1535 "foo",
1536 "bar",
1537 "description",
1538 "POC task that runs every hour",
1539 "priority",
1540 10)),
1541 "0 0 0/1 1/1 * ? *"));
1542 } catch (SchedulerException e) {
1543 logger.error("Error creating scheduling poc tasks", e);
1544 }
1545 }
1546 }