Skip to content

Commit

Permalink
YEL-146 [merge] 개발서버 배포
Browse files Browse the repository at this point in the history
YEL-146 [merge] 개발서버 배포
  • Loading branch information
hyeonjeongs authored Aug 28, 2023
2 parents f3327bf + 996a80e commit b7ded57
Show file tree
Hide file tree
Showing 12 changed files with 324 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,11 @@ public void deleteFriend(Long userId, Long targetId) {
final User target = userRepository.getById(targetId);
final User user = userRepository.getById(userId);

friendRepository.delete(friendRepository.getByUserAndTarget(userId, targetId));
friendRepository.delete(friendRepository.getByUserAndTarget(targetId, userId));
Friend friendByUser = friendRepository.getByUserAndTarget(userId, targetId);
Friend friendByTarget = friendRepository.getByUserAndTarget(targetId, userId);

friendRepository.delete(friendByUser);
friendRepository.delete(friendByTarget);
}

public RecommendFriendResponse findAllRecommendKakaoFriends(Pageable pageable, Long userId,
Expand All @@ -141,7 +144,7 @@ public SearchFriendResponse searchFriend(Long userId, Pageable pageable,
final Long groupId = user.getGroup().getId();

List<User> friendList = new ArrayList<>();

if (keyword==null || keyword.trim().isEmpty()) {
return SearchFriendResponse.of(0, Collections.emptyList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@
import com.yello.server.global.common.dto.response.GoogleTokenIssueResponse;
import com.yello.server.global.common.entity.GoogleToken;
import com.yello.server.global.common.repository.GoogleTokenRepository;
import com.yello.server.global.common.util.AppleUtil;
import com.yello.server.global.common.util.ConstantUtil;
import com.yello.server.global.common.util.RestUtil;
import com.yello.server.infrastructure.client.ApiWebClient;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
Expand All @@ -71,7 +71,7 @@ public class PurchaseService {
private final PurchaseRepository purchaseRepository;
private final GoogleTokenRepository googleTokenRepository;
private final PurchaseManager purchaseManager;
private final AppleUtil appleUtil;
private final ApiWebClient apiWebClient;

public UserSubscribeNeededResponse getUserSubscribe(User user, LocalDateTime time) {
final Optional<Purchase> mostRecentPurchase =
Expand All @@ -89,7 +89,7 @@ public UserSubscribeNeededResponse getUserSubscribe(User user, LocalDateTime tim
public void verifyAppleSubscriptionTransaction(Long userId,
AppleTransaction request) {
ResponseEntity<AppleOrderResponse> verifyReceiptResponse =
appleUtil.appleGetTransaction(request);
apiWebClient.appleGetTransaction(request);
final User user = userRepository.getById(userId);

purchaseManager.handleAppleTransactionError(verifyReceiptResponse, request.transactionId());
Expand All @@ -109,18 +109,20 @@ public void verifyAppleSubscriptionTransaction(Long userId,
@Transactional
public void verifyAppleTicketTransaction(Long userId, AppleTransaction request) {
final ResponseEntity<AppleOrderResponse> verifyReceiptResponse =
appleUtil.appleGetTransaction(request);
apiWebClient.appleGetTransaction(request);
final User user = userRepository.getById(userId);

purchaseManager.handleAppleTransactionError(verifyReceiptResponse, request.transactionId());

switch (request.productId()) {
case ONE_TICKET_ID:
purchaseManager.createTicket(user, ProductType.ONE_TICKET, Gateway.APPLE, request.transactionId());
purchaseManager.createTicket(user, ProductType.ONE_TICKET, Gateway.APPLE,
request.transactionId());
user.addTicketCount(1);
break;
case TWO_TICKET_ID:
purchaseManager.createTicket(user, ProductType.TWO_TICKET, Gateway.APPLE, request.transactionId());
purchaseManager.createTicket(user, ProductType.TWO_TICKET, Gateway.APPLE,
request.transactionId());
user.addTicketCount(2);
break;
case FIVE_TICKET_ID:
Expand Down Expand Up @@ -175,16 +177,19 @@ public GoogleSubscriptionGetResponse verifyGoogleSubscriptionTransaction(Long us

Gson gson = new Gson();
JsonObject object = gson.fromJson(subscribeResponse.getBody(), JsonObject.class);
final String subscriptionState = object.get("subscriptionState").toString().replaceAll("\"", "");
final String subscriptionState =
object.get("subscriptionState").toString().replaceAll("\"", "");

switch (subscriptionState) {
case ConstantUtil.GOOGLE_PURCHASE_SUBSCRIPTION_EXPIRED -> {
user.setSubscribe(Subscribe.NORMAL);
throw new GoogleBadRequestException(GOOGLE_SUBSCRIPTION_TRANSACTION_EXPIRED_EXCEPTION);
throw new GoogleBadRequestException(
GOOGLE_SUBSCRIPTION_TRANSACTION_EXPIRED_EXCEPTION);
}
case ConstantUtil.GOOGLE_PURCHASE_SUBSCRIPTION_CANCELED -> {
if (user.getSubscribe()==Subscribe.CANCELED) {
throw new GoogleBadRequestException(GOOGLE_SUBSCRIPTION_DUPLICATED_CANCEL_EXCEPTION);
throw new GoogleBadRequestException(
GOOGLE_SUBSCRIPTION_DUPLICATED_CANCEL_EXCEPTION);
} else {
// TODO messageQueue 를 이용한 결제 만료일 도달 시, 유저 구독 상태 변경하기
user.setSubscribe(Subscribe.CANCELED);
Expand All @@ -201,7 +206,8 @@ public GoogleSubscriptionGetResponse verifyGoogleSubscriptionTransaction(Long us
}

@Transactional
public GoogleTicketGetResponse verifyGoogleTicketTransaction(Long userId, GoogleTicketGetRequest request)
public GoogleTicketGetResponse verifyGoogleTicketTransaction(Long userId,
GoogleTicketGetRequest request)
throws IOException {
final User user = userRepository.getById(userId);

Expand All @@ -210,7 +216,8 @@ public GoogleTicketGetResponse verifyGoogleTicketTransaction(Long userId, Google
throw new PurchaseConflictException(GOOGLE_SUBSCRIPTIONS_SUBSCRIPTION_EXCEPTION);
});

final GoogleToken googleToken = googleTokenRepository.getById(googleTokenRepository.tokenId);
final GoogleToken googleToken =
googleTokenRepository.getById(googleTokenRepository.tokenId);
if (googleToken.getAccessToken().isEmpty() || googleToken.getRefreshToken().isEmpty()) {
throw new GoogleTokenNotFoundException(GOOGLE_TOKEN_FIELD_NOT_FOUND_EXCEPTION);
}
Expand All @@ -236,11 +243,13 @@ public GoogleTicketGetResponse verifyGoogleTicketTransaction(Long userId, Google
if (inAppResponse.getBody().purchaseState()==0) {
purchaseRepository.findByTransactionId(inAppResponse.getBody().orderId())
.ifPresent(action -> {
throw new PurchaseConflictException(GOOGLE_SUBSCRIPTIONS_SUBSCRIPTION_EXCEPTION);
throw new PurchaseConflictException(
GOOGLE_SUBSCRIPTIONS_SUBSCRIPTION_EXCEPTION);
});

Purchase ticket = purchaseManager.createTicket(user, getProductType(request.productId()),
Gateway.GOOGLE, request.orderId());
Purchase ticket =
purchaseManager.createTicket(user, getProductType(request.productId()),
Gateway.GOOGLE, request.orderId());
user.addTicketCount(getTicketAmount(request.productId()) * request.quantity());
ticket.setTransactionId(inAppResponse.getBody().orderId());
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,47 +1,6 @@
package com.yello.server.global.common.factory;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Date;
import lombok.SneakyThrows;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
public interface TokenFactory {

@Component
public class TokenFactory {

@Value("${kid}")
private String kid;

@Value("${iss}")
private String iss;

@Value("${aud}")
private String aud;

@Value("${bid}")
private String bid;

@Value("${sig}")
private String sig;

@SneakyThrows
public String generateAppleToken() {
return Jwts.builder()
.setHeaderParam("kid", kid)
.setIssuer(iss)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + (3 * 60 * 1000)))
.setAudience(aud)
.claim("bid", bid)
.signWith(
SignatureAlgorithm.ES256,
KeyFactory.getInstance("EC")
.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(sig)))
)
.compact();
}
String generateAppleToken();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.yello.server.global.common.factory;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Date;
import lombok.SneakyThrows;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class TokenFactoryImpl implements TokenFactory {

@Value("${kid}")
private String kid;

@Value("${iss}")
private String iss;

@Value("${aud}")
private String aud;

@Value("${bid}")
private String bid;

@Value("${sig}")
private String sig;


@SneakyThrows
@Override
public String generateAppleToken() {
return Jwts.builder()
.setHeaderParam("kid", kid)
.setIssuer(iss)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + (3 * 60 * 1000)))
.setAudience(aud)
.claim("bid", bid)
.signWith(
SignatureAlgorithm.ES256,
KeyFactory.getInstance("EC")
.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(sig)))
)
.compact();
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.yello.server.infrastructure.client;

import com.yello.server.domain.purchase.dto.apple.AppleOrderResponse;
import com.yello.server.domain.purchase.dto.apple.AppleTransaction;
import org.springframework.http.ResponseEntity;

public interface ApiWebClient {

ResponseEntity<AppleOrderResponse> appleGetTransaction(
AppleTransaction appleTransaction);

ResponseEntity<AppleOrderResponse> getTransactionByWebClient(
AppleTransaction appleTransaction,
String appleUrl);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.yello.server.global.common.util;
package com.yello.server.infrastructure.client;

import static com.yello.server.global.common.ErrorCode.NOT_FOUND_TRANSACTION_EXCEPTION;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
Expand All @@ -17,17 +17,18 @@

@Component
@RequiredArgsConstructor
public class AppleUtil {
public class AppleApiWebClient implements ApiWebClient {

private final TokenFactory tokenFactory;
@Value("${apple.production.uri}")
private String APPLE_PRODUCTION_URL;
@Value("${apple.sandbox.uri}")
private String APPLE_SANDBOX_URL;


@Override
public ResponseEntity<AppleOrderResponse> appleGetTransaction(
AppleTransaction appleTransaction) {

ResponseEntity<AppleOrderResponse> transactionResponse =
getTransactionByWebClient(appleTransaction, APPLE_PRODUCTION_URL);

Expand All @@ -42,10 +43,9 @@ public ResponseEntity<AppleOrderResponse> appleGetTransaction(
return transactionResponse;
}

@Override
public ResponseEntity<AppleOrderResponse> getTransactionByWebClient(
AppleTransaction appleTransaction,
String appleUrl) {

AppleTransaction appleTransaction, String appleUrl) {
String appleToken = tokenFactory.generateAppleToken();

WebClient webClient = WebClient.builder()
Expand All @@ -58,5 +58,4 @@ public ResponseEntity<AppleOrderResponse> getTransactionByWebClient(
.exchangeToMono(clientResponse -> clientResponse.toEntity(AppleOrderResponse.class))
.block();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.yello.server.domain.purchase;

import static com.yello.server.global.common.ErrorCode.NOT_FOUND_TRANSACTION_EXCEPTION;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

import com.yello.server.domain.purchase.dto.apple.AppleOrderResponse;
import com.yello.server.domain.purchase.dto.apple.AppleTransaction;
import com.yello.server.domain.purchase.exception.PurchaseException;
import com.yello.server.global.common.factory.TokenFactory;
import com.yello.server.infrastructure.client.ApiWebClient;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.reactive.function.client.WebClient;

public class FakeAppleApiWebClient implements ApiWebClient {

private final TokenFactory tokenFactory;

private String APPLE_PRODUCTION_URL = "https://api.storekit.itunes.apple.com/inApps/v1/history";

private String APPLE_SANDBOX_URL =
"https://api.storekit-sandbox.itunes.apple.com/inApps/v1/history";

public FakeAppleApiWebClient(TokenFactory tokenFactory) {
this.tokenFactory = tokenFactory;
}

@Override
public ResponseEntity<AppleOrderResponse> appleGetTransaction(
AppleTransaction appleTransaction) {
ResponseEntity<AppleOrderResponse> transactionResponse =
getTransactionByWebClient(appleTransaction, APPLE_PRODUCTION_URL);

HttpStatus statusCode = transactionResponse.getStatusCode();
if (transactionResponse==null) {
throw new PurchaseException(NOT_FOUND_TRANSACTION_EXCEPTION);
}
if (statusCode.equals(HttpStatus.NOT_FOUND)) {
return getTransactionByWebClient(appleTransaction, APPLE_SANDBOX_URL);
}

return transactionResponse;
}

@Override
public ResponseEntity<AppleOrderResponse> getTransactionByWebClient(
AppleTransaction appleTransaction, String appleUrl) {
String appleToken = tokenFactory.generateAppleToken();

WebClient webClient = WebClient.builder()
.defaultHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_JSON_VALUE)
.defaultHeader(HttpHeaders.AUTHORIZATION, appleToken)
.build();

return webClient.get()
.uri(appleUrl + "/{transactionId}", appleTransaction.transactionId())
.exchangeToMono(clientResponse -> clientResponse.toEntity(AppleOrderResponse.class))
.block();
}
}
Loading

0 comments on commit b7ded57

Please sign in to comment.