Skip to content

Commit

Permalink
Merge branch 'Onlineberatung:develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
tkuzynow authored Sep 22, 2023
2 parents a1a4229 + b779e5d commit 0ef1c49
Show file tree
Hide file tree
Showing 28 changed files with 479 additions and 99 deletions.
62 changes: 61 additions & 1 deletion api/statisticsservice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ components:
enum:
- "ASSIGN_SESSION"
- "ARCHIVE_SESSION"
- "DELETE_ACCOUNT"
- "CREATE_MESSAGE"
- "START_VIDEO_CALL"
- "STOP_VIDEO_CALL"
Expand Down Expand Up @@ -165,7 +166,7 @@ components:
description: The id of the session
example: 12345

ArchiveSessionStatisticsEventMessage:
ArchiveOrDeleteSessionStatisticsEventMessage:
type: object
required:
- sessionId
Expand All @@ -188,6 +189,28 @@ components:
type: string
example: '2022-08-15T21:11:29'

DeleteAccountStatisticsEventMessage:
type: object
required:
- sessionId
- endDate
allOf:
- $ref: '#/components/schemas/StatisticsEventMessage'
- type: object
properties:
tenantId:
type: integer
format: int64
description: The id of the tenant
example: 1
userId:
type: string
description: The keycloak id of the consultant
example: d63f4cc0-215d-40e2-a866-2d3e910f0590
deleteDate:
type: string
example: '2022-08-15T21:11:29'

CreateMessageStatisticsEventMessage:
type: object
required:
Expand All @@ -205,6 +228,14 @@ components:
type: boolean
description: indicates whether the message has an attachment
example: true
receiverId:
type: string
description: receiving user id of the message (taken from session). Can be null for groupchat.
tenantId:
type: integer
format: int64
description: The id of the tenant
example: 1

StartVideoCallStatisticsEventMessage:
type: object
Expand All @@ -220,10 +251,17 @@ components:
format: int64
description: The id of the session
example: 12345
adviceSeekerId:
type: string
description: The id of the adviceseeker
videoCallUuid:
type: string
description: The uuid of the video call
example: 123e4567-e89b-12d3-a456-556642440000
tenantId:
type: integer
format: int64
description: The id of the tenant

StopVideoCallStatisticsEventMessage:
type: object
Expand Down Expand Up @@ -287,6 +325,9 @@ components:
agencyName:
type: string
example: "Dortmund Beratungstelle"
referer:
type: string
example: "referer"

RegistrationStatisticsListResponseDTO:
type: object
Expand Down Expand Up @@ -336,6 +377,19 @@ components:
agencyName:
type: string
example: "Dortmund Beratungstelle"
referer:
type: string
example: "referer"
appointmentsBookedCount:
type: integer
example: "4"
attendedVideoCallsCount:
type: integer
example: "6"
consultantMessagesCount:
type: integer
example: "72"
description: "Total number of messages sent by all consultants to this adviceseeker"

BookingCreatedStatisticsEventMessage:
type: object
Expand All @@ -355,6 +409,12 @@ components:
type: string
bookingId:
type: integer
adviceSeekerId:
type: string
tenantId:
type: integer
format: int64
description: The id of the tenant

BookingRescheduledStatisticsEventMessage:
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,26 @@
import static java.util.Objects.nonNull;

import de.caritas.cob.statisticsservice.api.model.RegistrationStatisticsResponseDTO;
import de.caritas.cob.statisticsservice.api.statistics.model.statisticsevent.StatisticEventsContainer;
import de.caritas.cob.statisticsservice.api.statistics.model.statisticsevent.StatisticsEvent;
import de.caritas.cob.statisticsservice.api.statistics.model.statisticsevent.meta.AdviceSeekerAwareMetaData;
import de.caritas.cob.statisticsservice.api.statistics.model.statisticsevent.meta.ArchiveMetaData;
import de.caritas.cob.statisticsservice.api.statistics.model.statisticsevent.meta.CreateMessageMetaData;
import de.caritas.cob.statisticsservice.api.statistics.model.statisticsevent.meta.DeleteAccountMetaData;
import de.caritas.cob.statisticsservice.api.statistics.model.statisticsevent.meta.RegistrationMetaData;
import java.util.List;
import java.util.Collection;
import java.util.Optional;
import org.springframework.stereotype.Component;

