Skip to content

Commit

Permalink
Div. overhaling
Browse files Browse the repository at this point in the history
  • Loading branch information
farjamm committed Jul 4, 2024
1 parent 9fe1604 commit ec468d1
Show file tree
Hide file tree
Showing 96 changed files with 977 additions and 731 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
@Tag(name = "Audit")
@RequiredArgsConstructor
public class AuditController {

// TODO: Implementerer ikke controller → service → DB. Flytt all forretningslogikk og *Repository-aksess til tjenestelaget.

private final AuditVersionRepository repository;
private final StorageService storage;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
package no.nav.data.common.auditing;

import lombok.RequiredArgsConstructor;
import no.nav.data.common.auditing.domain.AuditVersionRepository;
import no.nav.data.common.auditing.dto.AuditMetadata;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class AuditService {

private final AuditVersionRepository auditVersionRepository;

public AuditService(AuditVersionRepository auditVersionRepository) {
this.auditVersionRepository = auditVersionRepository;
}

public List<AuditMetadata> lastEditedProcessesByUser(String user) {
return auditVersionRepository.getLastChangedProcessesByUser(user, 20);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import no.nav.data.common.utils.MdcUtils;
import no.nav.data.polly.codelist.domain.Codelist;
import org.hibernate.proxy.HibernateProxy;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.Optional;
Expand All @@ -33,7 +35,11 @@
@Slf4j
public class AuditVersionListener {

private static AuditVersionRepository repository;
// Merk: Denne klassen er IKKE håndtert av Spring (siden den instansieres av JPA), men den avhenger av en Spring-managed bønne.
// Dette er løst med et hæck der Spring kaller en statisk metode i denne klassen for å tilby bønna.
// Men dette hacket virker ikke alltid for integrasjonstesting, så det er et hæck til i IntegrationTestBase for å få det til å gå.

private static volatile AuditVersionRepository repository;

private static final ObjectWriter wr;

Expand Down Expand Up @@ -64,16 +70,17 @@ public void preRemove(Object entity) {
audit(entity, Action.DELETE);
}

@Transactional(propagation = Propagation.MANDATORY)
private void audit(Object entity, Action action) {
try {
Assert.isTrue(entity instanceof Auditable, "Invalid object");
if (entity instanceof GenericStorage && !((GenericStorage) entity).getType().isAudit()) {
if (entity instanceof GenericStorage genStorage && !genStorage.getType().isAudit()) {
return;
}
String tableName = AuditVersion.tableName(((Auditable) entity).getClass());
String id = getIdForObject(entity);
String data = wr.writeValueAsString(entity);
String user = Optional.ofNullable(MdcUtils.getUser()).orElse("no user set");
String user = Optional.ofNullable(MdcUtils.getUser()).orElse("no-user-set");
AuditVersion auditVersion = AuditVersion.builder()
.action(action).table(tableName).tableId(id).data(data).user(user)
.build();
Expand All @@ -85,8 +92,8 @@ private void audit(Object entity, Action action) {

public static String getIdForObject(Object entity) {
String id;
if (entity instanceof Codelist) {
id = ((Codelist) entity).getList() + "-" + ((Codelist) entity).getCode();
if (entity instanceof Codelist clEntity) {
id = clEntity.getList() + "-" + clEntity.getCode();
} else {
UUID uuid = HibernateUtils.getId(entity);
Assert.notNull(uuid, "entity has not set id");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class AuditVersion {
@Column(name = "DATA", nullable = false, updatable = false)
private String data;

// TODO: Snu avhengigheten innover
public AuditResponse convertToResponse() {
return AuditResponse.builder()
.id(id.toString())
Expand All @@ -79,6 +80,7 @@ public AuditResponse convertToResponse() {
.build();
}

// TODO: Snu avhengigheten innover (ikke triviell). Flytt all forretningslogikk i domeneklassen ut til tjenestelaget.
public EventResponse convertToEventResponse() {
return EventResponse.builder()
.id(id.toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,30 @@ static Example<AuditVersion> exampleFrom(AuditVersion example) {

@Query(value = """
select * from audit_version av
where table_name = ?1 and action = ?2
where table_name = ?1 and action = ?2
and (?2 = 'DELETE' or not exists (select 1 from audit_version av2 where av2.table_id = av.table_id and av2.action = 'DELETE'))
""",
countQuery = """
select count(1) from audit_version av
where table_name = ?1 and action = ?2
and (?2 = 'DELETE' or not exists (select 1 from audit_version av2 where av2.table_id = av.table_id and av2.action = 'DELETE'))
""", nativeQuery = true)
""",
countQuery = """
select count(1) from audit_version av
where table_name = ?1 and action = ?2
and (?2 = 'DELETE' or not exists (select 1 from audit_version av2 where av2.table_id = av.table_id and av2.action = 'DELETE'))
""",
nativeQuery = true)
Page<AuditVersion> findForTableAndAction(String table, String action, Pageable page);

@Query(value = """
select cast(audit_id as text) as id, time, action, table_name as tableName, table_id as tableId
from audit_version where audit_id in (
select distinct on (table_id) audit_id
from audit_version
where table_name = 'PROCESS'
and user_id = ?1
and exists (select 1 from process where process_id = cast(table_id as uuid))
order by table_id, time desc
)
order by time desc
limit ?2
""", nativeQuery = true)
from audit_version where audit_id in (
select distinct on (table_id) audit_id
from audit_version
where table_name = 'PROCESS'
and user_id = ?1
and exists (select 1 from process where process_id = cast(table_id as uuid))
order by table_id, time desc
)
order by time desc
limit ?2
""", nativeQuery = true)
List<AuditMetadata> getLastChangedProcessesByUser(String userId, int limit);

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public abstract class Auditable {
@Column(name = "LAST_MODIFIED_DATE")
protected LocalDateTime lastModifiedDate;

// TODO: Snu avhengigheten innover
public ChangeStampResponse convertChangeStampResponse() {
return ChangeStampResponse.builder()
.lastModifiedBy(getLastModifiedBy())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@

public interface MailLogRepository extends JpaRepository<GenericStorage, UUID> {

@Override
@Query(value = "select * from generic_storage where type = 'MAIL_LOG' order by created_date desc",
countQuery = "select count(1) from generic_storage where type = 'MAIL_LOG'"
, nativeQuery = true)
countQuery = "select count(1) from generic_storage where type = 'MAIL_LOG'",
nativeQuery = true)
Page<GenericStorage> findAll(Pageable pageable);

@Query(value = "select * from generic_storage where type = 'MAIL_LOG' and data ->> 'to' = ?1 order by created_date desc", nativeQuery = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import no.nav.data.common.auditing.domain.Action;
import no.nav.data.common.auditing.domain.AuditVersion;
Expand All @@ -21,6 +22,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
Expand All @@ -31,20 +33,19 @@
import static no.nav.data.common.utils.StreamUtils.convert;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/event")
@Tag(name = "Event", description = "Domain object events")
public class EventController {

// TODO: Implementerer ikke controller → service → DB. Flytt all forretningslogikk, *Repository-aksess og @Transactional til tjenestelaget.

private final AuditVersionRepository repository;
private final List<String> allowedTables = convert(
List.of(InformationType.class, Process.class, Policy.class, Disclosure.class, Document.class),
AuditVersion::tableName);

public EventController(AuditVersionRepository repository) {
this.repository = repository;
}

@Operation(summary = "Get events")
@ApiResponse(description = "Events fetched")
@GetMapping
Expand All @@ -63,7 +64,6 @@ private void validateTable(String table) {
}

static class EventPage extends RestResponsePage<EventResponse> {

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import no.nav.data.common.security.SecurityProperties;
import no.nav.data.common.storage.StorageService;
import no.nav.data.common.storage.domain.GenericStorage;
import no.nav.data.common.storage.domain.GenericStorageRepository;
import no.nav.data.common.storage.domain.StorageType;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class EmailServiceImpl implements EmailService {
Expand All @@ -30,17 +32,21 @@ public void sendMail(MailTask mailTask) {
}

@Override
@Transactional
public void scheduleMail(MailTask mailTask) {
storage.save(mailTask);
}

@Scheduled(initialDelayString = "PT3M", fixedRateString = "PT5M")
public void sendMails() {
var tasks = storageRepository.findAllByType(StorageType.MAIL_TASK);

tasks.forEach(task -> {
sendMail(task.getDataObject(MailTask.class));
storageRepository.delete(task);
});
tasks.forEach(this::sendMailAndDeleteTask);
}

@Transactional // Viktig med en transaksjon per mail, slik at ikke allerede sendte mails blir rullet tilbake til repo ved feil
private void sendMailAndDeleteTask(GenericStorage task) {
storageRepository.delete(task);
sendMail(task.getDataObject(MailTask.class));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import no.nav.data.common.auditing.domain.Auditable;
import no.nav.data.common.auditing.domain.Auditable.Fields;

import java.time.LocalDateTime;
Expand All @@ -19,4 +20,13 @@ public class ChangeStampResponse {
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
private LocalDateTime createdDate;

public static ChangeStampResponse from(Auditable auditable) {
return ChangeStampResponse.builder()
.lastModifiedBy(auditable.getLastModifiedBy())
.lastModifiedDate(auditable.getLastModifiedDate() == null ? LocalDateTime.now() : auditable.getLastModifiedDate())
.createdDate(auditable.getCreatedDate())
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public Collection<String> getIds() {

@Data
static class AuthApps {

private String name;
private String clientId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private ConfigurableJWTProcessor<SecurityContext> getAadJwtTokenValidator(JWSAlg
new JWSVerificationKeySelector<>(jwsAlgorithm, keySource);
jwtProcessor.setJWSKeySelector(keySelector);

jwtProcessor.setJWTClaimsSetVerifier(new DefaultJWTClaimsVerifier<>() {
jwtProcessor.setJWTClaimsSetVerifier(new DefaultJWTClaimsVerifier<>(null, null) {
@Override
public void verify(JWTClaimsSet claimsSet, SecurityContext ctx) throws BadJWTException {
super.verify(claimsSet, ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,33 @@

import com.microsoft.graph.serviceclient.GraphServiceClient;
import com.microsoft.graph.users.item.sendmail.SendMailPostRequestBody;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import no.nav.data.common.mail.EmailProvider;
import no.nav.data.common.mail.MailTask;
import no.nav.data.common.storage.StorageService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static no.nav.data.common.security.azure.support.MailMessage.compose;

@Slf4j
@Service
@RequiredArgsConstructor
public class AzureAdService implements EmailProvider {

private final AzureTokenProvider azureTokenProvider;
private final StorageService storage;

public AzureAdService(AzureTokenProvider azureTokenProvider, StorageService storage) {
this.azureTokenProvider = azureTokenProvider;
this.storage = storage;
}

@Override
@Transactional
public void sendMail(MailTask mailTask) {
log.info("sending mail {} to {}", mailTask.getSubject(), mailTask.getTo());
SendMailPostRequestBody sendMailPostRequestBody = new SendMailPostRequestBody();
sendMailPostRequestBody.setMessage(compose(mailTask.getTo(), mailTask.getSubject(), mailTask.getBody()));
sendMailPostRequestBody.setSaveToSentItems(true);

getMailGraphClient().me().sendMail().post(sendMailPostRequestBody);

storage.save(mailTask.toMailLog());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public static UserInfoResponse noUser(boolean securityEnabled) {
return responseBuilder.build();
}

@SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
public static class UserInfoResponseBuilder {

private List<String> groups = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package no.nav.data.common.storage;

import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import lombok.RequiredArgsConstructor;
import no.nav.data.common.storage.domain.AppState;
import no.nav.data.common.storage.domain.GenericStorage;
import no.nav.data.common.storage.domain.GenericStorageData;
Expand All @@ -13,14 +14,11 @@
import java.util.function.Consumer;

@Service
@RequiredArgsConstructor
public class StorageService {

private final GenericStorageRepository repository;

public StorageService(GenericStorageRepository repository) {
this.repository = repository;
}

public <T extends GenericStorageData> T getSingleton(Class<T> type) {
return getSingletonAsStorage(type).getDataObject(type);
}
Expand All @@ -29,6 +27,7 @@ public <T extends GenericStorageData> T get(Class<T> type, UUID id) {
return repository.findById(id).orElseThrow().getDataObject(type);
}

@Transactional(readOnly = false) // Merk: På tross av navnet på metoden, kan den resultere i save
public <T extends GenericStorageData> GenericStorage getSingletonAsStorage(Class<T> type) {
return findType(StorageType.fromClass(type));
}
Expand All @@ -41,17 +40,19 @@ private GenericStorage create(StorageType type) {
return repository.save(GenericStorage.builder().generateId().type(type).data(JsonNodeFactory.instance.objectNode()).build());
}

@Transactional
public GenericStorage save(GenericStorage storage) {
return repository.save(storage);
}

@Transactional
public void save(GenericStorageData data) {
var storage = GenericStorage.builder().generateId().build();
storage.setDataObject(data);
repository.save(storage);
}

@Transactional
@Transactional
public void usingAppState(Consumer<AppState> consumer) {
var appStateStorage = getSingletonAsStorage(AppState.class);
var appState = appStateStorage.getDataObject(AppState.class);
Expand Down
Loading

0 comments on commit ec468d1

Please sign in to comment.