Skip to content
This repository has been archived by the owner on Mar 7, 2024. It is now read-only.

Feat/multiple ldes websocket #24

Merged
merged 37 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
4a1f34c
feat: zoom buttons styled + knowledgegraph set right
jobulcke Sep 27, 2023
c037bdd
feat: slider + buttons styled + global header + right fonts used + ma…
jobulcke Sep 28, 2023
212c4b9
feat: wrong placed scoped placed on a styling block
jobulcke Sep 28, 2023
4c35a42
feat: init of modals and checkboxtiles
jobulcke Oct 2, 2023
6cc6314
feat: z-stack bug fixed + checkboxtile finished
jobulcke Oct 2, 2023
cfd28a6
Feat: Add membercounter (#19)
WLefever-Cegeka Oct 2, 2023
f3b700d
fix: removal of member on map resolved + addition of styling of Membe…
jobulcke Oct 2, 2023
71b1815
Feat: Add linechart
Lefeverw Oct 2, 2023
8226a8a
Feat: minor
Lefeverw Oct 3, 2023
54e8a92
feat: polygon styling
jobulcke Oct 3, 2023
25e0ba3
feat: legend styled
jobulcke Oct 4, 2023
d98e495
feat: minor update IngestedMemberDto
Lefeverw Oct 4, 2023
acc14aa
feat: Add collection as field
Lefeverw Oct 4, 2023
7190389
feat: add collection to member
pj-cegeka Oct 4, 2023
29e203e
feat: add collection to in rectangle
pj-cegeka Oct 5, 2023
de2887c
feat: fix tests
pj-cegeka Oct 5, 2023
a6a59d5
WIP
Lefeverw Oct 4, 2023
4fc753d
WIP
Lefeverw Oct 5, 2023
29d7c47
WIP
Lefeverw Oct 5, 2023
691bdb0
custom code
Lefeverw Oct 5, 2023
d5c02b0
fix: set broken test to disabled
pj-cegeka Oct 5, 2023
5040705
custom code
Lefeverw Oct 5, 2023
b6bc44a
custom code
Lefeverw Oct 5, 2023
9bfa6dc
feat: markers styled with flanders icon + icon grows when clicked
jobulcke Oct 9, 2023
e5d79f6
fix: broken tests repaired
jobulcke Oct 9, 2023
3a63202
WIP: added logic to the checkbox tiles
jobulcke Oct 10, 2023
1043b3e
feat: layers are added/removed based on checkbox state
jobulcke Oct 10, 2023
01dc82d
chore: update page title and favicon
Yalz Oct 10, 2023
9f15568
WIP: custom icon for clusters
jobulcke Oct 10, 2023
36ea8f0
feat: cluster icons customized
jobulcke Oct 10, 2023
0603806
feat: zoom buttons styled + knowledgegraph set right
jobulcke Sep 27, 2023
427d4e5
temp
pj-cegeka Oct 5, 2023
ddcb15b
feat: unsubscribe websocket client on different ldes
pj-cegeka Oct 10, 2023
fb914ee
feat: add multiple stream logic for updates
pj-cegeka Oct 10, 2023
e3dc926
feat: add multiple stream logic for updates
pj-cegeka Oct 10, 2023
23177f9
feat: first attempt to dockerize
jobulcke Oct 10, 2023
989afc9
feat: fixes for dockerizing
jobulcke Oct 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
Expand Down Expand Up @@ -117,6 +121,11 @@
<artifactId>rdf4j-client</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.16.1</version>
</dependency>

<!-- TESTING -->
<dependency>
Expand Down Expand Up @@ -233,6 +242,7 @@
<directory>../frontend/target/dist</directory>
<includes>
<include>assets/</include>
<include>assets/svgs/</include>
<include>index.html</include>
<include>favicon.ico</include>
</includes>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@SpringBootApplication
public class Application {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@

@Configuration
public class EventStreamConfig {
private String name;
private String memberType;
private String timestampPath;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getMemberType() {
return memberType;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package be.informatievlaanderen.vsds.demonstrator.member.application.exceptions;

public class MembertypeException extends RuntimeException{
private final String membertype;
private final String member;

public MembertypeException(String membertype, String member) {
this.membertype = membertype;
this.member = member;
}

@Override
public String getMessage() {
return "Member " + member + " was not of expected type " + membertype;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package be.informatievlaanderen.vsds.demonstrator.member.application.exceptions;

public class MissingCollectionException extends RuntimeException{
private final String collectionName;

public MissingCollectionException(String collectionName) {
this.collectionName = collectionName;
}

@Override
public String getMessage() {
return "Eventstream with name " + collectionName + " could not be found.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import be.informatievlaanderen.vsds.demonstrator.member.application.valueobjects.IngestedMemberDto;
import be.informatievlaanderen.vsds.demonstrator.member.application.valueobjects.MemberDto;
import be.informatievlaanderen.vsds.demonstrator.member.rest.dtos.LineChartDto;
import org.locationtech.jts.geom.Geometry;

import java.time.LocalDateTime;
Expand All @@ -10,7 +11,12 @@
public interface MemberService {
void ingestMember(IngestedMemberDto ingestedMemberDto);

List<MemberDto> getMembersInRectangle(Geometry rectangleGeometry, LocalDateTime timestamp, String timePeriod);
List<MemberDto> getMembersInRectangle(Geometry rectangleGeometry, String collectionName, LocalDateTime timestamp, String timePeriod);

MemberDto getMemberById(String memberId);

long getNumberOfMembers();
long getNumberOfMembersByCollection(String collection);

LineChartDto getLineChartDtos();
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
package be.informatievlaanderen.vsds.demonstrator.member.application.services;

import be.informatievlaanderen.vsds.demonstrator.member.application.config.EventStreamConfig;
import be.informatievlaanderen.vsds.demonstrator.member.application.config.StreamsConfig;
import be.informatievlaanderen.vsds.demonstrator.member.application.exceptions.InvalidGeometryProvidedException;
import be.informatievlaanderen.vsds.demonstrator.member.application.exceptions.ResourceNotFoundException;
import be.informatievlaanderen.vsds.demonstrator.member.application.valueobjects.IngestedMemberDto;
import be.informatievlaanderen.vsds.demonstrator.member.application.valueobjects.MemberDto;
import be.informatievlaanderen.vsds.demonstrator.member.domain.member.valueobjects.Dataset;
import be.informatievlaanderen.vsds.demonstrator.member.domain.member.valueobjects.HourCount;
import be.informatievlaanderen.vsds.demonstrator.member.domain.member.valueobjects.LineChart;
import be.informatievlaanderen.vsds.demonstrator.member.domain.member.entities.Member;
import be.informatievlaanderen.vsds.demonstrator.member.domain.member.repositories.MemberRepository;
import be.informatievlaanderen.vsds.demonstrator.member.rest.MemberExceptionHandler;
import be.informatievlaanderen.vsds.demonstrator.member.rest.websocket.WebSocketConfig;
import be.informatievlaanderen.vsds.demonstrator.member.rest.dtos.LineChartDto;
import be.informatievlaanderen.vsds.demonstrator.member.rest.websocket.MessageController;
import org.locationtech.jts.geom.Geometry;
import org.opengis.referencing.operation.TransformException;
import org.opengis.util.FactoryException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.wololo.jts2geojson.GeoJSONWriter;
import be.informatievlaanderen.vsds.demonstrator.member.rest.websocket.MessageController;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.NoSuchElementException;

@Service
public class MemberServiceImpl implements MemberService {
Expand All @@ -41,9 +43,9 @@ public MemberServiceImpl(MemberRepository repository, StreamsConfig streams, Mes
@Override
public void ingestMember(IngestedMemberDto ingestedMemberDto) {
try {
Member member = ingestedMemberDto.getMemberGeometry(streams.getStreams());
Member member = ingestedMemberDto.getMember(streams.getStreams());
repository.saveMember(member);
messageController.send(new MemberDto(member.getMemberId(), geoJSONWriter.write(member.getGeometry()), member.getTimestamp()));
messageController.send(new MemberDto(member.getMemberId(), geoJSONWriter.write(member.getGeometry()), member.getTimestamp()), ingestedMemberDto.getCollection());

log.info("new member ingested");
} catch (FactoryException | TransformException e) {
Expand All @@ -52,9 +54,9 @@ public void ingestMember(IngestedMemberDto ingestedMemberDto) {
}

@Override
public List<MemberDto> getMembersInRectangle(Geometry rectangleGeometry, LocalDateTime timestamp, String timePeriod) {
public List<MemberDto> getMembersInRectangle(Geometry rectangleGeometry, String collectionName, LocalDateTime timestamp, String timePeriod) {
var duration = Duration.parse(timePeriod).dividedBy(2);
return repository.getMembersByGeometry(rectangleGeometry, timestamp.minus(duration), timestamp.plus(duration))
return repository.getMembersByGeometry(rectangleGeometry, collectionName, timestamp.minus(duration), timestamp.plus(duration))
.stream()
.map(memberGeometry -> new MemberDto(memberGeometry.getMemberId(), geoJSONWriter.write(memberGeometry.getGeometry()), memberGeometry.getTimestamp()))
.toList();
Expand All @@ -66,4 +68,33 @@ public MemberDto getMemberById(String memberId) {
.map(memberGeometry -> new MemberDto(memberGeometry.getMemberId(), geoJSONWriter.write(memberGeometry.getGeometry()), memberGeometry.getTimestamp()))
.orElseThrow(() -> new ResourceNotFoundException("Member", memberId));
}

@Override
public long getNumberOfMembers() {
return repository.getNumberOfMembers();
}

@Override
public long getNumberOfMembersByCollection(String collection) {
return repository.getNumberOfMembersByCollection(collection);
}

@Override
public LineChartDto getLineChartDtos() {
LocalDateTime startDate = LocalDateTime.now().minusDays(7);
LineChart lineChart = new LineChart(startDate);

streams
.getStreams()
.stream()
.map(EventStreamConfig::getName)
.map(collection -> {
long numberOfMembers = getNumberOfMembersByCollection(collection);

List<Member> membersAfterLocalDateTime = repository.findMembersByCollectionAfterLocalDateTime(collection,startDate);
return new Dataset(collection, numberOfMembers - membersAfterLocalDateTime.size(), new HourCount(membersAfterLocalDateTime));
}).forEach(lineChart::addDataSet);

return new LineChartDto(lineChart.getLabels(), lineChart.getDatasetDtos());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package be.informatievlaanderen.vsds.demonstrator.member.application.services;

import org.apache.jena.rdf.model.Model;

public interface MemberValidator {
void validate(Model member, String collectionName);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package be.informatievlaanderen.vsds.demonstrator.member.application.services;

import be.informatievlaanderen.vsds.demonstrator.member.application.config.EventStreamConfig;
import be.informatievlaanderen.vsds.demonstrator.member.application.config.StreamsConfig;
import be.informatievlaanderen.vsds.demonstrator.member.application.exceptions.MembertypeException;
import be.informatievlaanderen.vsds.demonstrator.member.application.exceptions.MissingCollectionException;
import org.apache.jena.rdf.model.Model;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.Optional;

@Service
public class MemberValidatorImpl implements MemberValidator {

private final StreamsConfig streams;

public MemberValidatorImpl(StreamsConfig streams) {
this.streams = streams;
}

@Override
public void validate(Model member, String collectionName) {
Optional<EventStreamConfig> streamConfig = streams.getStreams().stream().filter(streams -> Objects.equals(streams.getName(), collectionName)).findFirst();
if(streamConfig.isEmpty()) {
throw new MissingCollectionException(collectionName);
} else if (!testMembertype(member, streamConfig.get().getMemberType())) {
throw new MembertypeException("todo", streamConfig.get().getMemberType());
}

}

private boolean testMembertype(Model member, String memberType) {
//TODO
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,34 @@
import static org.apache.jena.rdf.model.ResourceFactory.createResource;

public class IngestedMemberDto {
private final String collection;
private final Model model;

public IngestedMemberDto(Model model) {
public IngestedMemberDto(String collection, Model model) {
this.collection = collection;
this.model = model;
}

public Model getModel() {
return model;
}

public Member getMemberGeometry(List<EventStreamConfig> streams) throws FactoryException, TransformException {
Geometry geometry = getMemberGeometry();
public Member getMember(List<EventStreamConfig> streams) throws FactoryException, TransformException {
Geometry geometry = getMember();
String memberId = getMemberId(streams);
String timestampString = (String) getTimestampPath(streams);
LocalDateTime timestamp;
if (timestampString.contains("Z")) {
if (timestampString.contains("Z") || timestampString.contains("+")) {
timestamp = ZonedDateTime.parse(timestampString).toLocalDateTime();
} else {
timestamp = LocalDateTime.parse(timestampString);
}
return new Member(memberId, geometry, timestamp);
return new Member(memberId, collection, geometry, timestamp);
}

private Geometry getMemberGeometry() throws FactoryException, TransformException {
private Geometry getMember() throws FactoryException, TransformException {
List<RDFNode> wktNodes = model.listObjectsOfProperty(model.createProperty("http://www.opengis.net/ont/geosparql#asWKT")).toList();
if(wktNodes.isEmpty()) {
if (wktNodes.isEmpty()) {
throw new NoGeometryProvidedException();
} else {
RDFNode wktObject = wktNodes.get(0);
Expand All @@ -58,6 +60,7 @@ private Geometry getMemberGeometry() throws FactoryException, TransformException
private Statement getMemberProperty(List<EventStreamConfig> streams, Function<EventStreamConfig, Selector> createSelector) {
return Iterables.getOnlyElement(streams
.stream()
.filter(stream -> stream.getName().equals(collection))
.map(stream -> model.listStatements(createSelector.apply(stream)))
.map(StmtIterator::nextStatement)
.toList());
Expand All @@ -75,4 +78,8 @@ private Object getTimestampPath(List<EventStreamConfig> streams) {
.asLiteral().getString();

}

public String getCollection() {
return collection;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package be.informatievlaanderen.vsds.demonstrator.member.custom;

import be.informatievlaanderen.vsds.demonstrator.member.application.valueobjects.IngestedMemberDto;
import jakarta.annotation.PostConstruct;
import org.apache.jena.datatypes.TypeMapper;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.Statement;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.apache.jena.rdf.model.ResourceFactory.*;

@Component
public class MeetPuntRepository {

private final Map<String, Statement> meetpuntLocaties;

public MeetPuntRepository() {
this.meetpuntLocaties = new HashMap<>();
}

@PostConstruct
private void initializeMeetpunten() {
final int size = 16 * 1024 * 1024;
final ExchangeStrategies strategies = ExchangeStrategies.builder()
.codecs(codecs -> codecs.defaultCodecs().maxInMemorySize(size))
.build();
String content = WebClient.builder().exchangeStrategies(strategies).baseUrl("http://miv.opendata.belfla.be/miv/configuratie/xml").build().get().retrieve()
.bodyToMono(String.class).block();
Document doc = Jsoup.parse(content, "", Parser.xmlParser());
for (Element e : doc.select("meetpunt")) {
String meetpuntId = e.attr("unieke_id");
String wkt = "POINT (" + e.select("lengtegraad_EPSG_4326").get(0).text().replace(",", ".") + " " + e.select("breedtegraad_EPSG_4326").get(0).text().replace(",", ".") + ")";

meetpuntLocaties.put(meetpuntId, createStatement(createResource("http://custom"), createProperty("http://www.opengis.net/ont/geosparql#asWKT"), createTypedLiteral(wkt, TypeMapper.getInstance().getTypeByName("http://www.opengis.net/ont/geosparql#wktLiteral"))));
}
}


public List<Statement> get(String s) {
return List.of(meetpuntLocaties.get(s));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@

public class Member {
private final String memberId;
private final String collection;
private final Geometry geometry;
private final LocalDateTime timestamp;

public Member(String memberId, Geometry geometry, LocalDateTime timestamp) {
public Member(String memberId, String collection, Geometry geometry, LocalDateTime timestamp) {
this.memberId = memberId;
this.collection = collection;
this.geometry = geometry;
this.timestamp = timestamp;
}
Expand All @@ -28,6 +30,10 @@ public LocalDateTime getTimestamp() {
return timestamp;
}

public String getCollection() {
return collection;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand All @@ -42,4 +48,5 @@ public boolean equals(Object o) {
public int hashCode() {
return memberId.hashCode();
}

}
Loading