Cloud Storage 시작하기

Google Display & Video 360은 항목 읽기 파일을 Google Cloud Storage에 자동으로 저장합니다. 이러한 파일은 액세스 권한이 부여된 계정에서만 액세스할 수 있습니다.

프로젝트 만들기

다음과 같이 프로젝트를 만들고 구성합니다.

  1. Google API 콘솔에서 사용 설정된 API 페이지로 이동합니다.

    아직 Google에 로그인하지 않은 경우 로그인하라는 메시지가 표시됩니다.

  2. 프로젝트 드롭다운에서 기존 프로젝트를 선택하거나 새 프로젝트를 만듭니다.
    • 기존 프로젝트가 여러 개 있는 경우 Google Cloud Storage를 활성화하려는 프로젝트를 선택한 다음 계속을 선택합니다.
    • 프로젝트가 없으면 새 프로젝트 만들기를 선택하고 프로젝트 이름을 입력한 다음 만들기를 선택합니다.

      참고: 일부 리소스 식별자(예: 프로젝트 ID)는 프로젝트 수명 이후에도 보존될 수 있습니다. 따라서 민감한 정보는 리소스 식별자에 저장하지 마세요.

  3. 사용 설정된 API 목록에 Google Cloud Storage 구성요소가 나열되는지 확인합니다. 목록에 없으면 Google API 탭을 클릭하고 Google Cloud Storage 구성요소를 검색하여 선택한 다음 API 사용 설정을 클릭합니다.

    대부분의 프로젝트에서는 Google Cloud Storage 구성요소가 이미 사용 설정되어 있습니다. JSON API를 사용하여 Google Cloud Storage에 액세스하려는 경우 Google Cloud Storage JSON API가 사용 설정되어 있는지도 확인해야 합니다.

  4. 프로젝트에 결제를 사용 설정합니다.

    프로젝트에 결제를 사용 설정하지 않은 경우 Google Cloud Storage를 사용하려면 먼저 결제를 사용 설정해야 합니다. 결제를 사용 설정한다고 해서 반드시 비용이 청구되지는 않습니다. 자세한 내용은 가격 책정을 참조하세요.

    1. 클라우드 스토리지 프로젝트 내에서 왼쪽 상단의 갤러리 메뉴를 클릭한 다음 결제를 선택합니다.
    2. 아직 결제 계정이 없으면 안내에 따라 새 결제 계정을 만드세요.
    3. 기존 결제 계정이 있으면 해당 계정을 선택한 후 계정 설정을 선택합니다.

Google API 콘솔에서 동일한 프로젝트 내에서 다음 섹션으로 이동합니다.

Cloud Storage에 대한 액세스 설정

  1. 필수 프로젝트 내의 Google API 콘솔에서 왼쪽 상단에 있는 갤러리 메뉴를 클릭하고 API 및 서비스를 선택한 다음 사용자 인증 정보를 클릭합니다. 사용자 인증 정보 페이지에서 서비스 계정 키를 찾습니다.

    서비스 계정 키 이메일 주소를 찾습니다.

    1. 서비스 계정 관리 링크 (서비스 계정 키 섹션 오른쪽)를 선택합니다.
    2. 이메일 주소는 표시되는 권한 페이지에 표시됩니다.

    서비스 계정 키가 없으면 새 서비스 계정을 만듭니다.

    1. 사용자 인증 정보 만들기 드롭다운을 선택한 후 서비스 계정 키를 선택합니다.
    2. 서비스 계정 드롭다운에서 새 서비스 계정을 선택합니다.
    3. 서비스 계정의 이름을 입력합니다. 이름과 프로젝트 이름에서 서비스 계정 ID가 자동으로 생성됩니다.
    4. 서비스 계정 ID gserviceaccount.com 이메일 주소기록합니다. 만들기를 선택한 후에는 사용자 인증 정보 페이지에 표시되지 않습니다.
    5. 키 유형 섹션에서 JSON을 선택합니다.
    6. 만들기를 클릭합니다. 계정의 공개 키/비공개 키 쌍이 포함된 JSON 파일이 다운로드 폴더에 저장됩니다. 이 키는 API에 애플리케이션을 인증하고 API에 보내는 모든 요청에 서명하는 데 사용됩니다. 생성된 JSON 파일을 애플리케이션에서 액세스할 수 있는 안전한 위치에 저장합니다.
  2. 항목 읽기 파일 또는 Google Bid Manager API의 사용 설정을 요청하려면 Display & Video 360 지원팀에 문의하세요.

    지원팀에서 액세스 권한을 확인한 후 전용 Google 그룹을 만들고 Display & Video 360 파트너 세부정보에서 다음 필드를 업데이트합니다. 파트너 수준 액세스 권한이 있는 사용자만 이러한 업데이트를 할 수 있습니다.

    • 로그 읽기 Google 그룹
      읽기 전용 그룹에는 파일을 읽고 스토리지 버킷의 콘텐츠를 나열할 수 있는 권한만 있습니다.
    • 로그 관리 Google 그룹
      관리 그룹은 읽기 전용 그룹의 모든 권한을 가지고 있지만 버킷 내의 파일 ACL을 변경할 수도 있습니다. 관리 그룹에도 버킷 ACL을 변경할 수 있는 권한이 없고 파일을 생성, 수정 또는 삭제할 권한도 없습니다.

    Google 그룹이 추가된 후에는 Display & Video 360 지원팀의 추가 개입 없이도 필요에 따라 Google 그룹에 사용자를 추가하거나 삭제할 수 있습니다. 그룹에 있는 사용자만 데이터에 액세스할 수 있습니다.

