> For the complete documentation index, see [llms.txt](https://paastaguide.gitbook.io/paas-ta-5-5-0/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://paastaguide.gitbook.io/paas-ta-5-5-0/guide-5.5.0-semini/sample-app-guide/openpaas_paasta_application_go_develope_guide.md).

# Go

## 1. 개요

### 1.1. 문서 개요

#### 1.1.1. 목적

본 문서(Go 애플리케이션 개발 가이드)는 Open PaaS 프로젝트의 서비스팩(Mysql, MongoDB, RabbitMQ, Radis, GlusterFS)을 Go 애플리케이션과 연동하여 서비스를 사용하고 애플리케이션을 배포하는 방법에 대해 제시하는 문서이다.

#### 1.1.2. 범위

본 문서의 범위는 Open PaaS 프로젝트의 Go 애플리케이션 개발과 서비스팩 연동에 대한 내용으로 한정되어 있다.

#### 1.1.3. 참고 자료

* [***https://code.google.com/p/golang-korea/wiki/EffectiveGo***](https://code.google.com/p/golang-korea/wiki/EffectiveGo)
* [***https://github.com/brianmario/mysql2***](https://github.com/brianmario/mysql2)
* [***https://github.com/redis/redis-rb***](https://github.com/redis/redis-rb)
* [***https://github.com/fog/fog***](https://github.com/fog/fog)
* [***https://www.jetbrains.com/idea/***](https://www.jetbrains.com/idea/)

## 2. Go 애플리케이션 개발가이드

### 2.1. 개요

Open PaaS에 등록된 다양한 서비스팩을 Go언어로 작성된 애플리케이션과 바인딩하고 해당 애플리케이션에 바인딩된 환경정보(VCAP\_SERVICES)에서 각 서비스별 접속정보를 획득하여 애플리케이션에 적용하여 이용 할 수 있도록 Windows 환경에서 Go 애플리케이션을 작성 할 수 있도록한다.

### 2.2. 개발환경 구성

Go 애플리케이션 개발을 위해 다음과 같은 환경으로 개발환경을 구성 한다.

* OS : Windows 7 64bit
* Go : 1.5.2
* IDE : Intellij IDEA &#x20;

  Intellij IDEA 는 Commnuity와 Ultimate 버전이 있는데, Community 버전은 Free이고, Ultimate 버전은 은 30-day trial버전이다.

#### 2.2.1. Go SDK설치

1. Go SDK 다운로드

| <https://golang.org/dl/> |
| ------------------------ |

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F8a5ea3fb8e3ffb6501ed73c40397ad080871423a.png?generation=1615338213357973\&alt=media)

* 다운로드

Go SDK : go1.5.2.windows-amd64.msi

1. Go SDK 설치
2. go1.5.2.windows-amd64.msi 더블클릭하여 설치를 실행한다.

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F884d18f022d1fc1384a80289539ddc9056b68355.png?generation=1615338212337377\&alt=media)

* “실행” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Ffa0d7764fdb97d53137e6c7d8c366e0ec795adbd.png?generation=1615338215478623\&alt=media)

* “Next” 버튼을 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F1e8d9a786b80683886439a8b2bbfab0e76163929.png?generation=1615338214595747\&alt=media)

* “Next” 버튼을 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fbb84027d2b315906d778f9638b71bfdd865b1fe6.png?generation=1615338214037852\&alt=media)

* Go SDK가 설치될 디렉토리 선택 후 “Next” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F9ec83adac507b05bf96113f676322ba62bc90e46.png?generation=1615338215400289\&alt=media)

* “Install” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F48a309de0831f7e53678781f4e8aa2d538e759ca.png?generation=1615338215845849\&alt=media)

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F1640ddb32691432c51d7e25f291359f2d8871a97.png?generation=1615338219703591\&alt=media)

* “Finish” 버튼 클릭

#### 2.2.2. IntelliJ IDEA설치

1. IDEA 다운로드

| <http://www.jetbrains.com/idea/> |
| -------------------------------- |

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F0ef2f924c1dd937d06f9f41dc77b793527067280.png?generation=1615338216861471\&alt=media)

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F80ae0e523a9a15c75d94c69d15d55bcf4b8c91ac.png?generation=1615338212199427\&alt=media)

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fa41180165e5ffcd6f766a43393a85069c3119e62.png?generation=1615338216013819\&alt=media)

