Skip to content

Commit

Permalink
chore: fixing discrepancies
Browse files Browse the repository at this point in the history
  • Loading branch information
paulushcgcj committed Dec 18, 2024
1 parent 2705586 commit 6a6ae7b
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 95 deletions.
47 changes: 38 additions & 9 deletions backend/src/main/java/ca/bc/gov/app/ApplicationConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,18 @@ public final class ApplicationConstant {
dc.district_code as district,
dc.district_code || ' - ' || dc.description as district_desc
FROM nrfc.submission s
left join nrfc.submission_status_code ssc on ssc.submission_status_code = s.submission_status_code\s
left join nrfc.submission_type_code stc on stc.submission_type_code = s.submission_type_code
left join nrfc.submission_detail sd on sd.submission_id = s.submission_id\s
left join nrfc.business_type_code btc on btc.business_type_code = sd.business_type_code\s
left join nrfc.district_code dc on dc.district_code = sd.district_code\s
left join nrfc.client_type_code ctc on ctc.client_type_code = sd.client_type_code\s
left join nrfc.submission_status_code ssc
on ssc.submission_status_code = s.submission_status_code
left join nrfc.submission_type_code stc
on stc.submission_type_code = s.submission_type_code
left join nrfc.submission_detail sd
on sd.submission_id = s.submission_id
left join nrfc.business_type_code btc
on btc.business_type_code = sd.business_type_code
left join nrfc.district_code dc
on dc.district_code = sd.district_code
left join nrfc.client_type_code ctc
on ctc.client_type_code = sd.client_type_code
where s.submission_id = :submissionId""";

public static final String SUBMISSION_CONTACTS_QUERY = """
Expand All @@ -71,7 +77,15 @@ public final class ApplicationConstant {
sc.last_name,
sc.business_phone_number,
sc.email_address,
(select STRING_AGG(sl.location_name,', ') as locations from nrfc.submission_location sl left join nrfc.submission_location_contact_xref slcx on slcx.submission_location_id = sl.submission_location_id left join nrfc.submission_contact sc on sc.submission_contact_id = slcx.submission_contact_id where sl.submission_id = :submissionId) as locations,
(
select STRING_AGG(sl.location_name,', ') as locations
from nrfc.submission_location sl
left join nrfc.submission_location_contact_xref slcx
on slcx.submission_location_id = sl.submission_location_id
left join nrfc.submission_contact sc
on sc.submission_contact_id = slcx.submission_contact_id
where sl.submission_id = :submissionId
) as locations,
sc.idp_user_id
FROM nrfc.submission_contact sc
left join nrfc.contact_type_code ctc on ctc.contact_type_code = sc.contact_type_code
Expand All @@ -90,7 +104,9 @@ public final class ApplicationConstant {
sl.location_name
FROM nrfc.submission_location sl
left join nrfc.country_code cc on cc.country_code = sl.country_code
left join nrfc.province_code pc on (pc.province_code = sl.province_code and pc.country_code = cc.country_code)
left join nrfc.province_code pc on (
pc.province_code = sl.province_code and pc.country_code = cc.country_code
)
where sl.submission_id = :submissionId
order by sl.submission_location_id""";

Expand All @@ -108,7 +124,20 @@ left join nrfc.province_code pc on (pc.province_code = sl.province_code and pc.c
public static final String ROLE_ADMIN = "CLIENT_ADMIN";
public static final String ROLE_SUSPEND = "CLIENT_SUSPEND";

public static final String OPENDATA_FILTER = "<Filter><Or><PropertyIsLike wildCard=\"*\" singleChar=\".\" escape=\"!\"><PropertyName>%s</PropertyName><Literal>*%s*</Literal></PropertyIsLike><PropertyIsLike wildCard=\"*\" singleChar=\".\" escape=\"!\"><PropertyName>%s</PropertyName><Literal>*%s*</Literal></PropertyIsLike><PropertyIsLike wildCard=\"*\" singleChar=\".\" escape=\"!\"><PropertyName>%s</PropertyName><Literal>*%s*</Literal></PropertyIsLike><PropertyIsLike wildCard=\"*\" singleChar=\".\" escape=\"!\"><PropertyName>%s</PropertyName><Literal>*%s*</Literal></PropertyIsLike></Or></Filter>";
public static final String OPENDATA_FILTER = "<Filter><Or><PropertyIsLike wildCard=\"*\" "
+ "singleChar=\".\" escape=\"!\">"
+ "<PropertyName>%s</PropertyName>"
+ "<Literal>*%s*</Literal></PropertyIsLike>"
+ "<PropertyIsLike wildCard=\"*\" singleChar=\".\" "
+ "escape=\"!\"><PropertyName>%s</PropertyName>"
+ "<Literal>*%s*</Literal></PropertyIsLike>"
+ "<PropertyIsLike wildCard=\"*\" singleChar=\".\" "
+ "escape=\"!\"><PropertyName>%s</PropertyName>"
+ "<Literal>*%s*</Literal></PropertyIsLike>"
+ "<PropertyIsLike wildCard=\"*\" singleChar=\".\" "
+ "escape=\"!\"><PropertyName>%s</PropertyName>"
+ "<Literal>*%s*</Literal></PropertyIsLike>"
+ "</Or></Filter>";

public static final String MDC_USERID = "X-USER";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,15 @@ public WebClient openDataSacBandApi(
.baseUrl(configuration.getOpenData().getSacBandUrl()).build();
}

/**
* Configures and provides a WebClient for accessing the Open Data SAC Tribe API. This WebClient
* is pre-configured with the base URL for the SAC Tribe API, as specified in the provided
* {@link ForestClientConfiguration}.
*
* @param configuration The configuration containing the SAC Tribe API URL and other settings.
* @param webClientBuilder A builder for creating WebClient instances.
* @return A WebClient instance configured for the Open Data SAC Tribe API.
*/
@Bean
public WebClient openDataSacTribeApi(
ForestClientConfiguration configuration,
Expand Down Expand Up @@ -275,6 +284,16 @@ public WebClient openDataBcMapsBandApi(
return webClientBuilder.baseUrl(configuration.getOpenData().getOpenMapsBandUrl()).build();
}

/**
* Configures and provides a WebClient for accessing the Open Data BC Maps Tribe API. This
* WebClient is pre-configured with the base URL for the BC Maps Tribe API, as specified in the
* provided {@link ForestClientConfiguration}.
*
* @param configuration The configuration containing the BC Maps Tribe API URL and other
* settings.
* @param webClientBuilder A builder for creating WebClient instances.
* @return A WebClient instance configured for the Open Data BC Maps Tribe API.
*/
@Bean
public WebClient openDataBcMapsTribeApi(
ForestClientConfiguration configuration,
Expand Down Expand Up @@ -306,6 +325,14 @@ public WebClient processorApi(
return webClientBuilder.baseUrl(configuration.getProcessor().getUrl()).build();
}

/**
* Configures and provides an ObjectMapper bean. This ObjectMapper is built using the provided
* Jackson2ObjectMapperBuilder and is configured with the JavaTimeModule and a custom
* ForestClientDetailsSerializerModifier module.
*
* @param builder The Jackson2ObjectMapperBuilder used to build the ObjectMapper.
* @return A configured ObjectMapper instance.
*/
@Bean
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {

Expand All @@ -316,6 +343,12 @@ public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
return mapper;
}

/**
* Creates and configures a SimpleModule for customizing the serialization of ForestClientDetails.
* This module registers a custom serializer modifier, ForestClientDetailsSerializerModifier.
*
* @return A configured SimpleModule instance with the custom serializer modifier.
*/
SimpleModule forestClientDetailsDtoModule() {
SimpleModule module = new SimpleModule();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class ClientController {
* provider) is extracted from the token to authorize the request.
*
* @param clientNumber the incorporation number of the client whose details are being requested
* @param principal the JWT authentication token containing user and business information
* @param principal the JWT authentication token containing user and business information
* @return a {@link Mono} emitting the {@link ClientDetailsDto} containing the client's details
*/
@GetMapping("/{clientNumber}")
Expand All @@ -66,21 +66,23 @@ public Mono<ClientDetailsDto> getClientDetailsByIncorporationNumber(
}

@GetMapping("/details/{clientNumber}")
public Mono<ForestClientDetailsDto> getClientDetailsByClientNumber(@PathVariable String clientNumber) {
public Mono<ForestClientDetailsDto> getClientDetailsByClientNumber(
@PathVariable String clientNumber) {
log.info("Requesting client details for client number {}", clientNumber);
return clientService.getClientDetailsByClientNumber(clientNumber);
}

/**
* Performs a full-text search for clients based on the provided keyword, with pagination support.
* Performs a full-text search for clients based on the provided keyword, with pagination
* support.
*
* <p>This endpoint allows searching for clients by a keyword. The results are paginated, and the
* <p>This endpoint allows searching for clients by a keyword. The results are paginated, and the
* total count of matching records is included in the response headers.
*
* @param page the page number to retrieve (default is 0)
* @param size the number of records per page (default is 10)
* @param keyword the keyword to search for (default is an empty string, which returns all
* records)
* @param page the page number to retrieve (default is 0)
* @param size the number of records per page (default is 10)
* @param keyword the keyword to search for (default is an empty string, which returns all
* records)
* @param serverResponse the HTTP response to include the total count of records in the headers
* @return a {@link Flux} emitting {@link ClientListDto} objects containing the search results
*/
Expand All @@ -107,15 +109,15 @@ public Flux<ClientListDto> fullSearch(
})
.map(Pair::getFirst)
.doFinally(signalType ->
serverResponse
.getHeaders()
.putIfAbsent(
ApplicationConstant.X_TOTAL_COUNT,
List.of("0")
)
serverResponse
.getHeaders()
.putIfAbsent(
ApplicationConstant.X_TOTAL_COUNT,
List.of("0")
)
);
}

/**
* Retrieve a Flux of ClientLookUpDto objects by searching for clients with a specific name.
*
Expand All @@ -133,18 +135,18 @@ public Flux<ClientLookUpDto> findByClientName(@PathVariable String name) {
/**
* Finds a client based on their registration number.
*
* <p>This endpoint retrieves client information by searching for a registration number.
* <p>This endpoint retrieves client information by searching for a registration number.
* If no client is found, an error is returned.
*
* @param registrationNumber the registration number of the client to look up
* @return a {@link Mono} emitting the {@link ClientLookUpDto} if found, or an error
* if no data exists
* @return a {@link Mono} emitting the {@link ClientLookUpDto} if found, or an error if no data
* exists
*/
@GetMapping(value = "/incorporation/{registrationNumber}")
public Mono<ClientLookUpDto> findByRegistrationNumber(
@PathVariable String registrationNumber) {
log.info("Requesting a client with registration number {} from the client service.",
registrationNumber);
registrationNumber);
return clientService
.findByClientNameOrIncorporation(registrationNumber)
.next()
Expand All @@ -154,10 +156,10 @@ public Mono<ClientLookUpDto> findByRegistrationNumber(
/**
* Searches for an individual client by user ID and last name.
*
* <p>This endpoint fetches an individual client using their user ID and last name.
* <p>This endpoint fetches an individual client using their user ID and last name.
* The request is validated against existing records in the system.
*
* @param userId the unique identifier of the individual to search for
* @param userId the unique identifier of the individual to search for
* @param lastName the last name of the individual to search for
* @return a {@link Mono} indicating completion, or an error if the individual is not found
*/
Expand All @@ -166,9 +168,9 @@ public Mono<Void> findByIndividual(
@PathVariable String userId,
@RequestParam String lastName
) {
log.info("Receiving request to search individual with id {} and last name {}",
userId,
lastName);
log.info("Receiving request to search individual with id {} and last name {}",
userId,
lastName);
return clientService.findByIndividual(userId, lastName);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
import reactor.core.publisher.Mono;
import reactor.util.context.Context;

/**
* This class is a web filter that extracts a value from the security context and sets it in the MDC
* (Mapped Diagnostic Context) for logging and tracing purposes. The value is then propagated down
* the filter chain and set in the reactive context to ensure it is available for logging and
* tracing in both reactive and non-reactive parts of the application.
*/
public abstract class ContextPropagatorWebFilter implements WebFilter {

protected abstract String getContextKey();
Expand All @@ -20,16 +26,15 @@ public abstract class ContextPropagatorWebFilter implements WebFilter {

/**
* Filters each incoming request to extract from the security context a {@link String} value using
* {@link #getContextValueExtractor()} and set it in the MDC.
* The value is then propagated down the filter chain and set in the reactive context
* to ensure it is available for logging and tracing in both reactive and non-reactive parts of
* the application.
* {@link #getContextValueExtractor()} and set it in the MDC. The value is then propagated down
* the filter chain and set in the reactive context to ensure it is available for logging and
* tracing in both reactive and non-reactive parts of the application.
*
* @param exchange The current server web exchange that contains information about the request and
* response.
* @param chain The web filter chain that allows the filter to pass on the request to the next
* entity in the chain.
* @return A Mono<Void> that indicates when request handling is complete.
* @return A {@link Mono} of {@link Void} that indicates when request handling is complete.
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Expand All @@ -56,10 +61,10 @@ public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
/**
* Initializes and registers a thread-local context for the current thread. This method configures
* the {@link ContextRegistry} to handle the value within the MDC (Mapped Diagnostic Context),
* allowing for the propagation of the value across different parts of the application that run
* on the same thread. It specifically sets up accessors for getting, setting, and removing the
* value from the MDC. This setup is crucial for maintaining state across the reactive and
* non-reactive parts of the application.
* allowing for the propagation of the value across different parts of the application that run on
* the same thread. It specifically sets up accessors for getting, setting, and removing the value
* from the MDC. This setup is crucial for maintaining state across the reactive and non-reactive
* parts of the application.
*/
private void contextLoad() {
ContextRegistry
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
@Order(-1)
public class UserIdWebFilter extends ContextPropagatorWebFilter {

/**
* Retrieves the context key for the user ID. This key is used to store the user ID in the MDC
* (Mapped Diagnostic Context).
*
* @return The context key for the user ID.
*/
@Override
protected String getContextKey() {
return ApplicationConstant.MDC_USERID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,37 @@
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Component;

/**
* Extracts the user roles from the security context and sets them in the MDC (Mapped Diagnostic
* Context). This filter is applied globally to all incoming requests. It ensures that the user
* roles are available in the MDC, facilitating logging and tracing of requests by user roles. The
* filter operates in both reactive and non-reactive contexts, ensuring compatibility across
* different parts.
*/
@Component
@Slf4j
@Order(-2)
public class UserRolesWebFilter extends ContextPropagatorWebFilter {

/**
* Retrieves the context key for the user roles. This key is used to store the user roles in the
* MDC (Mapped Diagnostic Context).
*
* @return The context key for the user roles.
*/
@Override
protected String getContextKey() {
return ApplicationConstant.MDC_USERROLES;
}

/**
* Extracts the context value for the user roles from the given Authentication object. This
* function retrieves the roles from different types of principals (JwtAuthenticationToken, Jwt,
* UserDetails) and concatenates them into a comma-separated string.
*
* @return A function that takes an Authentication object and returns a comma-separated string of
* user roles.
*/
@Override
protected Function<Authentication, String> getContextValueExtractor() {
return authentication -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,22 @@
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import lombok.extern.slf4j.Slf4j;

/**
* A custom BeanSerializerModifier that modifies the serializer for ForestClientDetailsDto.
* If the bean class is assignable from ForestClientDetailsDto, it returns a custom serializer
* ForestClientObfuscate. Otherwise, it returns the default serializer.
*/
@Slf4j
public class ForestClientDetailsSerializerModifier extends BeanSerializerModifier {

/**
* Modifies the serializer for the given bean description.
*
* @param config The serialization configuration.
* @param beanDesc The bean description.
* @param serializer The default serializer.
* @return A custom serializer if the bean class is ForestClientDetailsDto, otherwise the default serializer.
*/
@Override
public JsonSerializer<?> modifySerializer(
SerializationConfig config,
Expand All @@ -23,4 +36,4 @@ public JsonSerializer<?> modifySerializer(

return super.modifySerializer(config, beanDesc, serializer);
}
}
}
Loading

0 comments on commit 6a6ae7b

Please sign in to comment.