AWS를 사용한다면 CloudFront SDK를 통해 손쉽게 캐시 서버를 제어할 수 있다.
이전 포스팅에서 Naver Cloud에서 Object Storage는 S3 SDK가 호환된다고 했는데,
아쉽게도 CloudFront SDK는 CDN+(국내용) 또는 Global CDN(해외용)에 호환되지 않는다.
그렇지만 결론은 심플하다. API 방식을 사용하면 된다.
내가 필요한 기능은 CDN+ 의 데이터 삭제 기능인 "퍼지(purge)"이다.
기존에 CDN을 회원별 아이디를 디렉토리로 하여 생성하고 그 안에 대상 파일이 있는 구조이다.
요청에 필요한 파라미터를 보니, 나에게 필요한 것은 아래와 같았다.
- CDN 인스턴스 번호
- 전체 도메인 여부
- 전체 퍼지 여부
- 대상 디렉토리명
- 응답 타입
WebClient를 사용하여 API를 호출한다.
@Slf4j
@Component
@RequiredArgsConstructor
public class NcpCdnManager {
private static final String NCP_API_URL = "https://ncloud.apigw.gov-ntruss.com";
private static final String NCP_CDN_PURGE_PATH = "/cdn/v2/requestCdnPlusPurge";
private static final String QUERY_STRING_INDICATOR = "?";
private final WebClient webClient;
@Value(value = "${cloud.ncp.cdn.purge}")
private String purgeInstanceId;
@Value(value = "${cloud.credentials.access-key}")
private String accessKey;
@Value(value = "${cloud.credentials.secret-key}")
private String secretKey;
public void purge(String targetDirectoryName) {
UriComponents uriComponents = makeUriComponents(targetDirectoryName);
String path = uriComponents.getPath() + QUERY_STRING_INDICATOR + uriComponents.getQuery();
HttpHeaders httpHeaders = makeCdnPlusHeaders(String.valueOf(System.currentTimeMillis()), path);
webClient.get()
.uri(uriComponents.toString())
.headers(headers -> headers.addAll(httpHeaders))
.retrieve()
.bodyToMono(Void.class)
.doOnError(e -> {
log.error("NCP CDN+ Purge 실패", e);
throw new CustomException(ExceptionType.CDN_PURGE_FAIL);
})
.block();
}
private UriComponents makeUriComponents(String targetDirectoryName) {
return UriComponentsBuilder.newInstance()
.uri(URI.create(NCP_API_URL))
.path(NCP_CDN_PURGE_PATH)
.queryParam("cdnInstanceNo", purgeInstanceId)
.queryParam("isWholePurge", false)
.queryParam("targetDirectoryName", targetDirectoryName)
.queryParam("isWholeDomain", true)
.queryParam("responseFormatType", "JSON")
.build();
}
private HttpHeaders makeCdnPlusHeaders(String timeStamp, String path) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("x-ncp-apigw-timestamp", timeStamp);
httpHeaders.add("x-ncp-iam-access-key", accessKey);
httpHeaders.add("x-ncp-apigw-signature-v2", makeSignature(timeStamp, HttpMethod.GET.name(), path));
return httpHeaders;
}
private String makeSignature(String timeStamp, String method, String url) {
String message = new StringBuilder()
.append(method)
.append(" ")
.append(url)
.append("\n")
.append(timeStamp)
.append("\n")
.append(accessKey)
.toString();
try {
SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(rawHmac);
} catch (Exception e) {
log.error("NCP CDN+ Signature 생성 실패", e);
throw new CustomException(ExceptionType.CDN_SIGNATURE_FAIL);
}
}
}
API 요청시에 특정 헤더를 지정해주어야 한다.
- x-ncp-apigw-timestamp
- x-ncp-iam-access-key
- x-ncp-apigw-signature-v2
특히 "x-ncp-apigw-signature-v2" 는 암호화해서 넣어주어야 한다.
그리고 암호화에 필요한 url은 실제 url을 제외한 path와 query parameter를 포함하는 문자열로 구성된다.
기본적인 내용은 공식문서를 참고하였고, 암호화 로직은 아래의 블로그를 참고하였다.
https://api-gov.ncloud-docs.com/docs/networking-cdn
https://api-gov.ncloud-docs.com/docs/networking-cdn-requestcdnpluspurge
'개발 > Others' 카테고리의 다른 글
[NCP] S3 SDK를 Naver 클라우드에서 사용해보자 (0) | 2024.02.25 |
---|---|
[보안] JWT란 무엇일까 (1) | 2023.12.22 |
[ELK] 마치 SQL처럼 사용하자 (0) | 2023.09.10 |
[ELK] 시작한 김에 ELK(2) (0) | 2023.09.02 |
[ELK] 시작한 김에 ELK(1) (0) | 2023.08.27 |