* 다운로드 : ideaIC-15.0.2.exe
* IntelliJ IDEA 설치
* ideaIC-15.0.2.exe 더블클릭하여 설치를 실행한다.

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F37396c16730b2eeb898b9d590d864f217deb1fc6.png?generation=1615338212969537\&alt=media)

* “Next” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fe212743e83d066c04ad38d54eacf7fd3197b2b22.png?generation=1615338213828644\&alt=media)

* 설치위치 지정 후 “Next” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fc2de5b1e3b90a599e519e075d452e78d5a6972e6.png?generation=1615338217178494\&alt=media)

* “Next” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fe2e7c6aa146f3a861b97c4677432d4fc54558d71.png?generation=1615338214570440\&alt=media)

* “Install” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fa8d74ad8ed7d492fbc6b2a8b9c234da73f984551.png?generation=1615338217137789\&alt=media)

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fc38854284de8c339ea618be18c1a777e282eb7fb.png?generation=1615338213987748\&alt=media)

* “Run IntelliJ IDEA Community Edition” 체크 선택
* “Finish” 버튼 클릭

### 2.3. 개발

샘플 애플리케이션에의 데이터 관리는 MySQL, MongoDB 중에 하나를 이용하기 때문에 API 요청시 요청 본문에 DBType 값을 가지고 결정한다.

#### 2.3.1. 샘플 애플리케이션 연동

1. Go 샘플 프로젝트 연결

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F921230180c4ff35cde5bd3372f83dac70ef14212.png?generation=1615338214822205\&alt=media)

* “Import Project” 선택

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fca2f58182165602defd178ca2d6f69cdf2db26a4.png?generation=1615338215547456\&alt=media)

* 다운로드 받은 Go 샘플 어플리케이션의 위치를 지정
* “Ok” 버튼을 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fc3a02681fa0f81185e3fcc4027381b3dfb0810c3.png?generation=1615338213557173\&alt=media) ![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F3ad8eafd9c5c7eff390b14eb242b14886fe426f6.png?generation=1615338216614908\&alt=media)

* “Next” 버튼 클릭 - “Next” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fc62903d6b6672f140c0aa59ef92a8ffa94692bc7.png?generation=1615338215008193\&alt=media)

* “Next” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F70a5b1b20d854cf1f574579e535e8e9a3ef0a38c.png?generation=1615338219588074\&alt=media)

* “Finish” 버튼 클릭

#### 2.3.2. 샘플 애플리케이션 환경설정

* IntelliJ IDEA 환경에 Go Plugin 설치 및 Go 샘플 어플리케이션의 환결설정

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fa742912c6a2e65a4d5577c25ef783f9808bfd120.png?generation=1615338213214226\&alt=media)

* File > Settings 선택

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F5af47b2122c97a7ff1d471a1118cd645d26487d8.png?generation=1615338218855792\&alt=media)

* Plugins > Browse repositories 선택

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F49d493439a71306f65a284745636df315beefbe7.png?generation=1615338214678572\&alt=media)

* “Go” 를 검색 후, 조회된 결과에서 Go 를 선택 후 Install 버튼을 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F401c7e6352abdd2e9cf3f83ef3ce2450a0249c2c.png?generation=1615338217730929\&alt=media)

* “Restart IntelliJ IDEA” 선택

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fd0dafc38eaf829ada889811136ba495a74178dfc.png?generation=1615338216179387\&alt=media)

* “Restart” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F79ec70a5e1df56d349baa5faf85e591ab92f04f8.png?generation=1615338219239297\&alt=media)

* File > Project Structure... 선택

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fcc1ad7b5be8ff3bc51f0da25f6e8b9009afa3cd2.png?generation=1615338218492758\&alt=media)

* Project SDK 영역의 “New” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F4ee7a28ed9b62e89cc9db84551a07201d45d1d4b.png?generation=1615338216633831\&alt=media)

* “Go SDK” 선택

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F334eac684be778ed7dec115e4b3b25f195089666.png?generation=1615338217992158\&alt=media)

* “Go SDK” 설치된 디렉토리 선택 후 “OK” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fc63fe70aaeba408eba177b943f398e66bdaafbbe.png?generation=1615338217846335\&alt=media)

* “OK” 선택

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F4efe5fe33ef72a655bf1ba974bdaca10b1df61a0.png?generation=1615338218645224\&alt=media)

* go-sample-app 프로젝트에서 “main.go” 파일을 선택
* 오른쪽 상단에 “Configure Go Libraries” 선택

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2Fe6eed6e0d7319b2f43cfe777e01ffc6d6b5292fa.png?generation=1615338219037320\&alt=media) ![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F8088811d0c2bcc3599121cf5ac1432106b336561.png?generation=1615338212996128\&alt=media)

