< Lab >
Lab Overview
실습 개요
- Cloud Storage 버킷 만들기
- 파일 업로드 UI 및 코드 변경 사항 검토
- Cloud Storage에 업로드 파일 데이터를 저장하는 코드 작성
App Dev - Storing Image and Video Files in Cloud Storage
앱 개발 - Cloud Storage에 이미지 및 비디오 파일 저장
- Google Cloud Shell 활성화
- GCP 콘솔의 오른쪽 상단 툴바에서 Cloud Shell 열기 버튼 클릭
- 프로젝트가 PROJECT_ID 로 설정된 것 확인
- 명령어를 통해 활성 계정 이름과 프로젝트 ID 나열
gcloud auth list gcloud config list project
- 퀴즈 애플리케이션 검토
- Cloud Shell에서 소스 코드 복제
git clone --depth=1 https://github.com/GoogleCloudPlatform/training-data-analyst
- 작업 디렉토리에 대한 소프트 링크 생성
ln -s ~/training-data-analyst/courses/developingapps/v1.3/java/cloudstorage ~/cloudstorage
- 실습 샘플 파일이 포함된 디렉터리로 변경
cd ~/cloudstorage/start
- 애플리케이션 구성
이 스크립트 파일은. prepare_environment.sh
1) App Engine 애플리케이션을 생성
2) GCLOUD_PROJECT 환경 변수를 내보냄
3) mvn clean install을 Run
4) Google Cloud Platform 프로젝트 ID를 출력 - 애플리케이션 실행
mvn spring-boot:run
- 웹 미리보기 - 포트 8080에서 미리보기를 클릭 해 아주 흥미로운 퀴즈 확인
- 도구 모음에서 질문 만들기를 클릭해 양식 확인
- 퀴즈 애플리케이션 코드 검사
- Cloud Shell 텍스트 편집기 실행
- 편집기 왼쪽에 있는 파일 브라우저 패널을 사용하여 폴더 /cloudstorage/start 로 이동해 Spring Boot 웹 애플리케이션 검토
1) new_question.html : 질문 만들기 양식에 대한 Thyme 템플릿이 포함
2) QuesetionController.java : POST 처리기가 이미지 서비스에서 메서드를 호출
3) ImageService.java : Cloud Storage에 이미지 파일 데이터를 저장하는 코드를 작성하는 파일
- Cloud Storage 버킷 생성
- Ctrl + C를 눌러 애플리케이션 중지
- 버킷 이름을 전달하며 Cloud Storage 버킷 생성
gsutil mb gs://$DEVSHELL_PROJECT_ID-media
- Cloud Storage 버킷 이름을 GCLOUD_BUCKET이라는 환경 변수로 내보냄
+) 응용 프로그램을 구성을 위해 환경 변수를 사용하므로 버킷 이름을 환경 변수로 내보낸 것이며
개발 팀은 변수를 변경하는 것만으로 애플리케이션을 개발, 테스트, 스테이징 및 프로덕션을 배포할 수 있음
export GCLOUD_BUCKET=$DEVSHELL_PROJECT_ID-media
- Cloud Storage에 객체 추가
- Java Cloud Storage 패키지 가져오기 및 사용
// ImageService.java // TODO: Write a start import for Cloud Storage // (1) ImageService.java 파일에서 Java Cloud Storage 패키지인 com.google.cloud.storage.* 를 가져옴 import com.google.cloud.storage.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @Service public class ImageService { // TODO: Create the storage client // (2) StorageOptions 클래스를 사용하여 명명된 Cloud Storage 클라이언트를 구성 // The StorageOptions class has a getDefaultInstance() // static method. // Use the getService() method to get the storage client private static Storage storage = StorageOptions .getDefaultInstance() .getService(); // TODO: Get the name of the Cloud Storage bucket // (3) bucketName 이라는 String을 선언하고, String 값 주석으로 ${google.storage.bucket} 이라는 속성에서 값을 검색 // Use a Spring @Value annotation to get the value // Get the value using ${google.storage.bucket} // This references the GCLOUD_BUCKET environment variable @Value("${google.storage.bucket}") private String bucketName;
- 파일을 Cloud Storage로 보내는 코드 작성
// ImageService.java public String saveImage(MultipartFile file) throws IOException { // The existing code in the method creates a unique name // based on the file's original name. It has a // prefix generated using the current date and time. // This should ensure that a new file upload won't // overwrite an existing object in the bucket String fileName = System.nanoTime() + file.getOriginalFilename(); // TODO: Create a new Cloud Storage object // (1) BlobInfo 객체를 선언하고 Storage Cloud 객체를 사용하여 초기화 // BlobInfo.Builder를 사용하여 개체를 사용자 지정 // 이를 통해 파일에서 콘텐츠 유형을 설정하고 인증되지 않은 읽기 액세스를 허용하도록 ACL 설정 // Use the BlobInfo class to represent this object // Use the BlobInfo.Builder to customize the Blob // Set the content type from the file // Set the object ACL to Public Read BlobInfo blobInfo = storage.create( BlobInfo.newBuilder(bucketName, fileName) .setContentType(file.getContentType()) .setAcl(new ArrayList<>( Arrays.asList(Acl.of(Acl.User.ofAllUsers(), Acl.Role.READER)))) .build(), file.getInputStream()); // TODO: Cloud Storage public URLs are in the form: // (2) 새 Cloud Storage 객체의 공개 URL을 문자열로 반환 // https://storage.googleapis.com/[BUCKET]/[OBJECT] // Use String concatentation to create return the URL return "https://storage-download.googleapis.com/" + bucketName+ "/" +fileName; }
전체 코드 )
// ImageService.java // TODO: Write a start import for Cloud Storage import com.google.cloud.storage.*; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @Service public class ImageService { // TODO: Create the storage client // The StorageOptions class has a getDefaultInstance() // static method. // Use the getService() method to get the storage client private static Storage storage = StorageOptions .getDefaultInstance() .getService(); // TODO: Get the name of the Cloud Storage bucket // Use a Spring @Value annotation to get the value // Get the value using ${google.storage.bucket} // This references the GCLOUD_BUCKET environment variable @Value("${google.storage.bucket}") private String bucketName; public String saveImage(MultipartFile file) throws IOException { // The existing code in the method creates a unique name // based on the file's original name. It has a // prefix generated using the current date and time. // This should ensure that a new file upload won't // overwrite an existing object in the bucket String fileName = System.nanoTime() + file.getOriginalFilename(); // TODO: Create a new Cloud Storage object // Use the BlobInfo class to represent this object // Use the BlobInfo.Builder to customize the Blob // Set the content type from the file // Set the object ACL to Public Read BlobInfo blobInfo = storage.create( BlobInfo.newBuilder(bucketName, fileName) .setContentType(file.getContentType()) .setAcl(new ArrayList<>( Arrays.asList(Acl.of(Acl.User.ofAllUsers(), Acl.Role.READER)))) .build(), file.getInputStream()); // TODO: Cloud Storage public URLs are in the form: // https://storage.googleapis.com/[BUCKET]/[OBJECT] // Use String concatentation to create return the URL return "https://storage-download.googleapis.com/" + bucketName+ "/" +fileName; } }
- 애플리케이션 실행 및 Cloud Storage 객체 생성
1) 저장한 후 Cloud Shell에서 응용 프로그램 시작
2) 이미지 파일을 로컬 컴퓨터로 다운로드mvn spring-boot:run
3) 웹 미리보기를 통해 퀴즈 애플리케이션을 연 후 질문 만들기 링크 클릭
4) 양식을 완성한 다음 저장
5) 클라우드 콘솔로 돌아가 Cloud Storage로 이동 후 브라우저에서 <Project ID>-media 버킷을 클릭
6) 이름이 지정된 새 객체를 확인
- 클라이언트 애플리케이션 실행 및 Cloud Storage 공개 URL 테스트
1) 퀴즈 애플리케이션의 URL 끝에 /api/quizzes/gcp 추가
웹 애플리케이션에 추가한 질문에 해당하는 클라이언트에 애플리케이션이 JSON 데이터를 반환하는 것을 확인 가능
"imageUrl" : "https://storage-download.googleapis.com/<Project ID>-media/객체이름"
즉, "https://storage-download.googleapis.com/" + bucketName+ "/" +fileName
2) 시험 응시 후 GCP를 클릭하고 질문에 대답하면 웹 애플리케이션 내에서 이미지 형식이 지정된 것을 볼 수 있음