네이버 클라우드 플랫폼 API 시작 가이드

개요

자세한 문서는 네이버 클라우드 플랫폼 모니터링 API reference를 참고합니다.
이 절에서는 간단한 시나리오를 통해, 생성/운영 중인 서버에 대한 모니터링 관련 정보를 조회합니다. 기술된 시나리오를 따라 해 봄으로써 모니터링 API에 대한 사용법을 익힐 수 있습니다.

시나리오 설명

소유하고 있는 서버에 대한 모니터링 통계 정보를 조회해 봅니다.

  1. 서버별로 제공 가능한 Metric정보 조회

    • 서버별로 통계 정보가 제공 가능한 Metric 이 어떤 것이 있는지 조회해 봅니다.
  2. Metric에 대한 통계 정보 조회

    • 특정 기간에 대한 서버(들)의 Metric 통계 정보를 조회해 봅니다.

인증

해당 가이드에서는 시나리오 수행을 위한 인증 URL을 만드는 과정을 살펴 보도록 합니다.
Java 샘플코드로 작성되었고, GET 방식의 http request method를 사용하여 요청하는 방식으로 작성되었습니다.
실제 요청 시에는 GET 방식으로 요청하는 것보다 POST 방식으로 request body에 값을 넣어서 요청하는 것을 추천합니다.

인증 URL생성

인증키를 생성하기 위해서 아래와 같은 절차를 따릅니다.

base string 생성

  1. 액션파라미터에 base string 생성에 필요한 인증 파라미터를 추가
  2. 요청파라미터와 value 값을 알파벳 순으로 정렬
  3. base string = RequestMethod + '&' + oauthEncode(requestUrl) + '&' + oauthEncode(queryString)

서명서 생성

Secret Key와 위에서 생성한 baseString을 가지고 HMAC SHA-1 해시알고리즘을 이용하여 서명서를 생성합니다.

요청 URL 생성

서명서까지 생성이 완료되었으면, 요청URL을 생성하여, API를 요청합니다.
OAuth 외부 라이브러리를 이용하여, authorization 헤더에 authparams 포함하여 쉽게 요청할 수도 있습니다.

자세한 사항은 Ncloud OAuth 인증 가이드를 참고하기 바란다.

요청 URL 생성 java sample code

아래는 요청 URL을 생성하는 java sample code이다.
해당 코드는 commons-codec-1.4.jar 라이브러리에 dependency를 가집니다. 따라서 아래 코드를 수행하기 위해서는 해당 jar가 자신의 build path에 추가되어야 합니다.
해당 jar는 간단하게 google.com이나 naver.com에서 검색을 통해서 다운로드할 수 도 있고, 또는 네이버 클라우드 비즈 라이브러리에서 dependency 항목으로 함께 제공됩니다.

import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.net.URLCodec;

/**
 * @author admin
 */
public class OAuthMain {
    private static String consumerKey = "CCe2T0ilv4aO3kIevT3x";
    private static String consumerSecret = "UXbllHzrAVV7rmcE270sESJZa3Fh8I2kOiBTf0oE";

    public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
        String requestMethod = "GET";
        String requestUrl = "https://api.ncloud.com";
        String monitoringNameSpace = "/monitoring/";

        Map<String, List<String>> requestParameters = new HashMap<String, List<String>>();

        requestParameters.put("action", Arrays.asList("getMetricStatistics"));
        requestParameters.put("instanceNoList.1", Arrays.asList("68745"));
        requestParameters.put("metricName", Arrays.asList("CPUUtilization"));
        requestParameters.put("startTime", Arrays.asList("2014-06-09T17:50:00+09:00"));
        requestParameters.put("endTime", Arrays.asList("2014-06-09T18:50:00+09:00"));
        requestParameters.put("period", Arrays.asList("1800"));
        requestParameters.put("responseFormatType", Arrays.asList("xml"));