* Global libraries 영역에는 Go SDK 디렉토리 선택
* Project libraries 영역에는 Go 샘플 어플리케이션이 위치한 디렉토리 선택
* “OK” 버튼 클릭

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F0b0f1878296f9aa8b59e12d40324eeb12200b656.png?generation=1615338218731827\&alt=media)

* 오른쪽 상단의 “Change module type to Go and reload project” 선택

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F8b7dfee8939ab419b73ca859f9105981fbc48e4b.png?generation=1615338217317913\&alt=media)

* “Reload project” 선택

![](https://3634999585-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MUwPz1AA_o-VOi2V3xJ%2Fsync%2F4e7c49ff0fe25f49f67f4baad67f2dc3fa9b3d08.png?generation=1615338219942156\&alt=media)

#### 2.3.3. VCAP\_SERVICES 환경설정 정보를 통한 연동

개방형 플랫폼에 배포되는 애플리케이션이 바인딩된 서비스별 접속 정보를 얻기 위해서는 애플리케이션별로 등록되어있는 VCAP\_SERVICES 환경설정 정보를 읽어들여 정보를 획득 할 수 있다.

1\). 개방형 플랫폼의 애플리케이션 환경정보

* 서비스를 바인딩하면 JSON 형태로 환경설정 정보가 애플리케이션 별로 등록된다.

```
{
 "VCAP_SERVICES": {
  "p-rabbitmq": [
   {
    "credentials": {
     "dashboard_url": "https://pivotal-rabbitmq.10.244.0.34.xip.io/#/login/f8b12fcd-df98-4745-a6b2-61f01d20fe24/5lpn72rufsivfgnf3ft4l1p797",
     "hostname": "10.244.9.50",
     "hostnames": [
      "10.244.9.50"
     ],

…..(중간 생략)…..
     "ssl": true,
     "uri": "amqps://f8b12fcd-df98-4745-a6b2-61f01d20fe24:5lpn72rufsivfgnf3ft4l1p797@10.244.9.50/a1aec425-d1ec-40b7-865f-4eaba371b9a2",
     "uris": [
      "amqps://f8b12fcd-df98-4745-a6b2-61f01d20fe24:5lpn72rufsivfgnf3ft4l1p797@10.244.9.50/a1aec425-d1ec-40b7-865f-4eaba371b9a2"
     ],
     "username": "f8b12fcd-df98-4745-a6b2-61f01d20fe24",
     "vhost": "a1aec425-d1ec-40b7-865f-4eaba371b9a2"
    },
    "label": "p-rabbitmq",
    "name": "rabbitmq-service-instance",
    "plan": "standard",
    "tags": [
     "rabbitmq",
     "messaging",
     "message-queue",
     "amqp",
     "stomp",
     "mqtt",
     "pivotal"
    ]
   }
  ]
…..(이하 생략)…..
```

* VCAP\_SERVICES 정보 구조

2\). VCAP\_SERVICES 정보 추출 방법

* VCAP\_SERVICE 정보 중 “uri” 정보를 추출하여 리턴한다.
* 부모 엘리먼트 (VCAP\_SERVICE)
  * 첫번째 엘리먼트 (p-rabbitmq) 서비스 이름 정보
  * 두번째 엘리먼트 (credentials) 정보
  * 세번째 엘리먼트 (uri) 정보

```
func sample_function_name() string {

   args := os.Getenv("VCAP_SERVICES")     //VCAP_SERVICES 엘리먼트 정보 (부모 엘리먼트)
   var amqp_uri string
   if args != "" {
      var vcap_env map[string]interface{}
      if err := json.Unmarshal([]byte(args), &vcap_env); err != nil {
         log.Panic(err.Error())
      }

      //Service instance (not name) - for example : p-mysql - type check !!! []interface{}
      if vcap_env["p-rabbitmq"] != nil {    //첫번째 엘리먼트(서비스 이름) 정보
         sub_env := vcap_env["p-rabbitmq"].([]interface{})
         credentials := (sub_env[0].(map[string]interface{}))["credentials"].(map[string]interface{})
//두번째 엘리먼트 “credentials” 정보
         amqp_uri = credentials["uri"].(string)    //세번째 엘리먼트 “uri”정보
      }
   }
   return amqp_uri
}
```

