方法扔了' org.springframework.beans.factory.support.scopenotactiveException'例外,当我尝试访问异步呼叫中的Singleton Bean时
我有一个httpbusinesscontext
的豆子。它的范围是请求。现在,当我尝试在同一类中的一个异步调用中访问它时。它抛出方法抛出'org.springframework.beans.factory.support.scopenotactiveException'exception>我在这里需要帮助,我该如何解决。我是否需要更改httpbusinesscontext
bean的范围,或者还有其他方法可以避免此问题。
这是我要获得的堆栈跟踪:
org.springframework.beans.factory.support.support.scopenotactiveException:错误创建使用名称'scopedtarget.gethttpthreadcontext':scope'的bean:scope'请求'的请求'对于当前线程而言并不活跃;如果您打算从单身人士来看,请考虑为此豆定义范围代理;嵌套例外是Java.lang.IlgalStateException:找不到线程键的请求:您是在实际Web请求之外引用请求属性,还是在最初接收线程之外处理请求?如果您实际上在Web请求中运行并仍会收到此消息,则您的代码可能在dispatcherservlet之外运行:在这种情况下,请使用requestContextListener或requestContextFilter揭示当前请求。
这是httpBusinessContext
类的Bean创建代码:
@Bean
@RequestScope
public HttpThreadBusinessContext getHttpThreadContext(){
return new HttpThreadBusinessContext();
}
这是代码:
/**
* This Service class will be used to handle business logic and complete processing if requestType = Details
*/
@Service
public class OrderDetailsRequestOperator {
private static final RxWrappedLogger logger = RxWrappedLogger.getWrappedLogger(OrderDetailsRequestOperator.class);
private static final AsyncRxWrappedLogger asyncWrappedLogger = AsyncRxWrappedLogger.getWrappedLogger(OrderDetailsRequestOperator.class);
private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
@Autowired
private HttpThreadBusinessContext httpThreadBusinessContext;
@Autowired
private SyncSapsRequestGateKeeper syncSapsRequestGateKeeper;
@Autowired
private FulfillmentOrderDtlRepo orderDtlRepo;
@ManagedConfiguration
private IRoutingConfig ccmManagedRoutingConfig;
@Autowired
private PatientRestrictionsCheckOperator patientRestrictionsCheckOperator;
@Autowired
private FulfillmentOrderRepo orderRepo;
/**
* Method to complete processing if requestType= Details
* @param request
* @return
*/
public OrderDetailsFulfillmentResponse processRequest(OrderDetailsFulfillmentRequest request) {
OrderDetailsFulfillmentResponse response;
OrderDetailsStoreResponse storeResponse;
/*
* post to store for order details
*/
try {
//set readyForPickup to true to always filter rx's that are in resolution
request.setIsReadyForPickup(true);
//Calling Downstream Store api for OrderDetail.
storeResponse = syncSapsRequestGateKeeper.retryAbleCall(request.getSiteNbr(),ccmManagedRoutingConfig.getOrderDetailsUrl(),getHttpHeaders(),
request,OrderDetailsStoreResponse.class);
response = OrderInfoUtil.buildOrderDetailsResponseFromStoreResponse(storeResponse);
response.setSiteNbr(request.getSiteNbr());
response.setCountryCode(request.getCountryCode());
response.setRequestType(request.getRequestType());
//check if order details were found
if(!storeResponse.getResponseCode().equals(Constants.SUCCESS_CODE)) {
return response;
}
logger.info(httpThreadBusinessContext,"Data Fetched successfully from SAPs");
//save order to fulfillment_order table with setting is_source_dotcom value
updateOrderInFulfillmentTable(storeResponse.getSiteNbr(),storeResponse.getOrderId(),storeResponse.getOrderDetails().getIsSourceDotcom());
} catch (Exception e) {
logger.error(httpThreadBusinessContext,"Error occurred during request to store", e);
return CommonUtil.getFailResponse(request, Constants.INTERNAL_SERVER_ERROR_CODE,Constants.PASSTHROUGH_REQUEST_ERROR_MSG);
}
/*
* Save order details to database
*/
try {
logger.info(httpThreadBusinessContext,"Going to save Order-dtl to DB");
//Saving Order-Detail to DB in case of Details request
saveOrderDtlToDB(request,storeResponse);
return response;
} catch(Exception e) {
logger.error(httpThreadBusinessContext,"Database error occurred saving Order Details", e);
return CommonUtil.getFailResponse(request, Constants.INTERNAL_SERVER_ERROR_CODE, Constants.DATABASE_ERROR_MSG);
}finally {
//populate patient flags asynchronously
if(storeResponse.getResponseCode().equals(Constants.SUCCESS_CODE)) {
this.updatePatientRestrictionsFlagAsync(response, storeResponse);
logger.debug(httpThreadBusinessContext, "patient restriction flgs updated");
}
}
}
/**
* this method starts a process in a separate thread to update value of has_paper_reduction flag in order_dtl table
* @param response
* @param storeResponse
*/
private void updatePatientRestrictionsFlagAsync(OrderDetailsFulfillmentResponse response, OrderDetailsStoreResponse storeResponse) {
logger.info(httpThreadBusinessContext,"updatePatientRestrictionsFlagAsync process initiated!");
// Run this process asynchronously so it can happen in the background
//calculate and update value of has_paper_reduction flag in DB for each Patient/order-Seq-Nbr
Integer storeNumber = response.getSiteNbr();
if(storeResponse != null && storeResponse.getOrderDetails() != null
&& storeResponse.getOrderDetails().getPatientDetails() != null){
for (StorePatientDetails patientDetails: storeResponse.getOrderDetails().getPatientDetails()) {
Integer patientId = patientDetails.getPatientId();
if(isIntegerGreaterThanZero(storeNumber) && isIntegerGreaterThanZero(patientId)){
// It should have been created in child thread instead oif parent thread as it is to be used in child thread.
final AsyncHttpThreadBusinessContext asyncHttpThreadBusinessContext = new AsyncHttpThreadBusinessContext(httpThreadBusinessContext);
CompletableFuture.supplyAsync(() -> {
return patientRestrictionsCheckOperator.getCloudPatientAPIResponse(storeNumber,patientId,asyncHttpThreadBusinessContext);
}).whenComplete((restrictList, t) -> { // child thread
// solution 1 :
// issue : The issue is that both threads are accessing same variable of logger and httpcontext at same time.
// i) convert the logger and context into bean.
// ii) create new object of looger and context every time in child thread.
// iii) change the scope of logger and context bean and set logger and context in interceptor the star tof request.
// create
// it should be there
if (restrictList != null) {
//Update the order details in the database with Has_paper_reduction flag.
boolean hasPaperReduced = patientRestrictionsCheckOperator.filterListByFLag(restrictList, RestrictionCode.HAS_PAPER_REDUCED.getKey(), asyncHttpThreadBusinessContext);
boolean isLargeFontLeaflet = patientRestrictionsCheckOperator.filterListByFLag(restrictList, RestrictionCode.LARGER_FONT_LEAFLET.getKey(), asyncHttpThreadBusinessContext);
boolean isVisuallyImpaired = patientRestrictionsCheckOperator.filterListByFLag(restrictList, RestrictionCode.VISUALLY_IMPAIRED.getKey(), asyncHttpThreadBusinessContext);
this.updatePatientRestrictionFlagsInOrderDtl(storeResponse.getOrderId(),storeNumber,
patientDetails,hasPaperReduced,isLargeFontLeaflet,isVisuallyImpaired,asyncHttpThreadBusinessContext);
asyncWrappedLogger.info(asyncHttpThreadBusinessContext,"updatePatientRestrictionFlagsAsync process completed ! has_paper_reduced : "+ restrictList);
logger.info(httpThreadBusinessContext,"updatePatientRestrictionFlagsAsync process completed ! has_paper_reduced : "+ restrictList);
}
});
}else{
logger.warn(httpThreadBusinessContext,"Error!Unable to compute patient restriction flags value,Invalid Params store:"+storeNumber+", patientID:"+patientId);
}
}
}
}
/**
* Save order Details to DB
* @param request
* @param response
*/
private void saveOrderDtlToDB(OrderDetailsFulfillmentRequest request, OrderDetailsStoreResponse response) {
//loop through length of patients list and nested loop through rx list. saving records on rx level
for (StorePatientDetails patient : response.getOrderDetails().getPatientDetails()) {
for(StoreRxDetails rx : patient.getRxDetails()) {
FulfillmentOrderDtlPK pk = new FulfillmentOrderDtlPK();
pk.setOrderId(request.getOrderId());
pk.setStoreNbr(request.getSiteNbr());
pk.setOrderSeqNbr(rx.getOrderSeqNbr());
FulfillmentOrderDtl row = new FulfillmentOrderDtl();
row.setOrderDtlPk(pk);
row.setPatientId(patient.getPatientId());
row.setFillSeqNbr(rx.getFillSeqNbr());
row.setRxFillId(rx.getRxFillId());
row.setRxNbr(rx.getRxNbr());
row.setRxPrice(rx.getRxPrice());
row.setPaymentComplete(false); // auto set to false here
row.setDrugCode(rx.getDrugCode());
row.setIsRefill(rx.getIsRefill()); // set value of isRefill to true or false
row.setPrefLangCode(response.getOrderDetails().getPatientDetails().get(0).getPreferredLanguage()); //only ever 1 patient in list
if(response.getOrderDetails().getCardOnFile()) {
row.setPaymentTypeCode(1); //1 for charge card, 2 for pay at register
}else {
row.setPaymentTypeCode(2);
}
orderDtlRepo.save(row);
}
}
}
/**
* Update the order details in the database with Has_paper_reduction flag
* @param orderId OrderID to be updated
* @param siteNbr StoreNumber
* @param patientDetails patient Details
* @param hasPaperReduction
* @param asyncHttpThreadBusinessContext asyncHttpThreadBusinessContext containing business info
*/
protected void updatePatientRestrictionFlagsInOrderDtl(String orderId,Integer siteNbr,StorePatientDetails patientDetails,Boolean hasPaperReduction,
Boolean isLargeFontLeaflet, Boolean isVisuallyImpaired, AsyncHttpThreadBusinessContext asyncHttpThreadBusinessContext) {
try {
List<FulfillmentOrderDtlPK> orderDetailsPkList = new ArrayList<>();
if(patientDetails != null && !patientDetails.getRxDetails().isEmpty()){
for (StoreRxDetails rxDetais : patientDetails.getRxDetails()) {
FulfillmentOrderDtlPK pk = new FulfillmentOrderDtlPK();
pk.setOrderId(orderId);
pk.setStoreNbr(siteNbr);
pk.setOrderSeqNbr(rxDetais.getOrderSeqNbr());
orderDetailsPkList.add(pk);
}
}
List<FulfillmentOrderDtl> orderDtlRows = orderDtlRepo.findAllById(orderDetailsPkList);
if (!orderDtlRows.isEmpty() && isUpdateRequired(hasPaperReduction, isLargeFontLeaflet, isVisuallyImpaired, orderDtlRows)){
orderDtlRepo.saveAll(orderDtlRows);
asyncWrappedLogger.info(asyncHttpThreadBusinessContext, "Order Details updated with patient restriction flags in Cloud SQL DB");
}
} catch (Exception e) {
asyncWrappedLogger.error(asyncHttpThreadBusinessContext,"Unable to update has_paper_reduction flag in order details in DB",e);
}
}
/**
* Validates if it needs to update flags containing restriction type codes value in the database
* @param hasPaperReduction flag to store restrictionTypeCode for paper reduction
* @param isLargeFontLeaflet flag to store restrictionTypeCode for large font leaflet
* @param isVisuallyImpaired flag to store restrictionTypeCode for visually Impaired indicator
* @param orderDtlRows order Details to be updated
*/
private boolean isUpdateRequired(Boolean hasPaperReduction, Boolean isLargeFontLeaflet, Boolean isVisuallyImpaired, List<FulfillmentOrderDtl> orderDtlRows) {
boolean updateRequired = false;
for (FulfillmentOrderDtl orderDtl: orderDtlRows) {
//update only if value is different
if (orderDtl.getHasPaperReduction() == null ||
!orderDtl.getHasPaperReduction().equals(hasPaperReduction)) {
orderDtl.setHasPaperReduction(hasPaperReduction);
updateRequired = true;
}
if (orderDtl.getIsLargeFontLeaflet() == null ||
!orderDtl.getIsLargeFontLeaflet().equals(isLargeFontLeaflet)) {
orderDtl.setIsLargeFontLeaflet(isLargeFontLeaflet);
updateRequired = true;
}
if (orderDtl.getIsVisuallyImpaired() == null ||
!orderDtl.getIsVisuallyImpaired().equals(isVisuallyImpaired)) {
orderDtl.setIsVisuallyImpaired(isVisuallyImpaired);
updateRequired = true;
}
}
return updateRequired;
}
/**
* this method updates the value of isSourceDotCom column in order fulfillment table.
* @param siteNbr
* @param orderId
* @param isSourceDotCom
*/
public int updateOrderInFulfillmentTable(Integer siteNbr, String orderId, Boolean isSourceDotCom) {
return orderRepo.updateisSourceDotcomColumnValue(isSourceDotCom,siteNbr, Integer.valueOf(orderId));
}
}
这是 httpbusinesscontext 类。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import
public class HttpThreadBusinessContext {
private Integer siteNbr;
private String countryCode;
private String endPoint;
private Object requestBody;
private Map<String, Object> requestIdentifier = new HashMap();
private String correlationId;
public HttpThreadBusinessContext() {
}
public Integer getSiteNbr() {
return this.siteNbr;
}
public String getCountryCode() {
return this.countryCode;
}
public String getEndPoint() {
return this.endPoint;
}
public Object getRequestBody() {
return this.requestBody;
}
public Map<String, Object> getRequestIdentifier() {
return this.requestIdentifier;
}
public String getCorrelationId() {
return this.correlationId;
}
public void setSiteNbr(Integer siteNbr) {
this.siteNbr = siteNbr;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public void setEndPoint(String endPoint) {
this.endPoint = endPoint;
}
public void setRequestBody(Object requestBody) {
this.requestBody = requestBody;
}
public void setRequestIdentifier(Map<String, Object> requestIdentifier) {
this.requestIdentifier = requestIdentifier;
}
public void setCorrelationId(String correlationId) {
this.correlationId = correlationId;
}
public InfoLog getInfoLog(String logMessage, Integer responseCode, String responseText) {
InfoLog infoLog = new InfoLog(logMessage, (Object)null, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, (Map)null);
infoLog.setCorrelationId(this.correlationId);
return infoLog;
}
public InfoLog getInfoLog(String logMessage) {
InfoLog infoLog = new InfoLog(logMessage, (Object)null, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null);
infoLog.setCorrelationId(this.correlationId);
return infoLog;
}
public InfoLog getInfoLog(String logMessage, Map<String, Object> infoLogIdentifier) {
InfoLog infoLog = new InfoLog(logMessage, (Object)null, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, infoLogIdentifier);
infoLog.setCorrelationId(this.correlationId);
return infoLog;
}
public InfoLog getInfoLog(String logMessage, Integer responseCode, String responseText, Map<String, Object> infoLogIdentifier) {
InfoLog infoLog = new InfoLog(logMessage, (Object)null, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, infoLogIdentifier);
infoLog.setCorrelationId(this.correlationId);
return infoLog;
}
public ErrorLog getErrorLog(String logMessage, Integer responseCode, String responseText, Exception exception) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, (Map)null, exception, (Map)null, (Map)null);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage, Integer responseCode, String responseText) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, (Map)null, (Exception)null, (Map)null, (Map)null);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, (Exception)null, (Map)null, (Map)null);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage, Exception exception) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, exception, (Map)null, (Map)null);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage, Exception exception, Map<String, Object> errorLogIdentifier) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, exception, (Map)null, errorLogIdentifier);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage, Integer responseCode, String responseText, Exception exception, Map<String, Object> errorLogIdentifier) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, (Map)null, exception, (Map)null, errorLogIdentifier);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage, Integer responseCode, String responseText, Map<String, Object> errorLogIdentifier) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, (Map)null, (Exception)null, (Map)null, errorLogIdentifier);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public DownStreamApiCallLog getDownStreamApiCallLog(long timeTakenInMillis, String downStreamApiUrl, Object downStreamRequestPayload, Object downStreamResponsePayload) {
DownStreamApiCallLog downStreamApiCallLog = new DownStreamApiCallLog((String)null, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, timeTakenInMillis, downStreamApiUrl, (Object)null, downStreamRequestPayload, downStreamResponsePayload, (String)null);
downStreamApiCallLog.setCorrelationId(this.correlationId);
return downStreamApiCallLog;
}
public DownStreamApiCallLog getDownStreamApiCallLog(long timeTakenInMillis, String downStreamApiUrl, Object identificationFields) {
DownStreamApiCallLog downStreamApiCallLog = new DownStreamApiCallLog((String)null, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, timeTakenInMillis, downStreamApiUrl, identificationFields, (Object)null, (Object)null, (String)null);
downStreamApiCallLog.setCorrelationId(this.correlationId);
return downStreamApiCallLog;
}
public DownStreamApiCallLog getDownStreamApiCallLog(long timeTakenInMillis, String downStreamApiUrl, Object identificationFields, String responseDetail) {
DownStreamApiCallLog downStreamApiCallLog = new DownStreamApiCallLog((String)null, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, timeTakenInMillis, downStreamApiUrl, identificationFields, (Object)null, (Object)null, responseDetail);
downStreamApiCallLog.setCorrelationId(this.correlationId);
return downStreamApiCallLog;
}
public DebugLog getDebugLog(String message) {
DebugLog debugLog = new DebugLog(message, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (String)null, (Map)null);
debugLog.setCorrelationId(this.correlationId);
return debugLog;
}
public DebugLog getDebugLog(String message, Object responseBody) {
DebugLog debugLog = new DebugLog(message, this.requestBody, responseBody, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (String)null, (Map)null);
debugLog.setCorrelationId(this.correlationId);
return debugLog;
}
public DebugLog getDebugLog(String message, Map<String, Object> debugLogIdentifier) {
DebugLog debugLog = new DebugLog(message, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (String)null, debugLogIdentifier);
debugLog.setCorrelationId(this.correlationId);
return debugLog;
}
public DebugLog getDebugLog(String message, Object requestBody, Object responseBody, Map<String, Object> debugLogIdentifier) {
DebugLog debugLog = new DebugLog(message, requestBody, requestBody, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (String)null, debugLogIdentifier);
debugLog.setCorrelationId(this.correlationId);
return debugLog;
}
public WarnLog getWarnLog(String message) {
WarnLog warnLog = new WarnLog(message, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, (Exception)null, (Map)null);
warnLog.setCorrelationId(this.correlationId);
return warnLog;
}
public WarnLog getWarnLog(String message, Exception exception) {
WarnLog warnLog = new WarnLog(message, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, exception, (Map)null);
warnLog.setCorrelationId(this.correlationId);
return warnLog;
}
public WarnLog getWarnLog(String message, Exception exception, Map<String, Object> warnLogIdentifier) {
WarnLog warnLog = new WarnLog(message, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, exception, warnLogIdentifier);
warnLog.setCorrelationId(this.correlationId);
return warnLog;
}
public void setBusinessInfo(String countryCode, String endPoint, Integer siteNbr, Object requestPayload, Map<String, Object> requestIdentifier) {
this.setCountryCode(countryCode);
this.setEndPoint(endPoint);
this.setSiteNbr(siteNbr);
this.setRequestBody(requestPayload);
this.setRequestIdentifier(requestIdentifier);
}
public void setBusinessInfo(String countryCode, String endPoint, Integer siteNbr, Map<String, Object> requestIdentifier) {
this.setCountryCode(countryCode);
this.setEndPoint(endPoint);
this.setSiteNbr(siteNbr);
this.setRequestIdentifier(requestIdentifier);
}
}
I have a bean of Httpbusinesscontext
at class level. It's scope is request. Now when I try to access it in one of the async call in same class. It throws Method threw 'org.springframework.beans.factory.support.ScopeNotActiveException' exception> I need help here that how can I resolve it. Do I need to change the scope of Httpbusinesscontext
bean or there is some other way through which I can avoid this issue.
Here is the stack trace I am getting:
org.springframework.beans.factory.support.ScopeNotActiveException: Error creating bean with name 'scopedTarget.getHttpThreadContext': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
Here is the code of bean creation for Httpbusinesscontext
class:
@Bean
@RequestScope
public HttpThreadBusinessContext getHttpThreadContext(){
return new HttpThreadBusinessContext();
}
Here is the code:
/**
* This Service class will be used to handle business logic and complete processing if requestType = Details
*/
@Service
public class OrderDetailsRequestOperator {
private static final RxWrappedLogger logger = RxWrappedLogger.getWrappedLogger(OrderDetailsRequestOperator.class);
private static final AsyncRxWrappedLogger asyncWrappedLogger = AsyncRxWrappedLogger.getWrappedLogger(OrderDetailsRequestOperator.class);
private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
@Autowired
private HttpThreadBusinessContext httpThreadBusinessContext;
@Autowired
private SyncSapsRequestGateKeeper syncSapsRequestGateKeeper;
@Autowired
private FulfillmentOrderDtlRepo orderDtlRepo;
@ManagedConfiguration
private IRoutingConfig ccmManagedRoutingConfig;
@Autowired
private PatientRestrictionsCheckOperator patientRestrictionsCheckOperator;
@Autowired
private FulfillmentOrderRepo orderRepo;
/**
* Method to complete processing if requestType= Details
* @param request
* @return
*/
public OrderDetailsFulfillmentResponse processRequest(OrderDetailsFulfillmentRequest request) {
OrderDetailsFulfillmentResponse response;
OrderDetailsStoreResponse storeResponse;
/*
* post to store for order details
*/
try {
//set readyForPickup to true to always filter rx's that are in resolution
request.setIsReadyForPickup(true);
//Calling Downstream Store api for OrderDetail.
storeResponse = syncSapsRequestGateKeeper.retryAbleCall(request.getSiteNbr(),ccmManagedRoutingConfig.getOrderDetailsUrl(),getHttpHeaders(),
request,OrderDetailsStoreResponse.class);
response = OrderInfoUtil.buildOrderDetailsResponseFromStoreResponse(storeResponse);
response.setSiteNbr(request.getSiteNbr());
response.setCountryCode(request.getCountryCode());
response.setRequestType(request.getRequestType());
//check if order details were found
if(!storeResponse.getResponseCode().equals(Constants.SUCCESS_CODE)) {
return response;
}
logger.info(httpThreadBusinessContext,"Data Fetched successfully from SAPs");
//save order to fulfillment_order table with setting is_source_dotcom value
updateOrderInFulfillmentTable(storeResponse.getSiteNbr(),storeResponse.getOrderId(),storeResponse.getOrderDetails().getIsSourceDotcom());
} catch (Exception e) {
logger.error(httpThreadBusinessContext,"Error occurred during request to store", e);
return CommonUtil.getFailResponse(request, Constants.INTERNAL_SERVER_ERROR_CODE,Constants.PASSTHROUGH_REQUEST_ERROR_MSG);
}
/*
* Save order details to database
*/
try {
logger.info(httpThreadBusinessContext,"Going to save Order-dtl to DB");
//Saving Order-Detail to DB in case of Details request
saveOrderDtlToDB(request,storeResponse);
return response;
} catch(Exception e) {
logger.error(httpThreadBusinessContext,"Database error occurred saving Order Details", e);
return CommonUtil.getFailResponse(request, Constants.INTERNAL_SERVER_ERROR_CODE, Constants.DATABASE_ERROR_MSG);
}finally {
//populate patient flags asynchronously
if(storeResponse.getResponseCode().equals(Constants.SUCCESS_CODE)) {
this.updatePatientRestrictionsFlagAsync(response, storeResponse);
logger.debug(httpThreadBusinessContext, "patient restriction flgs updated");
}
}
}
/**
* this method starts a process in a separate thread to update value of has_paper_reduction flag in order_dtl table
* @param response
* @param storeResponse
*/
private void updatePatientRestrictionsFlagAsync(OrderDetailsFulfillmentResponse response, OrderDetailsStoreResponse storeResponse) {
logger.info(httpThreadBusinessContext,"updatePatientRestrictionsFlagAsync process initiated!");
// Run this process asynchronously so it can happen in the background
//calculate and update value of has_paper_reduction flag in DB for each Patient/order-Seq-Nbr
Integer storeNumber = response.getSiteNbr();
if(storeResponse != null && storeResponse.getOrderDetails() != null
&& storeResponse.getOrderDetails().getPatientDetails() != null){
for (StorePatientDetails patientDetails: storeResponse.getOrderDetails().getPatientDetails()) {
Integer patientId = patientDetails.getPatientId();
if(isIntegerGreaterThanZero(storeNumber) && isIntegerGreaterThanZero(patientId)){
// It should have been created in child thread instead oif parent thread as it is to be used in child thread.
final AsyncHttpThreadBusinessContext asyncHttpThreadBusinessContext = new AsyncHttpThreadBusinessContext(httpThreadBusinessContext);
CompletableFuture.supplyAsync(() -> {
return patientRestrictionsCheckOperator.getCloudPatientAPIResponse(storeNumber,patientId,asyncHttpThreadBusinessContext);
}).whenComplete((restrictList, t) -> { // child thread
// solution 1 :
// issue : The issue is that both threads are accessing same variable of logger and httpcontext at same time.
// i) convert the logger and context into bean.
// ii) create new object of looger and context every time in child thread.
// iii) change the scope of logger and context bean and set logger and context in interceptor the star tof request.
// create
// it should be there
if (restrictList != null) {
//Update the order details in the database with Has_paper_reduction flag.
boolean hasPaperReduced = patientRestrictionsCheckOperator.filterListByFLag(restrictList, RestrictionCode.HAS_PAPER_REDUCED.getKey(), asyncHttpThreadBusinessContext);
boolean isLargeFontLeaflet = patientRestrictionsCheckOperator.filterListByFLag(restrictList, RestrictionCode.LARGER_FONT_LEAFLET.getKey(), asyncHttpThreadBusinessContext);
boolean isVisuallyImpaired = patientRestrictionsCheckOperator.filterListByFLag(restrictList, RestrictionCode.VISUALLY_IMPAIRED.getKey(), asyncHttpThreadBusinessContext);
this.updatePatientRestrictionFlagsInOrderDtl(storeResponse.getOrderId(),storeNumber,
patientDetails,hasPaperReduced,isLargeFontLeaflet,isVisuallyImpaired,asyncHttpThreadBusinessContext);
asyncWrappedLogger.info(asyncHttpThreadBusinessContext,"updatePatientRestrictionFlagsAsync process completed ! has_paper_reduced : "+ restrictList);
logger.info(httpThreadBusinessContext,"updatePatientRestrictionFlagsAsync process completed ! has_paper_reduced : "+ restrictList);
}
});
}else{
logger.warn(httpThreadBusinessContext,"Error!Unable to compute patient restriction flags value,Invalid Params store:"+storeNumber+", patientID:"+patientId);
}
}
}
}
/**
* Save order Details to DB
* @param request
* @param response
*/
private void saveOrderDtlToDB(OrderDetailsFulfillmentRequest request, OrderDetailsStoreResponse response) {
//loop through length of patients list and nested loop through rx list. saving records on rx level
for (StorePatientDetails patient : response.getOrderDetails().getPatientDetails()) {
for(StoreRxDetails rx : patient.getRxDetails()) {
FulfillmentOrderDtlPK pk = new FulfillmentOrderDtlPK();
pk.setOrderId(request.getOrderId());
pk.setStoreNbr(request.getSiteNbr());
pk.setOrderSeqNbr(rx.getOrderSeqNbr());
FulfillmentOrderDtl row = new FulfillmentOrderDtl();
row.setOrderDtlPk(pk);
row.setPatientId(patient.getPatientId());
row.setFillSeqNbr(rx.getFillSeqNbr());
row.setRxFillId(rx.getRxFillId());
row.setRxNbr(rx.getRxNbr());
row.setRxPrice(rx.getRxPrice());
row.setPaymentComplete(false); // auto set to false here
row.setDrugCode(rx.getDrugCode());
row.setIsRefill(rx.getIsRefill()); // set value of isRefill to true or false
row.setPrefLangCode(response.getOrderDetails().getPatientDetails().get(0).getPreferredLanguage()); //only ever 1 patient in list
if(response.getOrderDetails().getCardOnFile()) {
row.setPaymentTypeCode(1); //1 for charge card, 2 for pay at register
}else {
row.setPaymentTypeCode(2);
}
orderDtlRepo.save(row);
}
}
}
/**
* Update the order details in the database with Has_paper_reduction flag
* @param orderId OrderID to be updated
* @param siteNbr StoreNumber
* @param patientDetails patient Details
* @param hasPaperReduction
* @param asyncHttpThreadBusinessContext asyncHttpThreadBusinessContext containing business info
*/
protected void updatePatientRestrictionFlagsInOrderDtl(String orderId,Integer siteNbr,StorePatientDetails patientDetails,Boolean hasPaperReduction,
Boolean isLargeFontLeaflet, Boolean isVisuallyImpaired, AsyncHttpThreadBusinessContext asyncHttpThreadBusinessContext) {
try {
List<FulfillmentOrderDtlPK> orderDetailsPkList = new ArrayList<>();
if(patientDetails != null && !patientDetails.getRxDetails().isEmpty()){
for (StoreRxDetails rxDetais : patientDetails.getRxDetails()) {
FulfillmentOrderDtlPK pk = new FulfillmentOrderDtlPK();
pk.setOrderId(orderId);
pk.setStoreNbr(siteNbr);
pk.setOrderSeqNbr(rxDetais.getOrderSeqNbr());
orderDetailsPkList.add(pk);
}
}
List<FulfillmentOrderDtl> orderDtlRows = orderDtlRepo.findAllById(orderDetailsPkList);
if (!orderDtlRows.isEmpty() && isUpdateRequired(hasPaperReduction, isLargeFontLeaflet, isVisuallyImpaired, orderDtlRows)){
orderDtlRepo.saveAll(orderDtlRows);
asyncWrappedLogger.info(asyncHttpThreadBusinessContext, "Order Details updated with patient restriction flags in Cloud SQL DB");
}
} catch (Exception e) {
asyncWrappedLogger.error(asyncHttpThreadBusinessContext,"Unable to update has_paper_reduction flag in order details in DB",e);
}
}
/**
* Validates if it needs to update flags containing restriction type codes value in the database
* @param hasPaperReduction flag to store restrictionTypeCode for paper reduction
* @param isLargeFontLeaflet flag to store restrictionTypeCode for large font leaflet
* @param isVisuallyImpaired flag to store restrictionTypeCode for visually Impaired indicator
* @param orderDtlRows order Details to be updated
*/
private boolean isUpdateRequired(Boolean hasPaperReduction, Boolean isLargeFontLeaflet, Boolean isVisuallyImpaired, List<FulfillmentOrderDtl> orderDtlRows) {
boolean updateRequired = false;
for (FulfillmentOrderDtl orderDtl: orderDtlRows) {
//update only if value is different
if (orderDtl.getHasPaperReduction() == null ||
!orderDtl.getHasPaperReduction().equals(hasPaperReduction)) {
orderDtl.setHasPaperReduction(hasPaperReduction);
updateRequired = true;
}
if (orderDtl.getIsLargeFontLeaflet() == null ||
!orderDtl.getIsLargeFontLeaflet().equals(isLargeFontLeaflet)) {
orderDtl.setIsLargeFontLeaflet(isLargeFontLeaflet);
updateRequired = true;
}
if (orderDtl.getIsVisuallyImpaired() == null ||
!orderDtl.getIsVisuallyImpaired().equals(isVisuallyImpaired)) {
orderDtl.setIsVisuallyImpaired(isVisuallyImpaired);
updateRequired = true;
}
}
return updateRequired;
}
/**
* this method updates the value of isSourceDotCom column in order fulfillment table.
* @param siteNbr
* @param orderId
* @param isSourceDotCom
*/
public int updateOrderInFulfillmentTable(Integer siteNbr, String orderId, Boolean isSourceDotCom) {
return orderRepo.updateisSourceDotcomColumnValue(isSourceDotCom,siteNbr, Integer.valueOf(orderId));
}
}
and here is the HttpBusinessContext class.
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import
public class HttpThreadBusinessContext {
private Integer siteNbr;
private String countryCode;
private String endPoint;
private Object requestBody;
private Map<String, Object> requestIdentifier = new HashMap();
private String correlationId;
public HttpThreadBusinessContext() {
}
public Integer getSiteNbr() {
return this.siteNbr;
}
public String getCountryCode() {
return this.countryCode;
}
public String getEndPoint() {
return this.endPoint;
}
public Object getRequestBody() {
return this.requestBody;
}
public Map<String, Object> getRequestIdentifier() {
return this.requestIdentifier;
}
public String getCorrelationId() {
return this.correlationId;
}
public void setSiteNbr(Integer siteNbr) {
this.siteNbr = siteNbr;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public void setEndPoint(String endPoint) {
this.endPoint = endPoint;
}
public void setRequestBody(Object requestBody) {
this.requestBody = requestBody;
}
public void setRequestIdentifier(Map<String, Object> requestIdentifier) {
this.requestIdentifier = requestIdentifier;
}
public void setCorrelationId(String correlationId) {
this.correlationId = correlationId;
}
public InfoLog getInfoLog(String logMessage, Integer responseCode, String responseText) {
InfoLog infoLog = new InfoLog(logMessage, (Object)null, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, (Map)null);
infoLog.setCorrelationId(this.correlationId);
return infoLog;
}
public InfoLog getInfoLog(String logMessage) {
InfoLog infoLog = new InfoLog(logMessage, (Object)null, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null);
infoLog.setCorrelationId(this.correlationId);
return infoLog;
}
public InfoLog getInfoLog(String logMessage, Map<String, Object> infoLogIdentifier) {
InfoLog infoLog = new InfoLog(logMessage, (Object)null, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, infoLogIdentifier);
infoLog.setCorrelationId(this.correlationId);
return infoLog;
}
public InfoLog getInfoLog(String logMessage, Integer responseCode, String responseText, Map<String, Object> infoLogIdentifier) {
InfoLog infoLog = new InfoLog(logMessage, (Object)null, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, infoLogIdentifier);
infoLog.setCorrelationId(this.correlationId);
return infoLog;
}
public ErrorLog getErrorLog(String logMessage, Integer responseCode, String responseText, Exception exception) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, (Map)null, exception, (Map)null, (Map)null);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage, Integer responseCode, String responseText) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, (Map)null, (Exception)null, (Map)null, (Map)null);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, (Exception)null, (Map)null, (Map)null);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage, Exception exception) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, exception, (Map)null, (Map)null);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage, Exception exception, Map<String, Object> errorLogIdentifier) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, exception, (Map)null, errorLogIdentifier);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage, Integer responseCode, String responseText, Exception exception, Map<String, Object> errorLogIdentifier) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, (Map)null, exception, (Map)null, errorLogIdentifier);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public ErrorLog getErrorLog(String logMessage, Integer responseCode, String responseText, Map<String, Object> errorLogIdentifier) {
ErrorLog errorLog = new ErrorLog(logMessage, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, responseCode, responseText, (Map)null, (Exception)null, (Map)null, errorLogIdentifier);
errorLog.setCorrelationId(this.correlationId);
return errorLog;
}
public DownStreamApiCallLog getDownStreamApiCallLog(long timeTakenInMillis, String downStreamApiUrl, Object downStreamRequestPayload, Object downStreamResponsePayload) {
DownStreamApiCallLog downStreamApiCallLog = new DownStreamApiCallLog((String)null, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, timeTakenInMillis, downStreamApiUrl, (Object)null, downStreamRequestPayload, downStreamResponsePayload, (String)null);
downStreamApiCallLog.setCorrelationId(this.correlationId);
return downStreamApiCallLog;
}
public DownStreamApiCallLog getDownStreamApiCallLog(long timeTakenInMillis, String downStreamApiUrl, Object identificationFields) {
DownStreamApiCallLog downStreamApiCallLog = new DownStreamApiCallLog((String)null, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, timeTakenInMillis, downStreamApiUrl, identificationFields, (Object)null, (Object)null, (String)null);
downStreamApiCallLog.setCorrelationId(this.correlationId);
return downStreamApiCallLog;
}
public DownStreamApiCallLog getDownStreamApiCallLog(long timeTakenInMillis, String downStreamApiUrl, Object identificationFields, String responseDetail) {
DownStreamApiCallLog downStreamApiCallLog = new DownStreamApiCallLog((String)null, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, timeTakenInMillis, downStreamApiUrl, identificationFields, (Object)null, (Object)null, responseDetail);
downStreamApiCallLog.setCorrelationId(this.correlationId);
return downStreamApiCallLog;
}
public DebugLog getDebugLog(String message) {
DebugLog debugLog = new DebugLog(message, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (String)null, (Map)null);
debugLog.setCorrelationId(this.correlationId);
return debugLog;
}
public DebugLog getDebugLog(String message, Object responseBody) {
DebugLog debugLog = new DebugLog(message, this.requestBody, responseBody, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (String)null, (Map)null);
debugLog.setCorrelationId(this.correlationId);
return debugLog;
}
public DebugLog getDebugLog(String message, Map<String, Object> debugLogIdentifier) {
DebugLog debugLog = new DebugLog(message, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (String)null, debugLogIdentifier);
debugLog.setCorrelationId(this.correlationId);
return debugLog;
}
public DebugLog getDebugLog(String message, Object requestBody, Object responseBody, Map<String, Object> debugLogIdentifier) {
DebugLog debugLog = new DebugLog(message, requestBody, requestBody, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (String)null, debugLogIdentifier);
debugLog.setCorrelationId(this.correlationId);
return debugLog;
}
public WarnLog getWarnLog(String message) {
WarnLog warnLog = new WarnLog(message, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, (Exception)null, (Map)null);
warnLog.setCorrelationId(this.correlationId);
return warnLog;
}
public WarnLog getWarnLog(String message, Exception exception) {
WarnLog warnLog = new WarnLog(message, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, exception, (Map)null);
warnLog.setCorrelationId(this.correlationId);
return warnLog;
}
public WarnLog getWarnLog(String message, Exception exception, Map<String, Object> warnLogIdentifier) {
WarnLog warnLog = new WarnLog(message, this.requestBody, (Object)null, this.siteNbr, this.countryCode, this.endPoint, this.requestIdentifier, (Integer)null, (String)null, (Map)null, exception, warnLogIdentifier);
warnLog.setCorrelationId(this.correlationId);
return warnLog;
}
public void setBusinessInfo(String countryCode, String endPoint, Integer siteNbr, Object requestPayload, Map<String, Object> requestIdentifier) {
this.setCountryCode(countryCode);
this.setEndPoint(endPoint);
this.setSiteNbr(siteNbr);
this.setRequestBody(requestPayload);
this.setRequestIdentifier(requestIdentifier);
}
public void setBusinessInfo(String countryCode, String endPoint, Integer siteNbr, Map<String, Object> requestIdentifier) {
this.setCountryCode(countryCode);
this.setEndPoint(endPoint);
this.setSiteNbr(siteNbr);
this.setRequestIdentifier(requestIdentifier);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论