update code and update esb proxy function

This commit is contained in:
Mauve
2026-09-22 17:15:07 +08:00
parent 3700d7c5d5
commit 22023afef9
8 changed files with 171 additions and 122 deletions
@@ -2,11 +2,17 @@ package com.mgm.mcrm.apigateway.common.listener;
import com.mgm.mcrm.apigateway.allotment.services.RoomCriteriaDaylightService; import com.mgm.mcrm.apigateway.allotment.services.RoomCriteriaDaylightService;
import com.mgm.mcrm.apigateway.common.constants.SysCommon; import com.mgm.mcrm.apigateway.common.constants.SysCommon;
import com.mgm.mcrm.apigateway.common.utils.NotificationUtil;
import com.mgm.mcrm.apigateway.daylight.repositories.CfgCompRuleDao;
import com.mgm.mcrm.apigateway.daylight.services.DaylightApiService; import com.mgm.mcrm.apigateway.daylight.services.DaylightApiService;
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.AvailableRoomCountUpdatedHandler; import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.AvailableRoomCountUpdatedHandler;
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.CompRuleLimitsExceededChangedHandler;
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.ReservationNotificationHandler; import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.ReservationNotificationHandler;
import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.RoomTypeDateAvailabilityChangedHandler; import com.mgm.mcrm.apigateway.daylight.webhook.eventhandlers.impl.RoomTypeDateAvailabilityChangedHandler;
import com.mgm.mcrm.apigateway.daylight.webhook.services.DaylightWebhookFactory; import com.mgm.mcrm.apigateway.daylight.webhook.services.DaylightWebhookFactory;
import com.mgm.mcrm.apigateway.logging.dao.SysLogDeviceTokenRepository;
import com.mgm.mcrm.apigateway.notification.services.ApnNotificationService;
import com.mgm.mcrm.apigateway.reservation.repositories.BookingDao;
import com.mgm.mcrm.apigateway.reservation.services.BookingService; import com.mgm.mcrm.apigateway.reservation.services.BookingService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.boot.context.event.ApplicationStartedEvent;
@@ -22,6 +28,16 @@ public class ConfigListener implements ApplicationListener<ApplicationStartedEve
private BookingService bookingService; private BookingService bookingService;
@Resource @Resource
private DaylightApiService daylightApiService; private DaylightApiService daylightApiService;
@Resource
private CfgCompRuleDao cfgCompRuleDao;
@Resource
private BookingDao bookingDao;
@Resource
private SysLogDeviceTokenRepository sysLogDeviceTokenRepository;
@Resource
private NotificationUtil notificationUtil;
@Resource
private ApnNotificationService apnNotificationService;
@Override @Override
public void onApplicationEvent(ApplicationStartedEvent event) { public void onApplicationEvent(ApplicationStartedEvent event) {
@@ -32,5 +48,16 @@ public class ConfigListener implements ApplicationListener<ApplicationStartedEve
DaylightWebhookFactory.registerHandler("AvailableRoomCountUpdated", new AvailableRoomCountUpdatedHandler(roomCriteriaDaylightService)); DaylightWebhookFactory.registerHandler("AvailableRoomCountUpdated", new AvailableRoomCountUpdatedHandler(roomCriteriaDaylightService));
//--Register Reservation Notification handlers //--Register Reservation Notification handlers
DaylightWebhookFactory.registerHandler("ReservationNotification", new ReservationNotificationHandler(bookingService, daylightApiService)); DaylightWebhookFactory.registerHandler("ReservationNotification", new ReservationNotificationHandler(bookingService, daylightApiService));
DaylightWebhookFactory.registerHandler(
"ComplimentaryRuleLimitsExceededChangedNotification",
new CompRuleLimitsExceededChangedHandler(
cfgCompRuleDao,
bookingDao,
sysLogDeviceTokenRepository,
notificationUtil,
apnNotificationService,
daylightApiService
)
);
} }
} }
@@ -41,25 +41,8 @@ public class HttpService {
public String sslGet(String url, Header[] headers, Map<String, Object> map) throws Exception { public String sslGet(String url, Header[] headers, Map<String, Object> map) throws Exception {
log.info("======sslGet======url:{}===========headers:{} =============== map:{}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(map));
// 使用 HttpConfig 配置 GET 请求(带参数)
HttpRequestOptions getConfig = HttpRequestOptions.create()
.url(daylightUrl + url)
.timeout(requestConfig)
.map(map)
.encoding("utf-8")
.client(httpClient);
String result = HttpClientExecutor.get(getConfig, headers);
log.info("====== GET request result size:{}", result.length());
return result;
}
public String sslGetNoLog(String url, Header[] headers, Map<String, Object> map) throws Exception {
// todo 在這裏需要把請求頭的信息插入到數據庫裏 // todo 在這裏需要把請求頭的信息插入到數據庫裏
log.info("======sslGet======url:{}===========headers:{} =============== map:{}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(map)); log.info("GET method, url={}, headers={}, map={}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(map));
// 使用 HttpConfig 配置 GET 请求(带参数) // 使用 HttpConfig 配置 GET 请求(带参数)
HttpRequestOptions getConfig = HttpRequestOptions.create() HttpRequestOptions getConfig = HttpRequestOptions.create()
.url(daylightUrl + url) .url(daylightUrl + url)
@@ -69,7 +52,7 @@ public class HttpService {
.client(httpClient); .client(httpClient);
String result = HttpClientExecutor.get(getConfig, headers); String result = HttpClientExecutor.get(getConfig, headers);
log.info("====== GET request result size={}", result.length()); log.info("GET request result size={}", result);
return result; return result;
} }
@@ -77,7 +60,7 @@ public class HttpService {
public HttpResult sslGetHttpResult(String url, Header[] headers, Map<String, Object> map) throws Exception { public HttpResult sslGetHttpResult(String url, Header[] headers, Map<String, Object> map) throws Exception {
// todo 在這裏需要把請求頭的信息插入到數據庫裏 // todo 在這裏需要把請求頭的信息插入到數據庫裏
log.info("======sslGet======url:{}===========headers:{} =============== map:{}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(map)); log.info("GET method, url={}, headers={}, map={}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(map));
// 使用 HttpConfig 配置 GET 请求(带参数) // 使用 HttpConfig 配置 GET 请求(带参数)
HttpRequestOptions getConfig = HttpRequestOptions.create() HttpRequestOptions getConfig = HttpRequestOptions.create()
.url(daylightUrl + url) .url(daylightUrl + url)
@@ -87,7 +70,7 @@ public class HttpService {
.client(httpClient); .client(httpClient);
HttpResult result = HttpClientExecutor.sendAndGetResp(getConfig, headers); HttpResult result = HttpClientExecutor.sendAndGetResp(getConfig, headers);
log.info("====== GET request result:{}", result.getResult()); log.info("GET request result size={}", result.getResult().length());
return result; return result;
} }
@@ -102,7 +85,7 @@ public class HttpService {
* @throws Exception 異常 * @throws Exception 異常
*/ */
public String sslPut(String url, Header[] headers, Map<String, Object> map) throws Exception { public String sslPut(String url, Header[] headers, Map<String, Object> map) throws Exception {
log.info("======sslPut======url:{}===========headers:{} =============== map:{}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(map)); log.info("PUT method, url={}, headers={}, map={}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(map));
HttpRequestOptions putConfig = HttpRequestOptions.create() HttpRequestOptions putConfig = HttpRequestOptions.create()
.url(daylightUrl + url) .url(daylightUrl + url)
.timeout(requestConfig) .timeout(requestConfig)
@@ -111,7 +94,7 @@ public class HttpService {
.encoding("utf-8") .encoding("utf-8")
.client(httpClient); .client(httpClient);
String result = HttpClientExecutor.send(putConfig, headers); String result = HttpClientExecutor.send(putConfig, headers);
log.info("====== PUT request result:{}", result); log.info("PUT request result={}", result);
return result; return result;
} }
@@ -126,7 +109,7 @@ public class HttpService {
* @throws Exception 異常 * @throws Exception 異常
*/ */
public String sslDelete(String url, Header[] headers, Object requestBody) throws Exception { public String sslDelete(String url, Header[] headers, Object requestBody) throws Exception {
log.info("======sslDelete======url:{}===========headers:{} =============== map:{}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(requestBody)); log.info("DELETE method, url={}, headers={}, map={}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(requestBody));
HttpRequestOptions deleteConfig = HttpRequestOptions.create() HttpRequestOptions deleteConfig = HttpRequestOptions.create()
.url(daylightUrl + url) .url(daylightUrl + url)
.timeout(requestConfig) .timeout(requestConfig)
@@ -134,7 +117,7 @@ public class HttpService {
.method(HttpMethods.DELETE) .method(HttpMethods.DELETE)
.client(httpClient); .client(httpClient);
String result = HttpClientExecutor.send(deleteConfig, headers); String result = HttpClientExecutor.send(deleteConfig, headers);
log.info("====== DELETE request result:{}", result); log.info("DELETE request result={}", result);
return result; return result;
} }
@@ -148,7 +131,7 @@ public class HttpService {
* @throws Exception 異常 * @throws Exception 異常
*/ */
public HttpResult sslPost(String url, Header[] headers, Object requestBody) throws Exception { public HttpResult sslPost(String url, Header[] headers, Object requestBody) throws Exception {
log.info("======sslCreatePost======url:{}===========headers:{}", daylightUrl + url, JSON.toJSONString(headers)); log.info("POST method, url={}, headers={}, map={}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(requestBody));
HttpRequestOptions postConfig = HttpRequestOptions.create() HttpRequestOptions postConfig = HttpRequestOptions.create()
.url(daylightUrl + url) .url(daylightUrl + url)
.timeout(requestConfig) .timeout(requestConfig)
@@ -157,7 +140,7 @@ public class HttpService {
.client(httpClient); .client(httpClient);
HttpResult result = HttpClientExecutor.sendAndPostResp(postConfig, headers); HttpResult result = HttpClientExecutor.sendAndPostResp(postConfig, headers);
// System.out.println("POST 请求结果:\n" + result); // System.out.println("POST 请求结果:\n" + result);
log.info("====== POST request result:{}", result); log.info("POST request result={}", result);
return result; return result;
} }
@@ -171,7 +154,7 @@ public class HttpService {
* @throws Exception 異常 * @throws Exception 異常
*/ */
public HttpResult sslPatch(String url, Header[] headers, Object requestBody) throws Exception { public HttpResult sslPatch(String url, Header[] headers, Object requestBody) throws Exception {
log.info("======sslCreatePatch======url:{}===========headers:{}", daylightUrl + url, JSON.toJSONString(headers)); log.info("PATCH method, url={}, headers={}, map={}", daylightUrl + url, JSON.toJSONString(headers), JSON.toJSONString(requestBody));
HttpRequestOptions patchConfig = HttpRequestOptions.create() HttpRequestOptions patchConfig = HttpRequestOptions.create()
.url(daylightUrl + url) .url(daylightUrl + url)
.timeout(requestConfig) .timeout(requestConfig)
@@ -180,30 +163,20 @@ public class HttpService {
.encoding("utf-8") .encoding("utf-8")
.client(httpClient); .client(httpClient);
HttpResult result = HttpClientExecutor.sendAndPatchResp(patchConfig, headers); HttpResult result = HttpClientExecutor.sendAndPatchResp(patchConfig, headers);
log.info("====== PATCH request result:{}", result); log.info("PATCH request result={}", result);
return result; return result;
} }
/** // public HttpResult sslSendNotification(String url, Header[] headers, SendNotificationRequest request) throws Exception {
* 使用 HttpConfig 配置 Delete 请求 // log.info("POST method, send notification, url={}, headers={}, map={}", notificationProxyUrl + url, JSON.toJSONString(headers), JSON.toJSONString(request));
* // HttpRequestOptions postConfig = HttpRequestOptions.create()
* @param url 請求路徑 // .url(notificationProxyUrl + url)
* @param headers 請求頭 // .timeout(requestConfig)
* @param map Cancel数据 // .json(JSON.toJSONString(request))
* @return 接口結果的json數據 // .method(HttpMethods.POST)
* @throws Exception 異常 // .client(httpClient);
*/ // HttpResult result = HttpClientExecutor.sendAndPostResp(postConfig, headers);
public HttpResult sslCancelPost(String url, Header[] headers, Map<String, Object> map) throws Exception { // log.info("POST request result={}", result);
log.info("======sslCancelPost======url:{}===========headers:{}", daylightUrl + url, JSON.toJSONString(headers)); // return result;
HttpRequestOptions postConfig = HttpRequestOptions.create() // }
.url(daylightUrl + url)
.timeout(requestConfig)
.json(JSON.toJSONString(map))
.method(HttpMethods.POST)
.client(httpClient);
HttpResult result = HttpClientExecutor.sendAndPostResp(postConfig, headers);
// System.out.println("POST 请求结果:\n" + result);
log.info("====== POST request result:{}", result);
return result;
}
} }
@@ -32,19 +32,12 @@ import java.util.Map;
@RequiredArgsConstructor @RequiredArgsConstructor
public class CompRuleLimitsExceededChangedHandler implements DaylightWebhookHandler { public class CompRuleLimitsExceededChangedHandler implements DaylightWebhookHandler {
@Resource private final CfgCompRuleDao cfgCompRuleDao;
private CfgCompRuleDao cfgCompRuleDao; private final BookingDao bookingDao;
@Resource private final SysLogDeviceTokenRepository sysLogDeviceTokenRepository;
private BookingDao bookingDao; private final NotificationUtil notificationUtil;
@Resource private final ApnNotificationService apnNotificationService;
private SysLogDeviceTokenRepository sysLogDeviceTokenRepository; private final DaylightApiService daylightApiService;
@Resource
private NotificationUtil notificationUtil;
@Resource
private ApnNotificationService apnNotificationService;
@Resource
private DaylightApiService daylightApiService;
@Override @Override
public BaseApiResponse<Void> handle(String payload, Map<String, String> headers) { public BaseApiResponse<Void> handle(String payload, Map<String, String> headers) {
@@ -15,6 +15,7 @@ import com.mgm.mcrm.apigateway.reservation.services.BookingService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -31,6 +32,9 @@ public class ReservationNotificationHandler implements DaylightWebhookHandler {
private final DaylightApiService daylightApiService; private final DaylightApiService daylightApiService;
@Value("${daylight.system-id}")
private String systemId;
@Override @Override
public BaseApiResponse<Void> handle(String payload, Map<String, String> headers) throws Exception { public BaseApiResponse<Void> handle(String payload, Map<String, String> headers) throws Exception {
BaseApiResponse<Void> result = new BaseApiResponse<>(); BaseApiResponse<Void> result = new BaseApiResponse<>();
@@ -51,8 +55,6 @@ public class ReservationNotificationHandler implements DaylightWebhookHandler {
} }
private Bookings convertEventToBooking(ReservationNotificationEvent eventData) { private Bookings convertEventToBooking(ReservationNotificationEvent eventData) {
log.info("Reservation Notification Event Data: {}", JSON.toJSONString(eventData)); log.info("Reservation Notification Event Data: {}", JSON.toJSONString(eventData));
Bookings result = new Bookings(); Bookings result = new Bookings();
@@ -65,11 +67,17 @@ public class ReservationNotificationHandler implements DaylightWebhookHandler {
result.setDlChannelId(eventData.getChannelId()); result.setDlChannelId(eventData.getChannelId());
result.setDlAccountId(eventData.getAccountId()); result.setDlAccountId(eventData.getAccountId());
result.setDlBlockId(eventData.getBlockId()); result.setDlBlockId(eventData.getBlockId());
result.setDlExternalNo(eventData.getDlExternalNo()); // result.setDlExternalNo(eventData.getDlExternalNo());
if (eventData.getExternalSystemIds() != null if (eventData.getExternalSystemIds() != null
&& !eventData.getExternalSystemIds().isEmpty()) { && !eventData.getExternalSystemIds().isEmpty()) {
eventData.getExternalSystemIds().stream()
.filter(t -> t.getId().equalsIgnoreCase(systemId))
.forEach(t -> result.setDlExternalNo(t.getValue()));
if (StringUtils.isEmpty(result.getDlExternalNo())) {
result.setDlExternalNo(eventData.getExternalSystemIds().getFirst().getValue()); result.setDlExternalNo(eventData.getExternalSystemIds().getFirst().getValue());
} }
}
result.setCreatedAt(parseDateTime(eventData.getCreatedAt())); result.setCreatedAt(parseDateTime(eventData.getCreatedAt()));
result.setUpdatedAt(parseDateTime(eventData.getUpdatedAt())); result.setUpdatedAt(parseDateTime(eventData.getUpdatedAt()));
result.setCheckinDate(DateTimeUtil.getDateFromString(eventData.getArrivalDate(),"yyyy-MM-dd")); result.setCheckinDate(DateTimeUtil.getDateFromString(eventData.getArrivalDate(),"yyyy-MM-dd"));
@@ -128,12 +136,26 @@ public class ReservationNotificationHandler implements DaylightWebhookHandler {
} }
} }
if (StringUtils.isBlank(result.getDlExternalNo())) {
JSONArray jsonArray = response.getData().getJSONArray("externalIds"); JSONArray jsonArray = response.getData().getJSONArray("externalIds");
if (!CollectionUtils.isEmpty(jsonArray)) { if (!CollectionUtils.isEmpty(jsonArray)) {
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
if (jsonObject.getString("systemId").equals(systemId)) {
result.setDlExternalNo(jsonObject.getString("number"));
break;
}
}
if (StringUtils.isBlank(result.getDlExternalNo())) {
String dlExternalNo = jsonArray.getJSONObject(0).getString("number"); String dlExternalNo = jsonArray.getJSONObject(0).getString("number");
result.setDlExternalNo(dlExternalNo); result.setDlExternalNo(dlExternalNo);
} }
} }
}
}
return result; return result;
} }
@@ -35,7 +35,7 @@ import java.util.Collections;
@RestController @RestController
public class NotificationProxyController { public class NotificationProxyController {
private final Logger logger = LoggerFactory.getLogger(WebProxyController.class); private final Logger logger = LoggerFactory.getLogger(NotificationProxyController.class);
@Resource @Resource
private NotificationProxyService notificationProxyService; private NotificationProxyService notificationProxyService;
@@ -25,12 +25,18 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration; import java.time.Duration;
import java.util.*; import java.util.*;
@Tag(name = "Proxy", description = "Controller for API proxy") @Tag(name = "Proxy", description = "Controller for API proxy")
@RestController @RestController
public class WebProxyController { public class WebProxyController {
private static final int LOG_BODY_PREVIEW_LIMIT = 4096;
private static final Set<String> SENSITIVE_HEADERS = Set.of(
"authorization", "proxy-authorization", "cookie", "set-cookie",
"x-api-key", "api-key"
);
private final Logger logger = LoggerFactory.getLogger(WebProxyController.class); private final Logger logger = LoggerFactory.getLogger(WebProxyController.class);
private final HttpProxyErrorHandler httpErrorHandler= new HttpProxyErrorHandler(); private final HttpProxyErrorHandler httpErrorHandler= new HttpProxyErrorHandler();
private final SoapProxyErrorHandler soapProxyErrorHandler = new SoapProxyErrorHandler(); private final SoapProxyErrorHandler soapProxyErrorHandler = new SoapProxyErrorHandler();
@@ -77,24 +83,11 @@ public class WebProxyController {
} }
@RequestMapping("/api/esb/proxy/**") @RequestMapping("/api/esb/proxy/**")
public ResponseEntity<byte[]> invokeEsbApiProxy(HttpServletRequest request) throws Exception { public ResponseEntity<byte[]> invokeEsbApiProxy(HttpServletRequest request) throws Exception {
logger.info("invokeEsbApiProxy start, method={}, uri={}, query={}", HttpMethod method = HttpMethod.valueOf(request.getMethod());
request.getMethod(), request.getRequestURI(), request.getQueryString());
String apiUrl = esbApiSetting.getServerUrl() + request.getRequestURI().replace("/api/esb/proxy", ""); String apiUrl = esbApiSetting.getServerUrl() + request.getRequestURI().replace("/api/esb/proxy", "");
logger.info("invokeEsbApiProxy target apiUrl={}", apiUrl); String queryString = request.getQueryString();
HttpHeaders headers = this.extractHeaders(request); HttpHeaders headers = this.extractHeaders(request);
byte[] requestBody = getRequestBody(request);
if (isMockFromDb()) {
return webProxyService.invokeMockRequest(
WebProxyService.ESB_API,
HttpMethod.valueOf(request.getMethod()),
apiUrl,
request.getQueryString(),
extractHeaders(request),
getRequestBody(request),
Duration.ofSeconds(esbApiSetting.getApiRequestTimeout()),
httpErrorHandler
).block();
}
EsbToken esbToken = esbTokenService.getApiAccessToken(); EsbToken esbToken = esbTokenService.getApiAccessToken();
if(esbToken==null || StringUtils.isBlank(esbToken.getAccessToken())){ if(esbToken==null || StringUtils.isBlank(esbToken.getAccessToken())){
@@ -105,16 +98,32 @@ public class WebProxyController {
ResponseEntity<byte[]> response = webProxyService.invokeRequest( ResponseEntity<byte[]> response = webProxyService.invokeRequest(
WebProxyService.ESB_API, WebProxyService.ESB_API,
HttpMethod.valueOf(request.getMethod()), method,
apiUrl, apiUrl,
request.getQueryString(), queryString,
extractHeaders(request), headers,
getRequestBody(request), requestBody,
Duration.ofSeconds(esbApiSetting.getApiRequestTimeout()), Duration.ofSeconds(esbApiSetting.getApiRequestTimeout()),
httpErrorHandler httpErrorHandler
).block(); ).block();
logger.info("invokeEsbApiProxy end, uri={}, status={}", if (response == null) {
request.getRequestURI(), response == null ? null : response.getStatusCode()); logger.error("invokeEsbApiProxy received a null response: method={}, apiUrl={}, query={}",
method, apiUrl, queryString);
} else if (response.getStatusCode().isError()) {
byte[] responseBody = response.getBody();
logger.warn("invokeEsbApiProxy error response: method={}, apiUrl={}, query={}, status={}, headers={}, bodyLength={}, bodyPreview={}",
method,
apiUrl,
queryString,
response.getStatusCode(),
sanitizeHeaders(response.getHeaders()),
responseBody == null ? 0 : responseBody.length,
bodyPreview(responseBody));
} else {
logger.info("invokeEsbApiProxy completed: method={}, apiUrl={}, query={}, status={}",
method, apiUrl, queryString, response.getStatusCode());
}
return response; return response;
} }
@@ -156,6 +165,29 @@ public class WebProxyController {
} }
} }
private Map<String, List<String>> sanitizeHeaders(HttpHeaders headers) {
Map<String, List<String>> sanitizedHeaders = new LinkedHashMap<>();
headers.forEach((name, values) -> sanitizedHeaders.put(
name,
SENSITIVE_HEADERS.contains(name.toLowerCase(Locale.ROOT))
? List.of("[REDACTED]")
: values
));
return sanitizedHeaders;
}
private String bodyPreview(byte[] body) {
if (body == null || body.length == 0) {
return "";
}
String content = new String(body, StandardCharsets.UTF_8);
if (content.length() <= LOG_BODY_PREVIEW_LIMIT) {
return content;
}
return content.substring(0, LOG_BODY_PREVIEW_LIMIT) + "...[truncated]";
}
private boolean isMockFromDb() { private boolean isMockFromDb() {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (now - lastMockCheckTime > MOCK_CHECK_INTERVAL_MS) { if (now - lastMockCheckTime > MOCK_CHECK_INTERVAL_MS) {
@@ -2,6 +2,7 @@ package com.mgm.mcrm.apigateway.reservation.repositories;
import com.mgm.mcrm.apigateway.reservation.models.Bookings; import com.mgm.mcrm.apigateway.reservation.models.Bookings;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List; import java.util.List;
@@ -13,5 +14,6 @@ public interface BookingDao extends JpaRepository<Bookings, Long> {
Bookings findFirstByDlProfileIdAndPlayerIdIsNotNull(String dlProfileId); Bookings findFirstByDlProfileIdAndPlayerIdIsNotNull(String dlProfileId);
@Query(value = "select * from bookings where dl_external_no = ?1", nativeQuery = true)
List<Bookings> findByDlExternalNo(String dlExternalNo); List<Bookings> findByDlExternalNo(String dlExternalNo);
} }
@@ -33,6 +33,7 @@ import com.mgm.mcrm.apigateway.player.services.PlayerService;
import com.mgm.mcrm.apigateway.reservation.models.Bookings; import com.mgm.mcrm.apigateway.reservation.models.Bookings;
import com.mgm.mcrm.apigateway.reservation.repositories.BookingDao; import com.mgm.mcrm.apigateway.reservation.repositories.BookingDao;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings; import org.apache.commons.lang3.Strings;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -43,6 +44,7 @@ import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Slf4j
@Service @Service
public class BookingService { public class BookingService {
@@ -85,17 +87,32 @@ public class BookingService {
List<Bookings> dbBookings = null; List<Bookings> dbBookings = null;
if (StringUtils.isNotEmpty(dlExternalNo)) { if (StringUtils.isNotEmpty(dlExternalNo)) {
log.info("Find booking by dlExternalNo={}", dlExternalNo);
TimeUnit.SECONDS.sleep(5);
dbBookings = bookingDao.findByDlExternalNo(dlExternalNo); dbBookings = bookingDao.findByDlExternalNo(dlExternalNo);
log.info("bookings isEmpty={}", dbBookings.isEmpty());
} }
if (CollectionUtils.isEmpty(dbBookings) && StringUtils.isNotEmpty(dlReservationId)) { if (CollectionUtils.isEmpty(dbBookings) && StringUtils.isNotEmpty(dlReservationId)) {
log.info("Find booking by dlReservationId={}", dlReservationId);
TimeUnit.SECONDS.sleep(2); TimeUnit.SECONDS.sleep(2);
dbBookings = bookingDao.findByDlReservationId(dlReservationId); dbBookings = bookingDao.findByDlReservationId(dlReservationId);
log.info("bookings isEmpty={}", dbBookings.isEmpty());
} }
if (CollectionUtils.isEmpty(dbBookings) && StringUtils.isNotEmpty(confirmNo)) { if (CollectionUtils.isEmpty(dbBookings) && StringUtils.isNotEmpty(confirmNo)) {
log.info("Find booking by confirmNo={}", confirmNo);
TimeUnit.SECONDS.sleep(2); TimeUnit.SECONDS.sleep(2);
dbBookings = bookingDao.findByConfirmationNo(confirmNo); dbBookings = bookingDao.findByConfirmationNo(confirmNo);
log.info("bookings isEmpty={}", dbBookings.isEmpty());
}
if (CollectionUtils.isEmpty(dbBookings) && StringUtils.isNotEmpty(dlExternalNo)) {
log.info("Find booking again by dlExternalNo={}", dlExternalNo);
TimeUnit.SECONDS.sleep(3);
dbBookings = bookingDao.findByDlExternalNo(dlExternalNo);
log.info("bookings isEmpty={}", dbBookings.isEmpty());
} }
Bookings dbBooking = null; Bookings dbBooking = null;
@@ -104,7 +121,7 @@ public class BookingService {
String dbBookingStatus = null; String dbBookingStatus = null;
if(!CollectionUtils.isEmpty(dbBookings)) { if(!CollectionUtils.isEmpty(dbBookings)) {
for(Bookings booking:dbBookings){ for(Bookings booking:dbBookings){
if("N".equalsIgnoreCase(booking.getApproveStatus())) { if("N".equalsIgnoreCase(booking.getApproveStatus()) || "PN".equalsIgnoreCase(booking.getApproveStatus())) {
dbBooking = booking; dbBooking = booking;
dbBookingStatus = dbBooking.getLastOperaStatus(); dbBookingStatus = dbBooking.getLastOperaStatus();
checkInDate = dbBooking.getCheckinDate(); checkInDate = dbBooking.getCheckinDate();
@@ -122,13 +139,9 @@ public class BookingService {
} }
bookingDao.save(dbBooking); bookingDao.save(dbBooking);
CfgProperties property = propertyDao.findByDlPropertyId(dbBooking.getDlPropertyId()); CfgProperties property = propertyDao.findById(dbBooking.getPropertyId()).orElse(null);
//Send Notification to Booker when booking lastOpera status Changed //Send Notification to Booker when booking lastOpera status Changed
LogUtil.info(BookingService.class,"Daylight webhook updated, prepare send notification");
LogUtil.info(BookingService.class,"DaylightBooking status=" + daylightBooking.getLastOperaStatus());
LogUtil.info(BookingService.class,"Db booking status=" + dbBookingStatus);
if (Strings.CS.equals(daylightBooking.getLastOperaStatus(),"RESERVED") && !Strings.CS.equals(dbBookingStatus,daylightBooking.getLastOperaStatus())){ if (Strings.CS.equals(daylightBooking.getLastOperaStatus(),"RESERVED") && !Strings.CS.equals(dbBookingStatus,daylightBooking.getLastOperaStatus())){
LogUtil.info(BookingService.class,"Booking last opera status changed, DB Record status:"+dbBookingStatus+", DlBooking status:"+daylightBooking.getLastOperaStatus()); LogUtil.info(BookingService.class,"Booking last opera status changed, DB Record status:"+dbBookingStatus+", DlBooking status:"+daylightBooking.getLastOperaStatus());
//设置Notification 内容 //设置Notification 内容
@@ -165,6 +178,10 @@ public class BookingService {
apnNotificationService.pushApnMessage(transactionId,deviceTokenValue,finalTitle,notificationContent,true); apnNotificationService.pushApnMessage(transactionId,deviceTokenValue,finalTitle,notificationContent,true);
} }
LogUtil.info(BookingService.class,"Daylight webhook updated, prepare send notification");
log.info("dbBooking checkin={}, checkout={}", checkInDate, checkOutDate);
log.info("dlBooking checkin={}, checkout={}", daylightBooking.getCheckinDate(), daylightBooking.getCheckoutDate());
LogUtil.info(BookingService.class,"Db booking status=" + dbBookingStatus);
//Send notification to Booker when Booking C/I | C/O date changed //Send notification to Booker when Booking C/I | C/O date changed
if ((checkInDate != null && !checkInDate.equals(daylightBooking.getCheckinDate()))|| if ((checkInDate != null && !checkInDate.equals(daylightBooking.getCheckinDate()))||
(checkOutDate != null && !checkOutDate.equals(daylightBooking.getCheckoutDate()))) { (checkOutDate != null && !checkOutDate.equals(daylightBooking.getCheckoutDate()))) {
@@ -315,24 +332,6 @@ public class BookingService {
} }
public Bookings createBookingFromDaylight(Bookings daylightBooking) throws Exception { public Bookings createBookingFromDaylight(Bookings daylightBooking) throws Exception {
String dlReservationId = daylightBooking.getDlReservationId();
List<Bookings> dbBookings = bookingDao.findByDlReservationId(dlReservationId);
if (!dbBookings.isEmpty()) {
Bookings dbBooking = null;
for (Bookings booking : dbBookings) {
if ("N".equalsIgnoreCase(booking.getApproveStatus())) {
dbBooking = booking;
break;
}
}
if (dbBooking != null) {
mergeDaylightToDbBooking(daylightBooking, dbBooking);
return dbBooking;
}
}
Bookings dbBooking = new Bookings(); Bookings dbBooking = new Bookings();
CfgProperties daylightProperty = propertyDao.findByDlPropertyId(daylightBooking.getDlPropertyId()); CfgProperties daylightProperty = propertyDao.findByDlPropertyId(daylightBooking.getDlPropertyId());
@@ -411,8 +410,9 @@ public class BookingService {
dbBooking.setDlReservationId(daylightBooking.getDlReservationId()); dbBooking.setDlReservationId(daylightBooking.getDlReservationId());
//get player info //get player info
if(StringUtils.isNotEmpty(dbBooking.getPlayerId())) { if(StringUtils.isNotEmpty(daylightBooking.getPlayerId())) {
ServiceResult serviceResult = playerService.findWebPlayerProfileByPlayerId(dbBooking.getPlayerId()); dbBooking.setPlayerId(daylightBooking.getPlayerId());
ServiceResult serviceResult = playerService.findWebPlayerProfileByPlayerId(daylightBooking.getPlayerId());
if(serviceResult.isSuccess()) { if(serviceResult.isSuccess()) {
PlayerProfileApiResult profile = (PlayerProfileApiResult) serviceResult.getReturnData(); PlayerProfileApiResult profile = (PlayerProfileApiResult) serviceResult.getReturnData();
dbBooking.setMemberLastName(profile.getName()); dbBooking.setMemberLastName(profile.getName());