* VCAP\_SERVICES 구조 참조

#### 2.3.4. config.ini 파일을 통한 Database, Redis, RabbitMQ 연동

1\). config.ini

* mysql 연결정보 설정

```
#Go Sample Web Server port
server.port = 8080
#Mysql DB Info
mysql.dburl=”mysql\_server\_ip”:”mysql\_server\_port”/”database\_name”
mysql.userid=”user\_id”
mysql.userpwd=”user\_password”
mysql.maxconn=”max\_connection\_number”

MongoB Info
mongodb.dburl=”mongodb\_server\_ip”: ”mongodb\_server\_port”/”collection\_name”
mongodb.userid=”user\_id”
mongodb.userpwd=”user\_password”

# Redis Info
redis.addr=”redis\_server\_ip”: ”redis\_server\_port”

# RabbitMQ Info
rabbitmq.user=”rabbitmq\_id”
rabbitmq.pass=”rabbitmq\_password”
rabbitmq.addr=”rabbitmq\_server\_ip”: ”rabbitmq\_server\_port”
```

2\). 연동 샘플

```
import (
   "bufio"
   "fmt"
   "io"
   "log"
   "os"
   "strconv"
   "strings"

   "net/http"

   "encoding/json"
   "org/openpaas/sample/Godeps/_workspace/src/gopkg.in/redis.v3"

   "org/openpaas/sample/datasource"
   "org/openpaas/sample/handler"
   "org/openpaas/sample/message"
)

type Config map[string]string

func main() {
   // Datasource - MySql, Cubrid, MongoDB 타입별 처리
   var dbconfig *datasource.DBConfig
   var mgodbconfig *datasource.MgoDBConfig
   var handlers http.Handler

   fmt.Println("##### Go Sample Application start!!!")
   //============================================
   // dbtype 정보는 시스템 프로퍼티에서 가져온다.
   dbtype := os.Getenv("dbtype")
   //============================================

   //============================================
   // Sample VCAP_SERVICE INFO Parsing
   os_args := os.Getenv("VCAP_SERVICES")
   readOSEnvironment(os_args)
   //============================================

   //============================================
   // 기본적인 프로퍼티 설정 정보 읽어오기
   config, err := ReadConfig(`config.ini`)
   if err != nil {
      fmt.Println(err)
   }
   //============================================

   // Default Redis Client Create - For Login & Logout
   redis_client := initRedis(config["redis.addr"])
   defer redis_client.Close()

   // default dbytype = "mysql"
   if dbtype == "" {
      dbtype = "mysql"
   }

   // RabbitMQ
   //endpoint := "amqps://929b5a98-6521-4da5-86c1-0fcaa2450a86:55dgq7ocf1gtiamqum0hb9p8be@10.244.9.50:5671/3c14abdc-c922-428c-af70-d61eb91ef818"
   endpoint := readOSEnvironment_mq()
   fmt.Println("########## credentials-uri:", endpoint)
   mq := message.NewRabbitMQ(endpoint)
   if mq != nil {
      defer message.CloseMQ(mq)
   }

   // DB Initialize -
   // DB 타입별로 Connection 처리
   if dbtype == "mysql" {
      maxConnection, err := strconv.Atoi(config["mysql.maxconn"])
      if err != nil {
         log.Println(err)
         os.Exit(-1)
      }

      dbconfig = datasource.NewDBConfig(config["mysql.userid"], config["mysql.userpwd"], config["mysql.dburl"], maxConnection)
      defer dbconfig.CloseDb()

      fmt.Println("dbmap:", dbconfig.DBMAP)
      if dbconfig.DBMAP == nil {
         log.Panic("Couldn't create Database Connection properly - MySQL!!!")
         os.Exit(-1)
      }

      // Route Path 정보와 처리 서비스 연결
      handlers = handler.NewHandler(dbconfig.DBMAP, redis_client, mq.Ch)

   } else if dbtype == "mongodb" {
      mgodbconfig = datasource.NewMgoDBConfig(config["mongodb.userid"], config["mongodb.userpwd"], config["mongodb.dburl"])
      defer mgodbconfig.CloseDb()

      fmt.Println("session:", mgodbconfig.SESSION)
      if mgodbconfig.SESSION == nil {
         log.Panic("Couldn't create Database Connection properly - MongoDB!!!")
         os.Exit(-1)
      }

      // Route Path 정보와 처리 서비스 연결
      handlers = handler.NewMgoHandler(mgodbconfig.SESSION, redis_client, mq.Ch)

   } else {
      fmt.Println("No database type found.")
      os.Exit(-1)
   }

   if err := http.ListenAndServe(fmt.Sprintf(":%v", config["server.port"]), handlers); err != nil {
      log.Fatalln(err)
   }
}

/*
   Read Config file
*/
func ReadConfig(filename string) (Config, error) {
   // init with some bogus data
   config := Config{
      "server.ip":     "127.0.0.1",
      "server.port":   "8080",
      "mysql.dburl":   "",
      "mysql.userid":  "",
      "mysql.userpwd": "",
      "mysql.maxconn": "",
   }

   if len(filename) == 0 {
      return config, nil
   }
   file, err := os.Open(filename)
   if err != nil {
      return nil, err
   }
   defer file.Close()

   reader := bufio.NewReader(file)
   for {
      line, err := reader.ReadString('\n')
      // check if the line has = sign
      // and process the line. Ignore the rest.
      if equal := strings.Index(line, "="); equal >= 0 {
         if key := strings.TrimSpace(line[:equal]); len(key) > 0 {
            value := ""
            if len(line) > equal {
               value = strings.TrimSpace(line[equal+1:])
            }
            // assign the config map
            config[key] = value
         }
      }
      if err == io.EOF {
         break
      }
      if err != nil {
         return nil, err
      }
   }
   return config, nil
}


func initRedis(addr string) *redis.Client {
   client := redis.NewClient(&redis.Options{
      Addr: addr,
   })
   return client
}
```

