-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #148 from bcgov/feature/GRAD2-3037
Feature/grad2 3037
- Loading branch information
Showing
22 changed files
with
742 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
api/src/main/java/ca/bc/gov/educ/api/gradbusiness/config/RestWebClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package ca.bc.gov.educ.api.gradbusiness.config; | ||
|
||
import ca.bc.gov.educ.api.gradbusiness.util.EducGradBusinessApiConstants; | ||
import ca.bc.gov.educ.api.gradbusiness.util.LogHelper; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.context.annotation.Profile; | ||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager; | ||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider; | ||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder; | ||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; | ||
import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager; | ||
import org.springframework.security.oauth2.client.web.OAuth2AuthorizedClientRepository; | ||
import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction; | ||
import org.springframework.web.reactive.function.client.ExchangeFilterFunction; | ||
import org.springframework.web.reactive.function.client.ExchangeStrategies; | ||
import org.springframework.web.reactive.function.client.WebClient; | ||
|
||
@Configuration | ||
@Profile("!test") | ||
public class RestWebClient { | ||
|
||
EducGradBusinessApiConstants constants; | ||
|
||
LogHelper logHelper; | ||
|
||
@Autowired | ||
public RestWebClient(EducGradBusinessApiConstants constants, LogHelper logHelper) { | ||
this.constants = constants; | ||
this.logHelper = logHelper; | ||
} | ||
|
||
@Bean("gradBusinessClient") | ||
public WebClient getGraduationClientWebClient(OAuth2AuthorizedClientManager authorizedClientManager) { | ||
ServletOAuth2AuthorizedClientExchangeFilterFunction filter = new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); | ||
filter.setDefaultClientRegistrationId("grad-business-client"); | ||
return WebClient.builder() | ||
.exchangeStrategies(ExchangeStrategies | ||
.builder() | ||
.codecs(codecs -> codecs | ||
.defaultCodecs() | ||
.maxInMemorySize(50 * 1024 * 1024)) | ||
.build()) | ||
.apply(filter.oauth2Configuration()) | ||
.filter(this.log()) | ||
.build(); | ||
} | ||
@Bean | ||
public OAuth2AuthorizedClientManager authorizedClientManager( | ||
ClientRegistrationRepository clientRegistrationRepository, | ||
OAuth2AuthorizedClientRepository authorizedClientRepository) { | ||
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder() | ||
.clientCredentials() | ||
.build(); | ||
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager( | ||
clientRegistrationRepository, authorizedClientRepository); | ||
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); | ||
return authorizedClientManager; | ||
} | ||
|
||
/** | ||
* Old web client. You can use a @Qualifier('default') to summon it. | ||
*/ | ||
@Bean | ||
public WebClient webClient() { | ||
return WebClient.builder().exchangeStrategies(ExchangeStrategies.builder() | ||
.codecs(configurer -> configurer | ||
.defaultCodecs() | ||
.maxInMemorySize(300 * 1024 * 1024)) // 300MB | ||
.build()) | ||
.filter(this.log()) | ||
.build(); | ||
} | ||
|
||
private ExchangeFilterFunction log() { | ||
return (clientRequest, next) -> next | ||
.exchange(clientRequest) | ||
.doOnNext((clientResponse -> LogHelper.logClientHttpReqResponseDetails( | ||
clientRequest.method(), | ||
clientRequest.url().toString(), | ||
clientResponse.statusCode().value(), | ||
clientRequest.headers().get(EducGradBusinessApiConstants.CORRELATION_ID), | ||
constants.isSplunkLogHelperEnabled()) | ||
)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
api/src/main/java/ca/bc/gov/educ/api/gradbusiness/model/dto/School.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package ca.bc.gov.educ.api.gradbusiness.model.dto; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import lombok.*; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Data | ||
@Builder | ||
@AllArgsConstructor | ||
@NoArgsConstructor | ||
@EqualsAndHashCode | ||
@Component("instituteSchool") | ||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
public class School { | ||
|
||
private String schoolId; | ||
private String districtId; | ||
private String mincode; | ||
private String independentAuthorityId; | ||
private String schoolNumber; | ||
private String faxNumber; | ||
private String phoneNumber; | ||
private String email; | ||
private String website; | ||
private String displayName; | ||
private String displayNameNoSpecialChars; | ||
private String schoolReportingRequirementCode; | ||
private String schoolOrganizationCode; | ||
private String schoolCategoryCode; | ||
private String facilityTypeCode; | ||
private String openedDate; | ||
private String closedDate; | ||
private boolean canIssueTranscripts; | ||
private boolean canIssueCertificates; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
api/src/main/java/ca/bc/gov/educ/api/gradbusiness/service/RESTService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package ca.bc.gov.educ.api.gradbusiness.service; | ||
|
||
import ca.bc.gov.educ.api.gradbusiness.exception.ServiceException; | ||
import ca.bc.gov.educ.api.gradbusiness.util.EducGradBusinessApiConstants; | ||
import ca.bc.gov.educ.api.gradbusiness.util.ThreadLocalStateUtil; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.beans.factory.annotation.Qualifier; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.HttpStatusCode; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.reactive.function.BodyInserters; | ||
import org.springframework.web.reactive.function.client.WebClient; | ||
import org.springframework.web.reactive.function.client.WebClientResponseException; | ||
import reactor.core.publisher.Mono; | ||
import reactor.util.retry.Retry; | ||
|
||
import java.time.Duration; | ||
|
||
@Service | ||
public class RESTService { | ||
private final WebClient graduationServiceWebClient; | ||
|
||
private static final String SERVER_ERROR = "5xx error."; | ||
private static final String SERVICE_FAILED_ERROR = "Service failed to process after max retries."; | ||
|
||
@Autowired | ||
public RESTService(@Qualifier("gradBusinessClient") WebClient graduationServiceWebClient) { | ||
this.graduationServiceWebClient = graduationServiceWebClient; | ||
} | ||
|
||
public <T> T get(String url, Class<T> clazz) { | ||
T obj; | ||
try { | ||
obj = graduationServiceWebClient | ||
.get() | ||
.uri(url) | ||
.headers(h -> h.set(EducGradBusinessApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID())) | ||
.retrieve() | ||
// if 5xx errors, throw Service error | ||
.onStatus(HttpStatusCode::is5xxServerError, | ||
clientResponse -> Mono.error(new ServiceException(getErrorMessage(url, SERVER_ERROR), clientResponse.statusCode().value()))) | ||
.bodyToMono(clazz) | ||
// only does retry if initial error was 5xx as service may be temporarily down | ||
// 4xx errors will always happen if 404, 401, 403 etc, so does not retry | ||
.retryWhen(Retry.backoff(3, Duration.ofSeconds(2)) | ||
.filter(ServiceException.class::isInstance) | ||
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> { | ||
throw new ServiceException(getErrorMessage(url, SERVICE_FAILED_ERROR), HttpStatus.SERVICE_UNAVAILABLE.value()); | ||
})) | ||
.block(); | ||
} catch (Exception e) { | ||
// catches IOExceptions and the like | ||
throw new ServiceException( | ||
getErrorMessage(url, e.getLocalizedMessage()), | ||
(e instanceof WebClientResponseException exception) ? exception.getStatusCode().value() : HttpStatus.SERVICE_UNAVAILABLE.value(), | ||
e); | ||
} | ||
return obj; | ||
} | ||
|
||
public <T> T post(String url, Object body, Class<T> clazz) { | ||
T obj; | ||
try { | ||
obj = graduationServiceWebClient.post() | ||
.uri(url) | ||
.headers(h -> h.set(EducGradBusinessApiConstants.CORRELATION_ID, ThreadLocalStateUtil.getCorrelationID())) | ||
.body(BodyInserters.fromValue(body)) | ||
.retrieve() | ||
.onStatus(HttpStatusCode::is5xxServerError, | ||
clientResponse -> Mono.error(new ServiceException(getErrorMessage(url, SERVER_ERROR), clientResponse.statusCode().value()))) | ||
.bodyToMono(clazz) | ||
.retryWhen(Retry.backoff(3, Duration.ofSeconds(2)) | ||
.filter(ServiceException.class::isInstance) | ||
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> { | ||
throw new ServiceException(getErrorMessage(url, SERVICE_FAILED_ERROR), HttpStatus.SERVICE_UNAVAILABLE.value()); | ||
})) | ||
.block(); | ||
} catch (Exception e) { | ||
throw new ServiceException(getErrorMessage(url, e.getLocalizedMessage()), HttpStatus.SERVICE_UNAVAILABLE.value(), e); | ||
} | ||
return obj; | ||
} | ||
|
||
private String getErrorMessage(String url, String errorMessage) { | ||
return "Service failed to process at url: " + url + " due to: " + errorMessage; | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
api/src/main/java/ca/bc/gov/educ/api/gradbusiness/service/SchoolService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package ca.bc.gov.educ.api.gradbusiness.service; | ||
|
||
import ca.bc.gov.educ.api.gradbusiness.model.dto.School; | ||
import ca.bc.gov.educ.api.gradbusiness.util.EducGradBusinessApiConstants; | ||
import ca.bc.gov.educ.api.gradbusiness.util.JsonTransformer; | ||
import com.fasterxml.jackson.core.type.TypeReference; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.List; | ||
|
||
@Service | ||
public class SchoolService { | ||
EducGradBusinessApiConstants educGraduationApiConstants; | ||
RESTService restService; | ||
|
||
JsonTransformer jsonTransformer; | ||
@Autowired | ||
public SchoolService(EducGradBusinessApiConstants educGraduationApiConstants, RESTService restService, JsonTransformer jsonTransformer) { | ||
this.educGraduationApiConstants = educGraduationApiConstants; | ||
this.restService = restService; | ||
this.jsonTransformer = jsonTransformer; | ||
} | ||
|
||
public List<School> getSchoolDetails(String mincode) { | ||
var response = this.restService.get(String.format(educGraduationApiConstants.getSchoolDetails(),mincode), List.class); | ||
return jsonTransformer.convertValue(response, new TypeReference<>() {}); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.