Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DMP-4653 Fixing courtroom name unique constraint violation #2536

Merged
merged 3 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package uk.gov.hmcts.darts.noderegistration.controller;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
Expand All @@ -10,7 +12,6 @@
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.transaction.annotation.Transactional;
import uk.gov.hmcts.darts.authorisation.component.UserIdentity;
import uk.gov.hmcts.darts.common.entity.CourthouseEntity;
import uk.gov.hmcts.darts.common.entity.CourtroomEntity;
Expand All @@ -34,7 +35,6 @@

@Slf4j
@AutoConfigureMockMvc
@Transactional
class NodeRegistrationControllerTest extends IntegrationBase {

@Autowired
Expand All @@ -43,6 +43,15 @@ class NodeRegistrationControllerTest extends IntegrationBase {
@MockitoBean
private UserIdentity mockUserIdentity;

@BeforeEach
void startHibernateSession() {
openInViewUtil.openEntityManager();
}

@AfterEach
void closeHibernateSession() {
openInViewUtil.closeEntityManager();
}

@Test
void testPostRegisterDevices() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import uk.gov.hmcts.darts.common.entity.CourtCaseEntity;
import uk.gov.hmcts.darts.common.entity.CourthouseEntity;
import uk.gov.hmcts.darts.common.entity.CourtroomEntity;
Expand All @@ -16,39 +18,109 @@

public interface RetrieveCoreObjectService {

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* This method is used when events are received and processed.
* By creating a new transaction, along with using the @Retryable annotation, we can ensure that concurrent requests to create the
* same hearing can be processed without causing a constraint violation.
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class}, maxAttempts = 10)
Ben-Edwards-cgi marked this conversation as resolved.
Show resolved Hide resolved
HearingEntity retrieveOrCreateHearing(String courthouseName, String courtroomName, String caseNumber, LocalDateTime hearingDate);

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* This method is used for the following
* - daily list processing
* - adding audio using metadata
* By creating a new transaction, along with using the @Retryable annotation, we can ensure that concurrent requests to create the
* same hearing can be processed without causing a constraint violation.
* Concurrency isn't a concern for daily list processing.
*/
@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class}, maxAttempts = 10)
HearingEntity retrieveOrCreateHearing(String courthouseName, String courtroomName, String caseNumber, LocalDateTime hearingDate,
UserAccountEntity userAccount);

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* Retrieve or create a case and link to media.
* @deprecated This method is only used by tests. Tests should be refactored and this method should be removed.
*/
@SuppressWarnings("java:S1133") // suppress sonar warning about deprecated methods
@Deprecated(since = "04/02/2025")
HearingEntity retrieveOrCreateHearingWithMedia(String courthouseName, String courtroomName, String caseNumber, LocalDateTime hearingDate,
UserAccountEntity userAccount, MediaEntity mediaEntity);

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* Retrieve or create a courtroom.
* @deprecated This method is only used by tests.
* Tests should be refactored to use the other `retrieveOrCreateCourtroom` method, and this method should be removed.
*/
@SuppressWarnings("java:S1133") // suppress sonar warning about deprecated methods
@Deprecated(since = "04/02/2025")
CourtroomEntity retrieveOrCreateCourtroom(CourthouseEntity courthouse, String courtroomName, UserAccountEntity userAccount);

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* This method is used for the following
* - node register
* - events
* - get cases
* - adding audio
* - audio requests
* By creating a new transaction, along with using the @Retryable annotation, we can ensure that concurrent requests that attempt to create the
* same courtroom can be processed without causing a constraint violation.
* Concurrency isn't a concern for adding audio or audio requests. Due to the nature of these calls, it is extremely unlikely that the courtroom
* will not exist.
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class}, maxAttempts = 10)
CourtroomEntity retrieveOrCreateCourtroom(String courthouseName, String courtroomName, UserAccountEntity userAccount);

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* This method is used for the following
* - add case
* - events
* By creating a new transaction, along with using the @Retryable annotation, we can ensure that concurrent requests that attempt to create the
* same case can be processed without causing a constraint violation.
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class}, maxAttempts = 10)
CourtCaseEntity retrieveOrCreateCase(String courthouseName, String caseNumber);

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* Retrieve or create a case.
* @deprecated This method is only used by tests.
* Tests should be refactored to use the other `retrieveOrCreateCase` method, and this method should be removed.
*/
@SuppressWarnings("java:S1133") // suppress sonar warning about deprecated methods
@Deprecated(since = "04/02/2025")
CourtCaseEntity retrieveOrCreateCase(String courthouseName, String caseNumber, UserAccountEntity userAccount);

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* This method is used during add audio when retrieving/creating cases used in the metadata before adding to the media_linked_case table.
* It's possible that the same case could be sent in concurrent add audio requests.
* By creating a new transaction, along with using the @Retryable annotation, we can ensure that concurrent requests that attempt to create the
* same case can be processed without causing a constraint violation.
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class}, maxAttempts = 10)
CourtCaseEntity retrieveOrCreateCase(CourthouseEntity courthouse, String caseNumber, UserAccountEntity userAccount);

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* Used to retrieve the courthouse during add audio validation.
*/
CourthouseEntity retrieveCourthouse(String courthouseName);

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* This method is used for add case, it's possible that the same judge could be sent in concurrent add case requests.
* By creating a new transaction, along with using the @Retryable annotation, we can ensure that concurrent requests that attempt to create the
* same judge can be processed without causing a constraint violation.
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class}, maxAttempts = 10)
JudgeEntity retrieveOrCreateJudge(String judgeName);

@Retryable(backoff = @Backoff(delay = 50), retryFor = {DataIntegrityViolationException.class, PSQLException.class})
/**
* This method is only used to add judges during daily list processing. This task processed data in serial and therefore
* there are no concurrent write concerns.
*/
JudgeEntity retrieveOrCreateJudge(String judgeName, UserAccountEntity userAccount);

}