#### 2.3.5. GlusterFS 연동

1\). 파일 Upload

* 클라이언트에서 보낸 요청에서 파일을 읽어들여 GlusterFS Server로 전송

```
func (h *GlusterFSService) Upload(w http.ResponseWriter, r *http.Request) {
   if err := r.ParseMultipartForm(MAX_MEMORY); err != nil {
      log.Println(err)
      http.Error(w, err.Error(), http.StatusForbidden)
   }
   index := 0
   path := make([]string, len(r.MultipartForm.File))
   for _, fileHeaders := range r.MultipartForm.File {
      for _, fileHeader := range fileHeaders {
         file, _ := fileHeader.Open()
         buf, _ := ioutil.ReadAll(file)
         thumb_img_path, err := ObjectPut(buf, fileHeader.Filename)
         path[index] = "{\"thumb_img_path\":\"" + thumb_img_path + "\"}"
         if err != nil {
            log.Fatalln("!!! ObjectPut error:", err)
         }
      }
      index++
   }
   js, err := json.Marshal(path)
   if err != nil {
      log.Fatalln("Error writing JSON:", err)
   }
   w.Header().Set("Content-Type", "application/json")
   w.WriteHeader(http.StatusOK)
   w.Write([]byte(js))
   return
}
```

2\). GlusterFS Server 연결 및 파일전송

* GlusterFS Server로 연결을 맺고 파일을 전송

```
func ObjectPut(buf []byte, fileName string) (string, error) {
   userName, password, authUrl, tenantName := readOSEnvironment_gf()
   c := swift.Connection{
      UserName: userName,
      ApiKey:   password,
      AuthUrl:  authUrl,
      Tenant:   tenantName,
   }
   // Authenticate
   err := c.Authenticate()
   if err != nil {
      panic(err)
   }
   // Container
   _, _, err = c.Container(CONTAINER_NAME)
   if err != nil {
      var meta = swift.Headers{"X-Container-Read": ".r:*"}
      err = c.ContainerCreate(CONTAINER_NAME, meta)
      if err != nil {
         panic(err)
      }
   }
   // Put object
   headers := swift.Headers{}
   headers["Content-Length"] = strconv.FormatInt(int64(len(buf)), 10)
   err = c.ObjectPutBytes(CONTAINER_NAME, fileName, buf, "application/octet-stream")
   if err != nil {
      log.Fatalln("!!! ObjectPut error:", err)
   }
   // Fetch object info and compare
   info, _, err := c.Object(CONTAINER_NAME, fileName)
   if err != nil {
      log.Println(err)
   }
   if info.Bytes != int64(len(buf)) {
      log.Println("Bad length")
   }
   thumb_img_path := c.StorageUrl + "/" + CONTAINER_NAME + "/" + fileName
   return thumb_img_path, err
}
```

3\). GlusterFS 연결정보

* VCAP\_SERVICES에서 정보 추출