@Component
public class RegistrationStatisticsDTOConverter {

public RegistrationStatisticsResponseDTO convertStatisticsEvent(
StatisticsEvent rawEvent, List<StatisticsEvent> archiveSessionEvents) {
StatisticsEvent rawEvent, StatisticEventsContainer statisticEventsContainer) {
RegistrationMetaData metadata = (RegistrationMetaData) rawEvent.getMetaData();
String maxArchiveDate = findMaxArchiveDate(rawEvent.getSessionId(), statisticEventsContainer.getArchiveSessionEvents());
String deleteAccountDate = findDeleteAccountDate(rawEvent.getUser().getId(), statisticEventsContainer.getDeleteAccountEvents());

return new RegistrationStatisticsResponseDTO()
.userId(rawEvent.getUser().getId())
.registrationDate(metadata.getRegistrationDate())
Expand All @@ -27,11 +34,63 @@ public RegistrationStatisticsResponseDTO convertStatisticsEvent(
.counsellingRelation(metadata.getCounsellingRelation())
.mainTopicInternalAttribute(metadata.getMainTopicInternalAttribute())
.topicsInternalAttributes(metadata.getTopicsInternalAttributes())
.endDate(findEndDate(rawEvent.getSessionId(), archiveSessionEvents))
.postalCode(metadata.getPostalCode());
.endDate(getEndDate(maxArchiveDate, deleteAccountDate))
.postalCode(metadata.getPostalCode())
.referer(metadata.getReferer())
.attendedVideoCallsCount(
countEventsPerAdviceSeekerMatchingOnMetadata(rawEvent.getUser().getId(), statisticEventsContainer.getVideoCallStartedEvents()))
.appointmentsBookedCount(countEventsPerAdviceSeekerMatchingOnMetadata(rawEvent.getUser().getId(), statisticEventsContainer.getBookingCreatedEvents()))
.consultantMessagesCount(countEventsPerAdviceSeekerMatchingOnMetadataByReceiverId(rawEvent.getUser().getId(), statisticEventsContainer.getConsultantMessageCreatedEvents()));
}

private Integer countEventsPerAdviceSeekerMatchingOnMetadata(String adviceSeekerId,
Collection<StatisticsEvent> events) {

return events != null
? (int) getCountOfEventsPerAdviceSeekerMatchingOnMetadata(adviceSeekerId, events) : 0;
}

private Integer countEventsPerAdviceSeekerMatchingOnMetadataByReceiverId(String adviceSeekerId,
Collection<StatisticsEvent> events) {

return events != null
? (int) getCountOfEventsPerAdviceSeekerMatchingOnMetadataByReceiverId(adviceSeekerId, events) : 0;
}

private long getCountOfEventsPerAdviceSeekerMatchingOnMetadata(String adviceSeekerId,
Collection<StatisticsEvent> statisticsEvents) {
return statisticsEvents.stream()
.filter(event -> {
AdviceSeekerAwareMetaData metaData = (AdviceSeekerAwareMetaData) event.getMetaData();
return metaData.getAdviceSeekerId() != null && metaData.getAdviceSeekerId()
.equals(adviceSeekerId);
})
.count();
}

private long getCountOfEventsPerAdviceSeekerMatchingOnMetadataByReceiverId(String adviceSeekerId,
Collection<StatisticsEvent> createMessageEvents) {
return createMessageEvents.stream()
.filter(event -> {
CreateMessageMetaData metaData = (CreateMessageMetaData) event.getMetaData();
return metaData.getReceiverId() != null && metaData.getReceiverId()
.equals(adviceSeekerId);
})
.count();
}

private String getEndDate(String maxArchiveDate, String deleteAccountDate) {
return deleteAccountDate != null ? deleteAccountDate : maxArchiveDate;
}

private String findDeleteAccountDate(String userId, Collection<StatisticsEvent> deleteAccountEvents) {
return deleteAccountEvents != null ? deleteAccountEvents.stream()
.filter(event -> event.getUser() != null && event.getUser().getId().equals(userId))
.map(event -> ((DeleteAccountMetaData) event.getMetaData()).getDeleteDate())
.findFirst().orElse(null) : null;
}

private String findEndDate(Long sessionId, List<StatisticsEvent> archiveSessionEvents) {
private String findMaxArchiveDate(Long sessionId, Collection<StatisticsEvent> archiveSessionEvents) {
var maxArchiveEvent = findMaxArchiveSessionEvent(sessionId, archiveSessionEvents);
if (maxArchiveEvent.isPresent()) {
ArchiveMetaData metaData = (ArchiveMetaData) maxArchiveEvent.get().getMetaData();
Expand All @@ -40,9 +99,9 @@ private String findEndDate(Long sessionId, List<StatisticsEvent> archiveSessionE
return null;
}

private Optional<StatisticsEvent> findMaxArchiveSessionEvent(Long sessionId, List<StatisticsEvent> archiveSessionEvents) {
private Optional<StatisticsEvent> findMaxArchiveSessionEvent(Long sessionId, Collection<StatisticsEvent> archiveSessionEvents) {
return nonNull(archiveSessionEvents) ? archiveSessionEvents.stream()
.filter(event -> event.getSessionId() == sessionId)
.filter(event -> event.getSessionId() != null && event.getSessionId().equals(sessionId))
.max(comparing(StatisticsEvent::getTimestamp)) : Optional.empty();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package de.caritas.cob.statisticsservice.api.service;

import de.caritas.cob.statisticsservice.api.service.securityheader.TenantHeaderSupplier;
import de.caritas.cob.statisticsservice.config.apiclient.UserStatisticsApiControllerFactory;
import de.caritas.cob.statisticsservice.config.cache.CacheManagerConfig;
import de.caritas.cob.statisticsservice.userstatisticsservice.generated.web.UserStatisticsControllerApi;
import de.caritas.cob.statisticsservice.api.service.securityheader.SecurityHeaderSupplier;
import de.caritas.cob.statisticsservice.userstatisticsservice.generated.web.model.SessionStatisticsResultDTO;
import lombok.NonNull;
Expand All @@ -14,7 +14,7 @@
@RequiredArgsConstructor
public class UserStatisticsService {

private final @NonNull UserStatisticsControllerApi userStatisticsControllerApi;
private final @NonNull UserStatisticsApiControllerFactory userStatisticsApiControllerFactory;
private final @NonNull SecurityHeaderSupplier securityHeaderSupplier;
private final @NonNull TenantHeaderSupplier tenantHeaderSupplier;

Expand All @@ -41,6 +41,7 @@ public SessionStatisticsResultDTO retrieveSessionViaRcGroupId(String rcGroupId)
}

private SessionStatisticsResultDTO retrieveSession(Long sessionId, String rcGroupId) {
var userStatisticsControllerApi = userStatisticsApiControllerFactory.createControllerApi();
addDefaultHeaders(userStatisticsControllerApi.getApiClient());
return userStatisticsControllerApi
.getSession(sessionId, rcGroupId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,16 @@ public class SecurityHeaderSupplier {
@Value("${csrf.cookie.property}")
private String csrfCookieProperty;

/**
* Creates the headers containing keycloak token and csrf headers {@link HttpHeaders} object.
*
* @return the created {@link HttpHeaders}
*/
public HttpHeaders getKeycloakAndCsrfHttpHeaders() {
var header = getCsrfHttpHeaders();
this.addKeycloakAuthorizationHeader(header);

return header;
}

public HttpHeaders getCsrfHttpHeaders() {
var httpHeaders = new HttpHeaders();

return this.addCsrfValues(httpHeaders);
}

private HttpHeaders addCsrfValues(HttpHeaders httpHeaders) {
var csrfToken = UUID.randomUUID().toString();

httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.add("Cookie", csrfCookieProperty + "=" + csrfToken);
httpHeaders.add(csrfHeaderProperty, csrfToken);

return httpHeaders;
}

private void addKeycloakAuthorizationHeader(HttpHeaders httpHeaders) {
httpHeaders.add("Authorization", "Bearer " + authenticatedUser.getAccessToken());
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package de.caritas.cob.statisticsservice.api.statistics.listener;

import de.caritas.cob.statisticsservice.api.model.ArchiveSessionStatisticsEventMessage;
import de.caritas.cob.statisticsservice.api.model.ArchiveOrDeleteSessionStatisticsEventMessage;
import de.caritas.cob.statisticsservice.api.service.UserStatisticsService;
import de.caritas.cob.statisticsservice.api.statistics.model.statisticsevent.StatisticsEvent;
import de.caritas.cob.statisticsservice.api.statistics.model.statisticsevent.StatisticsEventBuilder;
Expand All @@ -16,21 +16,21 @@
*/
@Service
@RequiredArgsConstructor
public class ArchiveSessionListener {
public class ArchiveOrDeleteSessionListener {

private final @NonNull MongoTemplate mongoTemplate;
private final @NonNull UserStatisticsService userStatisticsService;

/**
* Consumer for archive session message statistics event.
*
* @param eventMessage the {@link ArchiveSessionStatisticsEventMessage} instance
* @param eventMessage the {@link ArchiveOrDeleteSessionStatisticsEventMessage} instance
*/
@RabbitListener(
id = "archive-session-event-listener",
queues = "#{rabbitMqConfig.QUEUE_NAME_ARCHIVE_SESSION}",
containerFactory = "simpleRabbitListenerContainerFactory")
public void receiveMessage(ArchiveSessionStatisticsEventMessage eventMessage) {
public void receiveMessage(ArchiveOrDeleteSessionStatisticsEventMessage eventMessage) {

StatisticsEvent statisticsEvent =
StatisticsEventBuilder.getInstance(
Expand All @@ -45,7 +45,7 @@ public void receiveMessage(ArchiveSessionStatisticsEventMessage eventMessage) {
mongoTemplate.insert(statisticsEvent);
}

private ArchiveMetaData buildMetaData(ArchiveSessionStatisticsEventMessage eventMessage) {
private ArchiveMetaData buildMetaData(ArchiveOrDeleteSessionStatisticsEventMessage eventMessage) {
return ArchiveMetaData.builder()
.endDate(eventMessage.getEndDate())
.tenantId(eventMessage.getTenantId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ private BookingCreatedMetaData buildMetaData(BookingCreatedStatisticsEventMessag
.uid(eventMessage.getUid())
.bookingId(eventMessage.getBookingId())
.currentBookingId(eventMessage.getBookingId())
.adviceSeekerId(eventMessage.getAdviceSeekerId())
.tenantId(eventMessage.getTenantId())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ public void receiveMessage(CreateMessageStatisticsEventMessage eventMessage) {
}

private CreateMessageMetaData buildMetaData(CreateMessageStatisticsEventMessage eventMessage) {
return CreateMessageMetaData.builder().hasAttachment(eventMessage.getHasAttachment()).build();
return CreateMessageMetaData.builder()
.receiverId(eventMessage.getReceiverId())
.hasAttachment(eventMessage.getHasAttachment())
.tenantId(eventMessage.getTenantId())
.build();
}
}
Loading

0 comments on commit 0ef1c49

Please sign in to comment.