데이터에 액세스

gsutil을 사용하여 데이터 액세스

gsutil 도구는 프로그래밍 경험 없이도 Google Cloud Storage 데이터에 쉽게 액세스할 수 있도록 하는 명령줄 애플리케이션입니다. 예를 들어 커스텀 애플리케이션을 만드는 대신 gsutil을 스크립트 또는 일괄 파일의 일부로 사용할 수 있습니다.

gsutil을 시작하려면 gsutil 문서를 참조하세요. 이전과 마찬가지로 OAuth 2를 사용하여 인증해야 하지만 gsutil은 처음 사용할 때 사용자 인증 정보를 요청하는 메시지를 표시하며, 이후 나중에 사용할 수 있도록 저장합니다.

프로그래매틱 방식으로 데이터에 액세스

Google Cloud Storage에는 프로그래매틱 방식으로 데이터에 액세스할 수 있게 해주는 여러 프로그래밍 언어용 API가 있습니다. 아래 샘플은 Google Cloud Storage에서 항목 읽기 파일 중 하나를 간단하게 다운로드하는 방법을 보여줍니다. 공개 항목 읽기 파일gdbm-public 버킷에 저장되고, 비공개 항목 읽기 파일은 파트너 및 광고주별 버킷에 저장됩니다.

Java

다음 예에서는 Google Cloud Storage에 저장된 데이터에 쉽게 액세스할 수 있도록 하는 Java용 Google API 클라이언트 라이브러리를 사용합니다. 기본 일반 Google API 클라이언트 라이브러리 외에, 별도의 Cloud Storage API용 라이브러리도 다운로드해야 합니다.

먼저 API와 통신할 때 사용할 사용자 인증 정보를 설정하여 데이터에 액세스하기 위한 승인을 받아야 합니다. 이 작업은 서비스 계정의 developer.gserviceaccount.com 이메일 주소를 ServiceAccountId로 사용하고 서비스 계정을 만들 때 Google API 콘솔에서 다운로드한 비공개 키 파일도 로드하는 Credential 객체를 만들면 됩니다. 이렇게 하면 이후 API에 대한 모든 요청이 서비스 계정의 비공개 키로 서명됩니다.

NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();
JacksonFactory JSON_FACTORY = new JacksonFactory();

...

Credential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
   .setJsonFactory(JSON_FACTORY)
   .setServiceAccountId("...@developer.gserviceaccount.com")
   .setServiceAccountScopes(StorageScopes.DEVSTORAGE_READ_ONLY)
   .setServiceAccountPrivateKeyFromP12File(new File("...-privatekey.p12"))
   .build();

Credential 객체를 만든 후 이 객체를 사용하여 향후 Google Cloud Storage API에 대한 모든 요청에 사용할 수 있는 새 Storage 객체를 인스턴스화할 수 있습니다.

Storage storage = new Storage(HTTP_TRANSPORT, JSON_FACTORY, credential);