```
func readOSEnvironment_gf() (string, string, string, string) {
   args := os.Getenv("VCAP_SERVICES")
   var userName, password, authUrl, tenantName string
   if args != "" {
      var vcap_env map[string]interface{}
      if err := json.Unmarshal([]byte(args), &vcap_env); err != nil {
         log.Panic(err.Error())
      }
      //Service instance (not name) - for example : p-mysql - type check !!! []interface{}
      if vcap_env["glusterfs"] != nil {
         sub_env := vcap_env["glusterfs"].([]interface{})
         credentials := (sub_env[0].(map[string]interface{}))["credentials"].(map[string]interface{})
         userName = credentials["username"].(string)
         password = credentials["password"].(string)
         authUrl = credentials["auth_url"].(string)
         tenantName = credentials["tenantname"].(string)
      }
   }
   return userName, password, authUrl, tenantName
}
```

### 2.4. 배포

* cf cli 명령어를 이용하여 Go 샘플 어플리케이션을 배포한다.
* cf cli가 설치되어 있고, cf login이 이미 되어 있다는 가정하에 진행한다.

```
### Go 샘플 어플리케이션 배포
$ cd “Go 샘플 어플리케이션” 디렉토리
$ source .envrc                 # GO_PATH를 지정하기 위해 

$ cd src/org/openpaas/sample

$ cf push –f manifest.yml        # Go 샘플 어플리케이션 배포
Using manifest file manifest.yml
Creating app go-sample in org org / space space as admin...
OK
Using route go-sample.os.paasxpert.com
Binding go-sample.os.paasxpert.com to go-sample...
OK
Uploading go-sample...
Uploading app files from: /home/ihocho/git/OpenPaaSSample/GoSample/go-sample-app/src/org/openpaas/sample
Uploading 854.2K, 185 files
Done uploading               
OK
Binding service rabbitmq-service-instance to app go-sample in org org / space space as admin...
OK
Starting app go-sample in org org / space space as admin...
Creating container
Successfully created container
Downloading app package...
Downloaded app package (321.1K)
Downloading buildpacks (https://github.com/cloudfoundry/go-buildpack.git)...
Downloaded buildpacks
Staging...
-------> Buildpack version 1.7.0
https://pivotal-buildpacks.s3.amazonaws.com/concourse-binaries/godep/godep-v17-linux-x64.tgz
-----> Checking Godeps/Godeps.json file.
-----> Installing go1.4.2... done
Downloaded [https://storage.googleapis.com/golang/go1.4.2.linux-amd64.tar.gz]
-----> Running: godep go install -tags cloudfoundry ./...
Exit status 0
Staging complete
Uploading droplet, build artifacts cache...
Uploading droplet...
Uploading build artifacts cache...
Uploaded build artifacts cache (60M)
Uploaded droplet (2.8M)
Uploading complete
1 of 1 instances running
App started
OK
App go-sample was started using this command `sample`
Showing health and status for app go-sample in org org / space space as admin...
OK
requested state: started
instances: 1/1
usage: 256M x 1 instances
urls: go-sample.os.paasxpert.com
last uploaded: Mon Dec 14 04:39:52 UTC 2015
stack: cflinuxfs2
buildpack: https://github.com/cloudfoundry/go-buildpack.git
     state     since                    cpu    memory         disk      details   
#0   running   2015-12-14 01:41:20 PM   0.0%   2.1M of 256M   0 of 1G
```

Go 샘플 애플리케이션에의 데이터 관리는 MySQL, MongoDB 중에 하나를 이용하기 때문에 배포시 환경변수 정보(dbtype)에 데이터베이스 이름(mysql or mongodb)를 설정하여 배포한다..

### 2.5. 테스트

curl 명령어를 통해 command 창에서 직접 테스트 할 수 있다.

```
### 모든 조직정보 조회
curl -v http://”depolyed_sample_app_name”/orgs

### 특정 조직정보 조회
curl -v http:// ”depolyed_sample_app_name”/orgs/{org_id}

### 조직 생성
curl -X POST -v 
–d '{"id":”org_id”,"label":"org_lable_info","desc":"org_description_info","url":"org_uri_info"}' 
http:// ”depolyed_sample_app_name”/orgs

### 조직 수정
curl -X PUT -v
-d '{"label":" org_lable_info ","desc":"org_description_info","url":"org_url_info"}'
http:// ”depolyed_sample_app_name”/orgs/{org_id}

### 조직 삭제
curl -X DELETE -v http:// ”depolyed_sample_app_name”/orgs/{org_id}
```
