API 서비스 애플리케이션을 Java 언어로 작성 한다. API 서비스는 서비스 요청을 처리함과 동시에 API 사용 내역을 CF-ABACUS에 전송하는 애플리케이션을 작성 한다.
※ 본 개발 가이드는 API 서비스 개발에 대해서만 기술하며, 다른 컴포넌트의 개발 또는 설치에 대해서 링크한 사이트를 참조한다.
2.2 개발환경 구성
Java 애플리케이션 개발을 위해 다음과 같은 환경으로 개발환경을 구성 한다.
CF release: v226 이상
java version "1.8.0_101"
springBootVersion : 1.3.0.BUILD-SNAPSHOT
gradle 2.14
Spring Tool Suite 혹은 Eclipse
2.2.1 CF-Abacus 설치
별도 제공하는 Abacus 설치 가이드를 참고하여 CF-Abacus를 설치한다.
2.3 샘플 API 서비스 개발
샘플 api 서비스는 서비스 요청이 있는 경우, 해당 요청에 대한 응답 처리와 api 서비스 요청에 대한 미터링 정보를 CF-ABACUS에 전송하는 처리를 한다.
2.3.1 gradle 프로젝트를 생성
프로젝트 디렉터리를 생성하고, gradle 프로젝트로 초기화 한다
$ mkdir sample_api_java_service // 프로젝트 디렉토리
$ cd sample_api_java_service/
~/sample_api_java_service $ gradle init --type java-library // gradle 초기화
: wrapper
: init
BUILD SUCCESSFU
Total time: 2.435 secs
This build could be faster, please consider using the Gradle Daemon:
https://docs.gradle.org/2.14/userguide/gradle_daemon.html
앱을 CF에 배포할 때 필요한 설정 정보 및 앱 실행 환경에 필요한 설정 정보를 기술 한다.
```yml applications:
name: sample-api-node-service # 애플리케이션 이름
memory: 512M # 애플리케이션 메모리 사이즈
instances: 1 # 애플리케이션 인스턴스 개수
host: sample-api-java-service
path: ./build/libs/sample_api_java_service.jar # 배포될 애플리케이션의 위치
env:
SPRING_PROFILES_ACTIVE : cloud
```
metering.properties
API 서비스의 사용량 정보를 abacus-collector에 전송 할 때, 필요한 설정 정보 및 계정 정보를 기술 한다.
# abacus usage collector RESTAPI 의 주소
abacus.collector = https://abacus-usage-collector.<CF도메인/v1/metering/collected/usage
# abacus usage collector 가 secured 모드 true / 아닐 경우 false
abacus.secured = true
# 파스-타 플랫폼의 uaa server
uaa.server = https://uaa.<CF도메인>
# abacus usage collector RESTAPI 계정 정보 및 사용권한 (UAA server에 미리 설정)
uaa.client.id = <abacus.usage.read/write scope 권한을 가진 ID>
uaa.client.secret = <abacus.usage.read/write scope 권한을 가진 ID 비밀번호>
uaa.client.scope = abacus.usage.object-storage.write,abacus.usage.object-storage.read
2.3.4 MeteringAuthService 클래스
UAA 서버 URL 및 계정 정보를 참조 하여, UAA token 을 취득하여 리턴 한다.
public String getUaacTokenHTTPS () throws MalformedURLException {
String authToken = "";
String urlStr = authServer + "/oauth/token?grant_type=client_credentials&scope=" + encodeURIComponent(scope);
StringBuffer sb = new StringBuffer();
try {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
} };
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
String authHeader = getAuthKey(clientId, clientSecret);
conn.setRequestProperty("authorization", authHeader);
InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
BufferedReader br = new BufferedReader(in);
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
authToken= parseAuthToken(sb.toString());
br.close();
in.close();
conn.disconnect();
} catch (Exception e) {
System.out.println(e.toString());
}
return authToken;
}
metering.properties 에서 취득한 계정 정보를 BASE64 로 인코딩 한다.
$ cf create-service <서비스명> <플랜 명> <서비스 인스턴스 명>
예)
$ cf create-service standard_obejct_storage_light_api_calls standard sampleNodejslightCallApi
##서비스 확인
$ cf services
Getting services in org real / space ops as admin...
OK
name service plan bound apps last operation sampleNodejslightCallApi standard_obejct_storage_light_api_calls standard create succeeded
2.6.4. API 서비스 연동 샘플 애플리케이션 배포 및 서비스 연결
애플리케이션과 서비스를 연결하는 과정을 '바인드(bind)라고 하며, 이 과정을 통해 서비스에 접근할 수 있는 접속정보를 생성한다.
애플리케이션과 서비스 연결
## API 서비스 연동 샘플 애플리케이션 배포
$ cd <샘플 애플리케이션 경로>/sample_api_node_caller
$ npm install && npm run babel && npm run cfpack && ./cfpush.sh
## 서비스 바인드
$ cf bind-service <APP_NAME> <SERVICE_INSTANCE> -c <PARAMETERS_AS_JSON>
예)
$ cf bind-service sample-api-node-caller sampleNodejslightCallApi -c '{"serviceKey": "cloudfoundry"}'
## 서비스 연결 확인
$ cf services
Getting services in org real / space ops as admin...
OK
name service plan bound apps last operation
sampleNodejslightCallApi standard_obejct_storage_light_api_calls standard sample-api-node-caller create succeeded
## 애플리케이션 실행
$ cf start <APP_NAME>
예)
$ cf start sample-api-node-caller
## 형상 확인
$ cf a
Getting apps in org real / space ops as admin...
OK
name requested state instances memory disk urls
sample-api-node-service started 1/1 512M 512M sample-api-node-service.bosh-lite.com
sample-api-java-broker started 1/1 512M 1G sample-api-java-broker.bosh-lite.com
sample-api-node-caller started 1/1 512M 512M sample-api-node-caller.bosh-lite.com
2.7. API 및 CF-Abacus 연동 테스트
API 연동 샘플 애플리케이션의 url을 통해 웹 브라우저에서 접속하면 API 연동 및 API 사용량에 대한 CF-Abacus 연동 테스트를 진행 할 수 있다.
CF-Abacus 연동 확인
## 조직 guid 확인
$ cf org <샘플 애플리케이션을 배포한 조직> --guid
예)
$ cf org real --guid
877d01b2-d177-4209-95b0-00de794d9bba
## 샘플 애플리케이션 guid 확인
$ cf env <샘플 애플리케이션 명>
예)
$ cf env sample-api-node-caller
Getting env variables for app sample-api-node-caller in org real / space ops as admin...
OK
<<중략>>
{
"VCAP_APPLICATION": {
"application_id": "58872d8a-edfc-44df-97f0-df67cf9033a7",
"application_name": "sample-api-node-caller",
"application_uris": [
"sample-api-node-caller.bosh-lite.com"
],
"application_version": "55678102-584c-4fca-8304-82f727506b1d",
"limits": {
"disk": 512,
"fds": 16384,
"mem": 512
},
"name": "sample-api-node-caller",
"space_id": "2ce08996-f463-406c-a971-adbbaf4e4ca5",
"space_name": "ops",
"uris": [
"sample-api-node-caller.bosh-lite.com"
],
"users": null,
"version": "55678102-584c-4fca-8304-82f727506b1d"
}
}
<<후략>>
## API 사용량 확인
$ curl 'http://abacus-usage-reporting.<파스-타 도메인>/v1/metering/organizations/<샘플 애플리케이션을 배포한 조직>/aggregated/usage'
예)
$ curl 'http://abacus-usage-reporting.bosh-lite.com/v1/metering/organizations/877d01b2-d177-4209-95b0-00de794d9bba/aggregated/usage'
API 서비스 제공자가 제공하는 서비스에 대한 각종 정책 정의 정보. JSON 형식으로 되었으며, 해당 정책을 CF-ABACUS에 등록하면 정책에 정의한 내용에 따라 API 사용량을 집계 한다.
정책은 서비스 제공자가 정의해야 하며, JSON 스키마는 다음을 참조한다.
https://github.com/cloudfoundry-incubator/cf-abacus/blob/master/doc/api.md
서비스 브로커 API
Cloud Controller와 Service Broker 사이의 규약으로써 서비스 브로커 API 개발에 대해서는 다음을 참조한다.
https://github.com/OpenPaaSRnD/Documents/blob/master/Development-Guide/ServicePack_develope_guide.md#11
서비스 API
서비스 제공자가 제공하는 API 서비스 기능 및 API 사용량을 CF-ABACUS에 전송하는 기능으로 구성되었다.
대시보드
서비스를 제공하기 위한 인증, 서비스 모니터링 등을 위한 대시보드 기능으로 서비스 제공자가 개발해야 한다.
CF-ABACUS
CF-ABACUS 핵심 기능으로써 수집한 사용량 정보를 집계한다.
CF-ABACUS은 CF 설치 후, CF에 마이크로 서비스 형태로 설치한다. 자세한 사항은 다음을 참조한다.
https://github.com/cloudfoundry-incubator/cf-abacus
파일
목적
build.gradle
애플리케이션에 필요한 의존성 정보를 기술
.gitignore
Git을 통한 형상 관리 시, 형상 관리를 할 필요가 없는 파일 또는 디렉토리를 설정한다.
manifest.yml
애플리케이션을 파스-타 플랫폼에 배포 시 적용하는 애플리케이션에 대한 환경 설정 정보
애플리케이션의 이름, 배포 경로, 인스턴스 수 등을 정의할 수 있다.
gradlew
Linux 환경에서 사용하는 gradlew 빌드 실행 파일
gradle 초기화 시 자동 생성 된다.
gradlew.bat
Window 환경에서 사용하는 gradle 빌드 실행 파일
gradle 초기화 시 자동 생성 된다.
settings.gradle
gradlew 실행 시 적용하는 환경 설정 파일
gradle 초기화 시 자동 생성 된다.
파일
목적
MeteringConfig
애플리케이션 구동 시 metering.properties를 로드 한다
MeteringAuthService
파스-타 플랫폼 상의 UAA 서버에서 abacus-usage-collector 에 대한 접근 권한 토큰을 취득하여 리턴 한다.
MeteringService
API 서비스 사용 요청 이 SampleApiJavaServiceController 에서 처리 될 때 API 서비스 처리에 대해 미터링이 적용된 사용량 보고서를 abacus-usage-collector 에 리포팅 한다.
SampleApiJavaServiceApplication
SpringBoot이 구동할 때, SpringBoot애플리케이션에 필요한 context 객체 들을 로드 한다.
SampleApiJavaServiceController
API 서비스 사용 요청을 처리하는 REST Controller.
본 샘플 애플리케이션에서는 API 서비스 고유의 비즈니스 로직은 구현 하지 않았으며, API 사용량을 abacus-collector에 전송하는 기능만 수행 한다.
application.properties
SpringBoot이 구동할 때, spring 에 필요한 property
metering.properties
API 사용량을 abacus-collector 전송 시에 설정 할 property 들이 정의 되어 있다.