Storage 객체가 생겼으므로 이제 API에 요청할 수 있습니다. 다음은 bucket 버킷에서 특정 항목 bucketObjectName에 대한 검색을 요청합니다. 이 라이브러리는 Google Cloud Storage에서 파일의 HTTP 다운로드를 처리하므로 개발자는 콘텐츠를 콘솔에 출력하기만 하면 됩니다.

Get bucketObject = storage.objects().get(bucketName, bucketObjectName);

ByteArrayOutputStream output = new ByteArrayOutputStream();
bucketObject.getMediaHttpDownloader().setDirectDownloadEnabled(true);
bucketObject.executeAndDownloadTo(output);

System.out.println(output.toString());

bucketbucketObjectName의 값은 액세스하는 API 부분에 따라 달라집니다. 이름 지정 규칙에 대한 해당 섹션을 참조하세요.

C#

다음 예에서는 Google Cloud Storage에 저장된 데이터에 간편하고 쉽게 액세스할 수 있도록 하는 .NET용 Google API 클라이언트 라이브러리를 사용합니다.

먼저 API와 통신할 때 사용할 사용자 인증 정보를 설정하여 데이터에 액세스할 수 있는 권한을 얻어야 합니다. 이렇게 하려면 서비스 계정의 developer.gserviceaccount.com 이메일 주소를 ServiceAccountId로 사용하는 AssertionFlowClient 객체를 만들고 서비스 계정을 만들 때 Google API 콘솔에서 다운로드한 비공개 키 파일도 로드합니다.

string keyPath = @"...-privatekey.p12";
X509Certificate2 certificate = new X509Certificate2(keyPath, "notasecret", X509KeyStorageFlags.Exportable);
var provider = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate)
{
    ServiceAccountId = "...@developer.gserviceaccount.com",
    Scope = StorageService.Scopes.DevstorageRead_only.GetStringValue()
};

AssertionFlowClient 객체를 만든 후 이 객체를 사용하여 새로운 OAuth2Authenticator 객체를 인스턴스화합니다. 이 객체는 이후 Google Cloud Storage API에 대한 모든 향후 요청을 위해 새 Storage 인스턴스를 인스턴스화하는 데 사용할 수 있습니다.

var auth = new OAuth2Authenticator<AssertionFlowClient>(provider, AssertionFlowClient.GetState);
StorageService service = new StorageService(auth);

Storage 객체가 생겼으므로 이제 API에 요청할 수 있습니다. 다음은 bucket 버킷에서 특정 항목 bucketObjectName에 대한 검색을 요청합니다. Google Cloud Storage에서 HTTP 다운로드를 처리하기 위해 표준 .NET 클라이언트 라이브러리 클래스를 사용하지만 요청에 항상 올바른 Authorization 헤더가 있도록 하려면 리디렉션이 발생하는 경우를 직접 처리해야 합니다.

var results = service.Objects.Get(bucketName, bucketObjectName).Fetch();

HttpWebRequest request = createRequest(results.Media.Link, auth);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

// Handle redirects manually to ensure that the Authorization header is present if
// your request is redirected.
if (response.StatusCode == HttpStatusCode.TemporaryRedirect)
{
    request = createRequest(response.Headers["Location"], auth);
    response = (HttpWebResponse)request.GetResponse();
}

그런 다음 평소와 같이 GetResponseStream를 통해 HttpWebResponse 객체에서 응답의 콘텐츠를 읽을 수 있습니다. bucketbucketObjectName 값은 액세스하는 API 부분에 따라 달라집니다. 이름 지정 규칙에 대한 해당 섹션을 참조하세요.

부록: 전체 샘플

Java

/*
 * Copyright (c) 2013 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.bidmanager.api.samples;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStreamReader;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.storage.Storage;
import com.google.api.services.storage.Storage.Objects.Get;
import com.google.api.services.storage.StorageScopes;

/**
 * A simple class that demonstrates how to download a specific object from a bucket using a
 * service account
 */
public class ServiceDownload {

  /**
   * This is the HTTP Transport object used for automatically refreshing access tokens.
   */
  static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  /**
   * This is the JSON factory used for parsing refresh token responses.Your first requirement
   */
  static final JacksonFactory JSON_FACTORY = new JacksonFactory();