        SortedMap<String, SortedSet<String>> significantParameters = getSignificateParametersForSiganturBaseString(requestParameters, consumerKey);
        String signatureBaseString = makeSignatureBaseString(requestMethod, requestUrl + monitoringNameSpace, significantParameters);
        String signature = sign(signatureBaseString, consumerSecret);
        String requestFullUrl = makeRequestUrl(requestUrl + monitoringNameSpace, significantParameters, signature);
        System.out.println(requestFullUrl);
    }

    /**
     * signature base string을 만들기 위한 significateParameter 설정
     * @param requestParameters
     * @param consumerKey
     * @return
     */
    private static SortedMap<String, SortedSet<String>> getSignificateParametersForSiganturBaseString(Map<String, List<String>> requestParameters, String consumerKey) {
        SortedMap<String, SortedSet<String>> significateParameters = convertTypeToSortedMap(requestParameters);

        SortedSet<String> consumerKeySet = new TreeSet<String>();
        consumerKeySet.add(consumerKey);
        significateParameters.put("oauth_consumer_key", consumerKeySet);

        SortedSet<String> nonceSet = new TreeSet<String>();
        nonceSet.add(generateNonce());
        significateParameters.put("oauth_nonce", nonceSet);

        SortedSet<String> signatureMethodSet = new TreeSet<String>();
        signatureMethodSet.add("HMAC-SHA1");
        significateParameters.put("oauth_signature_method", signatureMethodSet);

        SortedSet<String> timestampSet = new TreeSet<String>();
        timestampSet.add(generateTimestamp());
        significateParameters.put("oauth_timestamp", timestampSet);

        SortedSet<String> versionSet = new TreeSet<String>();
        versionSet.add("1.0");
        significateParameters.put("oauth_version", versionSet);

        return significateParameters;
    }

    /**
     * @param requestParameters
     * @param significateParameters
     */
    private static SortedMap<String, SortedSet<String>> convertTypeToSortedMap(Map<String, List<String>> requestParameters) {
        SortedMap<String, SortedSet<String>> significateParameters = new TreeMap<String, SortedSet<String>>();
        Iterator<String> parameterNames = requestParameters.keySet().iterator();
        while (parameterNames.hasNext()) {
            String parameterName = (String)parameterNames.next();
            List<String> parameterValues = requestParameters.get(parameterName);
            if (parameterValues == null) {
                parameterValues = new ArrayList<String>();
            }

            for (String parameterValue : parameterValues) {
                if (parameterValue == null) {
                    parameterValue = "";
                }

                SortedSet<String> significantValues = significateParameters.get(parameterName);
                if (significantValues == null) {
                    significantValues = new TreeSet<String>();
                    significateParameters.put(parameterName, significantValues);
                }
                significantValues.add(parameterValue);
            }

        }
        return significateParameters;
    }

    /**
     * @param url
     * @return
     */
    private static String normalizeUrl(String url) {
        try {
            URL requestURL = new URL(url);
            StringBuilder normalized = new StringBuilder(requestURL.getProtocol().toLowerCase()).append("://").append(requestURL.getHost().toLowerCase());
            if ((requestURL.getPort() >= 0) && (requestURL.getPort() != requestURL.getDefaultPort())) {
                normalized.append(":").append(requestURL.getPort());
            }
            normalized.append(requestURL.getPath());
            return normalized.toString();
        } catch (MalformedURLException e) {
            throw new IllegalStateException("Illegal URL for calculating the OAuth signature.", e);
        }
    }

    private static String generateTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000L);
    }

    private static String generateNonce() {
        return Long.toString((new Random()).nextLong());
    }

    /**
     * base string 생성
     * @param requestMethod
     * @param requestUrl
     * @param significantParameters
     * @return
     */
    private static String makeSignatureBaseString(String requestMethod, String requestUrl, SortedMap<String, SortedSet<String>> significantParameters) {
        StringBuilder queryString = getRequestQueryString(significantParameters);

        requestUrl = normalizeUrl(requestUrl);
        requestUrl = OAuthCodec2.oauthEncode(requestUrl);

        return new StringBuilder(requestMethod.toUpperCase()).append('&').append(requestUrl).append('&').append(OAuthCodec2.oauthEncode(queryString.toString())).toString();
    }

    /**
     * query string 생성
     * @param significantParameters
     * @return
     */
    private static StringBuilder getRequestQueryString(SortedMap<String, SortedSet<String>> significantParameters) {
        StringBuilder queryString = new StringBuilder();
        Iterator<Map.Entry<String, SortedSet<String>>> paramIt = significantParameters.entrySet().iterator();
        while (paramIt.hasNext()) {
            Map.Entry<String, SortedSet<String>> sortedParameter = paramIt.next();
            Iterator<String> valueIt = sortedParameter.getValue().iterator();
            while (valueIt.hasNext()) {
                String parameterValue = valueIt.next();
                queryString.append(OAuthCodec2.oauthEncode(sortedParameter.getKey())).append('=').append(OAuthCodec2.oauthEncode(parameterValue));
                if (paramIt.hasNext() || valueIt.hasNext()) {
                    queryString.append('&');
                }
            }
        }
        return queryString;
    }

    /**
     * base string과 consumer secret key를 가지고 signature 생성
     * @param signatureBaseString
     * @param consumerSecret
     * @return
     * @throws NoSuchAlgorithmException
     * @throws UnsupportedEncodingException
     * @throws InvalidKeyException
     */
    private static String sign(String signatureBaseString, String consumerSecret) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        Mac mac = Mac.getInstance("HmacSHA1");
        SecretKeySpec spec = new SecretKeySpec(new String(consumerSecret + "&").getBytes("UTF-8"), "HmacSHA1");
        mac.init(spec);
        byte text[] = signatureBaseString.getBytes("UTF-8");
        byte signatureBytes[] = mac.doFinal(text);
        signatureBytes = Base64.encodeBase64(signatureBytes);
        String signature = new String(signatureBytes, "UTF-8");
        return signature;
    }

    /**
     * request URL 생성
     * @param requestParameters
     * @param signature
     * @return
     * @throws UnsupportedEncodingException
     */
    private static String makeRequestUrl(String requestUrl, SortedMap<String, SortedSet<String>> significantParameters, String signature) throws UnsupportedEncodingException {
        StringBuilder queryString = getRequestQueryString(significantParameters);
        queryString.append('&').append("oauth_signature").append("=").append(URLEncoder.encode(signature, "UTF-8"));
        return new StringBuffer(requestUrl).append("?").append(queryString.toString()).toString();
    }
}

class OAuthCodec2 extends URLCodec {

    private OAuthCodec2() {
    }

    public static String oauthEncode(String value) {
        if (value == null)
            return "";
        try {
            return new String(URLCodec.encodeUrl(SAFE_CHARACTERS, value.getBytes("UTF-8")), "US-ASCII");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String oauthDecode(String value) throws DecoderException {
        if (value == null)
            return "";
        try {
            return new String(URLCodec.decodeUrl(value.getBytes("US-ASCII")), "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    protected static final BitSet SAFE_CHARACTERS;

    static {
        SAFE_CHARACTERS = (BitSet)URLCodec.WWW_FORM_URL.clone();
        SAFE_CHARACTERS.clear(42);
        SAFE_CHARACTERS.clear(32);
        SAFE_CHARACTERS.set(126);
    }
}

main 메소드를 수행하면, 인증URL이 포함된 아래와 같은 요청URL을 볼 수 있습니다.

https://api.ncloud.com/monitoring/?action=getMetricStatistics&endTime=2014-06-09T18%3A50%3A00%2B09%3A00&instanceNoList.1=68745&instanceNoList.2=68417&metricName=CPUUtilization&oauth_consumer_key=CCe2T0ilv4aO3kIevT3x&oauth_nonce=8844649875013849059&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1402484811&oauth_version=1.0&period=60&responseFormatType=xml&startTime=2014-06-09T17%3A50%3A00%2B09%3A00&oauth_signature=DUxxYjHIAtSIxd%2BA7TLYP0Wt3f0%3D

사용자는 My Page > API 인증키 관리 화면에서 Access Key, Secret Key를 발급받고, 위의 예제에서 consumerKey, consumerSecret 값을 해당 값으로 변경 후 테스트 해야 합니다.

모니터링의 경우 namespace가 /monitoring/,으로 사용되니 참고 바라며, 해당 URL복사하여, 브라우저로 요청을 합니다. 아래와 같은 결과를 볼 수 있습니다.

시나리오 수행

모든 시나리오는 인증의 샘플코드 방식으로 설명되며, main 메소드의 파라미터 부분에 대해서만 설명합니다.
자신이 소유하고 있는 서버의 Metric 통계 정보를 조회하기 위해서는 반드시 서버의 인스턴스 번호를 알아야 하며, 통계 정보로 제공 가능한 Metric이 어떤 것들이 있는지 알아야 합니다.

서버 인스턴스 번호 조회

서버 인스턴스 리스트 조회 API를 이용해서 Metric통계 정보를 획득하고자 하는 서버의 인스턴스 번호를 확인합니다.

요청URL 생성

  1. 액션

    • getServerInstanceList
  2. 액션파라미터

    • 없음

      public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
       String requestMethod = "GET";
       String requestUrl = "https://api.ncloud.com";
       String serverNameSpace = "/server/";
      
       Map<String, List<String>> requestParameters = new HashMap<String, List<String>>();
       requestParameters.put("action", Arrays.asList("getServerInstanceList"));
       requestParameters.put("responseFormatType", Arrays.asList("xml"));
      
       SortedMap<String, SortedSet<String>> significantParameters = getSignificateParametersForSiganturBaseString(requestParameters, consumerKey);
       String signatureBaseString = makeSignatureBaseString(requestMethod, requestUrl + serverNameSpace, significantParameters);
       String signature = sign(signatureBaseString, consumerSecret);
       String requestFullUrl = makeRequestUrl(requestUrl + serverNameSpace, significantParameters, signature);
       System.out.println(requestFullUrl);
      }
      

결과

https://api.ncloud.com/server/?action=getServerInstanceList&approachKey=HkLxujk8TYdMs1gdCade&oauth_consumer_key=HkLxujk8TYdMs1gdCade&oauth_nonce=-8691634114796417401&oauth_signature_method=HMAC-

결과 수행

아래와 같이 조회된 보유 서버 정보에서 인스턴스 번호를 확인할 수 있습니다.

통계 정보로 제공 되는 Metric 조회

통계 정보로 제공 가능한 Metric 정보가 어떤 것들이 있는지 조회합니다.

요청URL 생성

  1. 액션
    • getListMetrics
  2. 액션파라미터

    • instanceNo : 68417 (통계 정보를 조회하고자 하는 인스턴스 번호)
    public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
       String requestMethod = "GET";
       String requestUrl = "https://api.ncloud.com";
       String monitoringNameSpace = "/monitoring/";
    
       Map<String, List<String>> requestParameters = new HashMap<String, List<String>>();
       requestParameters.put("action", Arrays.asList("getListMetrics"));
       requestParameters.put("instanceNo", Arrays.asList("68417"));
       requestParameters.put("responseFormatType", Arrays.asList("xml"));
    
       SortedMap<String, SortedSet<String>> significantParameters = getSignificateParametersForSiganturBaseString(requestParameters, consumerKey);
       String signatureBaseString = makeSignatureBaseString(requestMethod, requestUrl + monitoringNameSpace, significantParameters);
       String signature = sign(signatureBaseString, consumerSecret);
       String requestFullUrl = makeRequestUrl(requestUrl + monitoringNameSpace, significantParameters, signature);
       System.out.println(requestFullUrl);
    }
    

결과

https://api.ncloud.com/monitoring/?action=getListMetrics&approachKey=HkLxujk8TYdMs1gdCade&instanceNo=68417&oauth_consumer_key=HkLxujk8TYdMs1gdCade&oauth_nonce=1683658783806074295&oauth_signature_method=HMAC-

결과 수행

아래처럼 인스턴스 번호가 68417인 서버의 경우 통계 정보가 획득 가능한 5가지 Metric 정보 (CPU 사용량, Disk I/O, Network In/Out)가 있음을 조회할 수 있습니다.

Metric통계 조회

앞서 조회한 정보들을 이용해서 일정 기간 동안 특정 주기의 Metric통계 정보를 조회해봅니다.

서버생성 요청 URL 생성

  1. 액션
    • getMetricStatistics
  2. 액션파라미터

    • instanceNoList.1 : 68417
    • metricName : CPUUtilization
    • startTime : 2014-06-09T17:50:00+09:00
    • endTime : 2014-06-09T18:50:00+09:00
    • period : 1800
    public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
       String requestMethod = "GET";
       String requestUrl = "https://api.ncloud.com";
       String monitoringNameSpace = "/monitoring/";
    
       Map<String, List<String>> requestParameters = new HashMap<String, List<String>>();
       requestParameters.put("action", Arrays.asList("getMetricStatistics"));
       requestParameters.put("instanceNoList.1", Arrays.asList("68417"));
       requestParameters.put("metricName", Arrays.asList("CPUUtilization"));
       requestParameters.put("startTime", Arrays.asList("2014-06-09T17:50:00+09:00"));
       requestParameters.put("endTime", Arrays.asList("2014-06-09T18:50:00+09:00"));
       requestParameters.put("period", Arrays.asList("1800"));
       requestParameters.put("responseFormatType", Arrays.asList("xml"));
    
       SortedMap<String, SortedSet<String>> significantParameters = getSignificateParametersForSiganturBaseString(requestParameters, consumerKey);
       String signatureBaseString = makeSignatureBaseString(requestMethod, requestUrl + monitoringNameSpace, significantParameters);
       String signature = sign(signatureBaseString, consumerSecret);
       String requestFullUrl = makeRequestUrl(requestUrl + monitoringNameSpace, significantParameters, signature);
       System.out.println(requestFullUrl);
    }
    

서버생성 URL 생성 결과

https://api.ncloud.com/monitoring/?action=getMetricStatistics&approachKey=HkLxujk8TYdMs1gdCade&endTime=2014-06-09T18%3A50%3A00%2B09%3A00&instanceNoList.1=68417&metricName=CPUUtilization&oauth_consumer_key=HkLxujk8TYdMs1gdCade&oauth_nonce=-8604354833602541619&oauth_signature_method=HMAC-

서버생성 결과 수행

아래처럼 일정 기간 동안 특정 주기의 Metric 통계 정보가 조회 됨을 확인할 수 있습니다.

연관 정보 바로가기

아래 가이드에서 연관 정보를 확인할 수 있습니다.

""에 대한 건이 검색되었습니다.

    ""에 대한 검색 결과가 없습니다.

    처리중...