  /**
   * The main method will attempt to download a specific named object from the gdbm-public bucket
   * using a service account.
   *
   * @param args Not used.
   */
  public static void main(String[] args) {

    try {
      // Prompt the user for the details of the object to download.
      System.out.print("Name of object to download, e.g. entity/20130430.0.Browser.json:");
      BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
      String bucketObjectName = in.readLine();
      in.close();
      String bucketName = "gdbm-public";

      Credential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
           .setJsonFactory(JSON_FACTORY)
           .setServiceAccountId("...@developer.gserviceaccount.com")
           .setServiceAccountScopes(StorageScopes.DEVSTORAGE_READ_ONLY)
           .setServiceAccountPrivateKeyFromP12File(
               new File("...-privatekey.p12"))
           .build();

      Storage storage = new Storage(HTTP_TRANSPORT, JSON_FACTORY, credential);

      Get bucketObject = storage.objects().get(bucketName, bucketObjectName);

      ByteArrayOutputStream output = new ByteArrayOutputStream();
      bucketObject.getMediaHttpDownloader().setDirectDownloadEnabled(true);
      bucketObject.executeAndDownloadTo(output);
      System.out.println(output.toString());

    } catch (Exception e) {
      System.err.println("Unexpected exception caught: " + e.getMessage());
      e.printStackTrace();
    }

  }


}

C#

/*
 * Copyright (c) 2013 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;

using DotNetOpenAuth.OAuth2;

using Google.Apis;
using Google.Apis.Requests;
using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using Google.Apis.Storage.v1beta1;
using Google.Apis.Storage.v1beta1.Data;
using Google.Apis.Util;

namespace ApiSamples
{
    /// <summary>
    /// A simple class that demonstrates how to download a specific object from a bucket using a
    /// service account
    /// </summary>
    class ServiceDownload
    {
        /// <summary>
        /// The main method will attempt to download a specific named object from the
        /// gdbm-public bucket using a service account.
        /// </summary>
        /// <param name="args">Not used.</param>
        public static void Main(string[] args)
        {

            // Prompt the user for the details of the object to download
            Console.WriteLine("Name of object to download, e.g. entity/20130430.0.Browser.json:");
            string bucketObjectName = Console.ReadLine();
            string bucketName = "gdbm-public";

            try
            {
                string keyPath = @"...-privatekey.p12";
                X509Certificate2 certificate = new X509Certificate2(keyPath, "notasecret", X509KeyStorageFlags.Exportable);
                var provider = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate)
                {
                    ServiceAccountId = "...@developer.gserviceaccount.com",
                    Scope = StorageService.Scopes.DevstorageRead_only.GetStringValue()
                };
                var auth = new OAuth2Authenticator<AssertionFlowClient>(provider, AssertionFlowClient.GetState);

                StorageService service = new StorageService(auth);
                var results = service.Objects.Get(bucketName, bucketObjectName).Fetch();

                HttpWebRequest request = createRequest(results.Media.Link, auth);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                // Handle redirects manully to ensure that the Authorization header is present if
                // our request is redirected.
                if (response.StatusCode == HttpStatusCode.TemporaryRedirect)
                {
                    request = createRequest(response.Headers["Location"], auth);
                    response = (HttpWebResponse)request.GetResponse();
                }

                Stream stream = response.GetResponseStream();
                StreamReader reader = new StreamReader(stream);
                String data = reader.ReadToEnd();
                Console.Write(data);
            }
            catch (Exception e)
            {
                Console.WriteLine("Unexpected exception caught: " + e.Message);
                Console.Write(e.StackTrace);
            }
            Console.ReadKey();
        }

        /// <summary>
        /// Generate a HttpWebRequest for the given URL with the appropriate OAuth2 authorization
        /// header applied.  The HttpWebRequest object returned has its AllowAutoRedirect option
        /// disabled to allow us to manually handle redirects.
        /// </summary>
        /// <param name="url">URL that is to be requested with this object</param>
        /// <param name="auth">The OAuth2Authenticator instance that contains the appropriate keys.</param>
        /// <returns>HttpWebRequest object ready to be used to make requests to the API</returns>
        private static HttpWebRequest createRequest(string url, OAuth2Authenticator<AssertionFlowClient> auth)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Headers.Add("Authorization", "Bearer " + auth.State.AccessToken);
            request.AllowAutoRedirect = false;
            return request;
        }

    }
}